Codebase list libdbix-class-perl / upstream/0.082820
Imported Upstream version 0.082820 gregor herrmann 8 years ago
56 changed file(s) with 1560 addition(s) and 1322 deletion(s). Raw diff Collapse all Expand all
1414 Alexander Keusch <cpan@keusch.at>
1515 alexrj: Alessandro Ranellucci <aar@cpan.org>
1616 alnewkirk: Al Newkirk <github@alnewkirk.com>
17 Altreus: Alastair McGowan-Douglas <alastair.mcgowan@opusvl.com>
1718 amiri: Amiri Barksdale <amiribarksdale@gmail.com>
1819 amoore: Andrew Moore <amoore@cpan.org>
1920 Andrew Mehta <Andrew@unitedgames.co.uk>
3738 caldrin: Maik Hentsche <maik.hentsche@amd.com>
3839 castaway: Jess Robinson <castaway@desert-island.me.uk>
3940 chorny: Alexandr Ciornii <alexchorny@gmail.com>
41 cj: C.J. Adams-Collier <cjcollier@cpan.org>
4042 claco: Christopher H. Laco <claco@cpan.org>
4143 clkao: CL Kao <clkao@clkao.org>
4244 Ctrl-O http://ctrlo.com/
5355 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
5456 dnm: Justin Wheeler <jwheeler@datademons.com>
5557 dpetrov: Dimitar Petrov <mitakaa@gmail.com>
58 Dr^ZigMan: Robert Stone <drzigman@drzigman.com>
5659 dsteinbrunner: David Steinbrunner <dsteinbrunner@pobox.com>
5760 duncan_dmg: Duncan Garland <Duncan.Garland@motortrak.com>
5861 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
7881 Ian Wells <ijw@cack.org.uk>
7982 idn: Ian Norton <i.norton@shadowcat.co.uk>
8083 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
84 ingy: Ingy döt Net <ingy@ingy.net>
8185 initself: Mike Baas <mike@initselftech.com>
8286 ironcamel: Naveed Massjouni <naveedm9@gmail.com>
8387 jasonmay: Jason May <jason.a.may@gmail.com>
98102 jshirley: J. Shirley <jshirley@gmail.com>
99103 kaare: Kaare Rasmussen
100104 kd: Kieren Diment <diment@gmail.com>
105 kkane: Kevin L. Kane <kevin.kane@gmail.com>
101106 konobi: Scott McWhirter <konobi@cpan.org>
102107 lejeunerenard: Sean Zellmer <sean@lejeunerenard.com>
103108 littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
193198 typester: Daisuke Murase <typester@cpan.org>
194199 uree: Oriol Soriano <oriol.soriano@capside.com>
195200 uwe: Uwe Voelker <uwe@uwevoelker.de>
201 vanstyn: Henry Van Styn <vanstyn@cpan.org>
196202 victori: Victor Igumnov <victori@cpan.org>
197203 wdh: Will Hawes <wdhawes@gmail.com>
198204 wesm: Wes Malone <wes@mitsi.com>
200206 wintermute: Toby Corkindale <tjc@cpan.org>
201207 wreis: Wallace Reis <wreis@cpan.org>
202208 xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
209 xmikew: Mike Wisener <xmikew@32ths.com>
203210 yrlnry: Mark Jason Dominus <mjd@plover.com>
204211 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
205212 Zefram: Andrew Main <zefram@fysh.org>
00 Revision history for DBIx::Class
1
2 0.082820 2015-03-20 20:35 (UTC)
3 * Fixes
4 - Protect destructors from rare but possible double execution, and
5 loudly warn the user whenever the problem is encountered (GH#63)
6 - Relax the 'self_result_object' argument check in the relationship
7 resolution codepath, restoring exotic uses of inflate_result
8 http://lists.scsys.co.uk/pipermail/dbix-class/2015-January/011876.html
9 - Fix updating multiple CLOB/BLOB columns on Oracle
10 - Fix exception on complex update/delete under a replicated setup
11 http://lists.scsys.co.uk/pipermail/dbix-class/2015-January/011903.html
12 - Fix uninitialized warnings on empty hashes passed to join/prefetch
13 https://github.com/vanstyn/RapidApp/commit/6f41f6e48 and
14 http://lists.scsys.co.uk/pipermail/dbix-class/2015-February/011921.html
15 - Fix hang in t/72pg.t when run against DBD::Pg 3.5.0. The ping()
16 implementation changes due to RT#100648 made an alarm() based
17 timeout lock-prone.
18
19 * Misc
20 - Remove warning about potential side effects of RT#79576 (scheduled)
21 - Various doc improvements (GH#35, GH#62, GH#66, GH#70, GH#71, GH#72)
22 - Depend on newer Moo, to benefit from a safer runtime (RT#93004)
23 - Fix intermittent failures in the LeakTracer on 5.18+
24 - Fix failures of t/54taint.t on Windows with spaces in the $^X
25 executable path (RT#101615)
126
227 0.082810 2014-10-25 13:58 (UTC)
328 * Fixes
0 DBIx::Class is Copyright (c) 2005-2014 by mst, castaway, ribasushi, and others.
0 DBIx::Class is Copyright (c) 2005-2015 by mst, castaway, ribasushi, and others.
11 See AUTHORS and LICENSE included with this distribution. All rights reserved.
22
33 This is free software; you can redistribute it and/or modify it under the
225225 META.yml
226226 README
227227 script/dbicadmin
228 t/00describe_environment.t
228229 t/04_c3_mro.t
229230 t/05components.t
230231 t/100extra_source.t
688689 t/update/all.t
689690 t/update/ident_cond.t
690691 t/update/type_aware.t
692 t/zzzzzzz_authors.t
691693 t/zzzzzzz_perl_perf_bug.t
692694 t/zzzzzzz_sqlite_deadlock.t
693695 xt/authors.t
5151 List::Util: 1.16
5252 MRO::Compat: 0.12
5353 Module::Find: 0.07
54 Moo: 1.006001
54 Moo: 2.000
5555 Path::Class: 0.18
5656 SQL::Abstract: 1.81
5757 Scope::Guard: 0.03
6767 homepage: http://www.dbix-class.org/
6868 license: http://dev.perl.org/licenses/
6969 repository: https://github.com/dbsrgits/DBIx-Class
70 version: 0.082810
70 version: 0.082820
7171 x_authority: cpan:RIBASUSHI
7272 x_contributors:
7373 - 'abraxxa: Alexander Hartmaier <abraxxa@cpan.org>'
7676 - 'Alexander Keusch <cpan@keusch.at>'
7777 - 'alexrj: Alessandro Ranellucci <aar@cpan.org>'
7878 - 'alnewkirk: Al Newkirk <github@alnewkirk.com>'
79 - 'Altreus: Alastair McGowan-Douglas <alastair.mcgowan@opusvl.com>'
7980 - 'amiri: Amiri Barksdale <amiribarksdale@gmail.com>'
8081 - 'amoore: Andrew Moore <amoore@cpan.org>'
8182 - 'Andrew Mehta <Andrew@unitedgames.co.uk>'
99100 - 'caldrin: Maik Hentsche <maik.hentsche@amd.com>'
100101 - 'castaway: Jess Robinson <castaway@desert-island.me.uk>'
101102 - 'chorny: Alexandr Ciornii <alexchorny@gmail.com>'
103 - 'cj: C.J. Adams-Collier <cjcollier@cpan.org>'
102104 - 'claco: Christopher H. Laco <claco@cpan.org>'
103105 - 'clkao: CL Kao <clkao@clkao.org>'
104106 - 'Ctrl-O http://ctrlo.com/'
115117 - 'dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>'
116118 - 'dnm: Justin Wheeler <jwheeler@datademons.com>'
117119 - 'dpetrov: Dimitar Petrov <mitakaa@gmail.com>'
120 - 'Dr^ZigMan: Robert Stone <drzigman@drzigman.com>'
118121 - 'dsteinbrunner: David Steinbrunner <dsteinbrunner@pobox.com>'
119122 - 'duncan_dmg: Duncan Garland <Duncan.Garland@motortrak.com>'
120123 - 'dwc: Daniel Westermann-Clark <danieltwc@cpan.org>'
140143 - 'Ian Wells <ijw@cack.org.uk>'
141144 - 'idn: Ian Norton <i.norton@shadowcat.co.uk>'
142145 - 'ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>'
146 - 'ingy: Ingy döt Net <ingy@ingy.net>'
143147 - 'initself: Mike Baas <mike@initselftech.com>'
144148 - 'ironcamel: Naveed Massjouni <naveedm9@gmail.com>'
145149 - 'jasonmay: Jason May <jason.a.may@gmail.com>'
160164 - 'jshirley: J. Shirley <jshirley@gmail.com>'
161165 - 'kaare: Kaare Rasmussen'
162166 - 'kd: Kieren Diment <diment@gmail.com>'
167 - 'kkane: Kevin L. Kane <kevin.kane@gmail.com>'
163168 - 'konobi: Scott McWhirter <konobi@cpan.org>'
164169 - 'lejeunerenard: Sean Zellmer <sean@lejeunerenard.com>'
165170 - 'littlesavage: Alexey Illarionov <littlesavage@orionet.ru>'
255260 - 'typester: Daisuke Murase <typester@cpan.org>'
256261 - 'uree: Oriol Soriano <oriol.soriano@capside.com>'
257262 - 'uwe: Uwe Voelker <uwe@uwevoelker.de>'
263 - 'vanstyn: Henry Van Styn <vanstyn@cpan.org>'
258264 - 'victori: Victor Igumnov <victori@cpan.org>'
259265 - 'wdh: Will Hawes <wdhawes@gmail.com>'
260266 - 'wesm: Wes Malone <wes@mitsi.com>'
262268 - 'wintermute: Toby Corkindale <tjc@cpan.org>'
263269 - 'wreis: Wallace Reis <wreis@cpan.org>'
264270 - 'xenoterracide: Caleb Cushing <xenoterracide@gmail.com>'
271 - 'xmikew: Mike Wisener <xmikew@32ths.com>'
265272 - 'yrlnry: Mark Jason Dominus <mjd@plover.com>'
266273 - 'zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>'
267274 - 'Zefram: Andrew Main <zefram@fysh.org>'
5555 'Data::Page' => '2.00',
5656 'Devel::GlobalDestruction' => '0.09',
5757 'Hash::Merge' => '0.12',
58 'Moo' => '1.006001',
58 'Moo' => '2.000',
5959 'MRO::Compat' => '0.12',
6060 'Module::Find' => '0.07',
6161 'namespace::clean' => '0.24',
+335
-321
README less more
0 DBIx::Class is Copyright (c) 2005-2014 by mst, castaway, ribasushi, and others.
0 DBIx::Class is Copyright (c) 2005-2015 by mst, castaway, ribasushi, and others.
11 See AUTHORS and LICENSE included with this distribution. All rights reserved.
22
33 NAME
203203 questions and suggestions have been shown to catalyze monumental
204204 improvements in consistency, accuracy and performance.
205205
206 List of the awesome contributors who made DBIC v0.082810 possible
207
208 abraxxa:Alexander Hartmaier <abraxxa@cpan.org>
209
210 acca:Alexander Kuznetsov <acca@cpan.org>
211
212 aherzog:Adam Herzog <adam@herzogdesigns.com>
206 List of the awesome contributors who made DBIC v0.082820 possible
207
208 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
209
210 acca: Alexander Kuznetsov <acca@cpan.org>
211
212 aherzog: Adam Herzog <adam@herzogdesigns.com>
213213
214214 Alexander Keusch <cpan@keusch.at>
215215
216 alexrj:Alessandro Ranellucci <aar@cpan.org>
217
218 alnewkirk:Al Newkirk <github@alnewkirk.com>
219
220 amiri:Amiri Barksdale <amiribarksdale@gmail.com>
221
222 amoore:Andrew Moore <amoore@cpan.org>
216 alexrj: Alessandro Ranellucci <aar@cpan.org>
217
218 alnewkirk: Al Newkirk <github@alnewkirk.com>
219
220 Altreus: Alastair McGowan-Douglas <alastair.mcgowan@opusvl.com>
221
222 amiri: Amiri Barksdale <amiribarksdale@gmail.com>
223
224 amoore: Andrew Moore <amoore@cpan.org>
223225
224226 Andrew Mehta <Andrew@unitedgames.co.uk>
225227
226 andrewalker:Andre Walker <andre@andrewalker.net>
227
228 andyg:Andy Grundman <andy@hybridized.org>
229
230 ank:Andres Kievsky <ank@ank.com.ar>
231
232 arc:Aaron Crane <arc@cpan.org>
233
234 arcanez:Justin Hunter <justin.d.hunter@gmail.com>
235
236 ash:Ash Berlin <ash@cpan.org>
237
238 bert:Norbert Csongrádi <bert@cpan.org>
239
240 bfwg:Colin Newell <colin.newell@gmail.com>
241
242 blblack:Brandon L. Black <blblack@gmail.com>
243
244 bluefeet:Aran Deltac <bluefeet@cpan.org>
245
246 boghead:Bryan Beeley <cpan@beeley.org>
247
248 bphillips:Brian Phillips <bphillips@cpan.org>
249
250 brd:Brad Davis <brd@FreeBSD.org>
228 andrewalker: Andre Walker <andre@andrewalker.net>
229
230 andyg: Andy Grundman <andy@hybridized.org>
231
232 ank: Andres Kievsky <ank@ank.com.ar>
233
234 arc: Aaron Crane <arc@cpan.org>
235
236 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
237
238 ash: Ash Berlin <ash@cpan.org>
239
240 bert: Norbert Csongrádi <bert@cpan.org>
241
242 bfwg: Colin Newell <colin.newell@gmail.com>
243
244 blblack: Brandon L. Black <blblack@gmail.com>
245
246 bluefeet: Aran Deltac <bluefeet@cpan.org>
247
248 boghead: Bryan Beeley <cpan@beeley.org>
249
250 bphillips: Brian Phillips <bphillips@cpan.org>
251
252 brd: Brad Davis <brd@FreeBSD.org>
251253
252254 Brian Kirkbride <brian.kirkbride@deeperbydesign.com>
253255
254 bricas:Brian Cassidy <bricas@cpan.org>
255
256 brunov:Bruno Vecchi <vecchi.b@gmail.com>
257
258 caelum:Rafael Kitover <rkitover@cpan.org>
259
260 caldrin:Maik Hentsche <maik.hentsche@amd.com>
261
262 castaway:Jess Robinson <castaway@desert-island.me.uk>
263
264 chorny:Alexandr Ciornii <alexchorny@gmail.com>
265
266 claco:Christopher H. Laco <claco@cpan.org>
267
268 clkao:CL Kao <clkao@clkao.org>
256 bricas: Brian Cassidy <bricas@cpan.org>
257
258 brunov: Bruno Vecchi <vecchi.b@gmail.com>
259
260 caelum: Rafael Kitover <rkitover@cpan.org>
261
262 caldrin: Maik Hentsche <maik.hentsche@amd.com>
263
264 castaway: Jess Robinson <castaway@desert-island.me.uk>
265
266 chorny: Alexandr Ciornii <alexchorny@gmail.com>
267
268 cj: C.J. Adams-Collier <cjcollier@cpan.org>
269
270 claco: Christopher H. Laco <claco@cpan.org>
271
272 clkao: CL Kao <clkao@clkao.org>
269273
270274 Ctrl-O <http://ctrlo.com/>
271275
272 da5id:David Jack Olrik <david@olrik.dk>
273
274 dams:Damien Krotkine <dams@cpan.org>
275
276 dandv:Dan Dascalescu <ddascalescu+github@gmail.com>
277
278 dariusj:Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
279
280 davewood:David Schmidt <mail@davidschmidt.at>
281
282 daxim:Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
283
284 dduncan:Darren Duncan <darren@darrenduncan.net>
285
286 debolaz:Anders Nor Berle <berle@cpan.org>
287
288 dew:Dan Thomas <dan@godders.org>
289
290 dim0xff:Dmitry Latin <dim0xff@gmail.com>
291
292 dkubb:Dan Kubb <dan.kubb-cpan@onautopilot.com>
293
294 dnm:Justin Wheeler <jwheeler@datademons.com>
295
296 dpetrov:Dimitar Petrov <mitakaa@gmail.com>
297
298 dsteinbrunner:David Steinbrunner <dsteinbrunner@pobox.com>
299
300 duncan_dmg:Duncan Garland <Duncan.Garland@motortrak.com>
301
302 dwc:Daniel Westermann-Clark <danieltwc@cpan.org>
303
304 dyfrgi:Michael Leuchtenburg <michael@slashhome.org>
305
306 edenc:Eden Cardim <edencardim@gmail.com>
276 da5id: David Jack Olrik <david@olrik.dk>
277
278 dams: Damien Krotkine <dams@cpan.org>
279
280 dandv: Dan Dascalescu <ddascalescu+github@gmail.com>
281
282 dariusj: Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
283
284 davewood: David Schmidt <mail@davidschmidt.at>
285
286 daxim: Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
287
288 dduncan: Darren Duncan <darren@darrenduncan.net>
289
290 debolaz: Anders Nor Berle <berle@cpan.org>
291
292 dew: Dan Thomas <dan@godders.org>
293
294 dim0xff: Dmitry Latin <dim0xff@gmail.com>
295
296 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
297
298 dnm: Justin Wheeler <jwheeler@datademons.com>
299
300 dpetrov: Dimitar Petrov <mitakaa@gmail.com>
301
302 Dr^ZigMan: Robert Stone <drzigman@drzigman.com>
303
304 dsteinbrunner: David Steinbrunner <dsteinbrunner@pobox.com>
305
306 duncan_dmg: Duncan Garland <Duncan.Garland@motortrak.com>
307
308 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
309
310 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
311
312 edenc: Eden Cardim <edencardim@gmail.com>
307313
308314 Eligo <http://eligo.co.uk/>
309315
310 ether:Karen Etheridge <ether@cpan.org>
311
312 evdb:Edmund von der Burg <evdb@ecclestoad.co.uk>
313
314 faxm0dem:Fabien Wernli <cpan@faxm0dem.org>
315
316 felliott:Fitz Elliott <fitz.elliott@gmail.com>
317
318 freetime:Bill Moseley <moseley@hank.org>
319
320 frew:Arthur Axel "fREW" Schmidt <frioux@gmail.com>
321
322 gbjk:Gareth Kirwan <gbjk@thermeon.com>
323
324 Getty:Torsten Raudssus <torsten@raudss.us>
325
326 goraxe:Gordon Irving <goraxe@cpan.org>
327
328 gphat:Cory G Watson <gphat@cpan.org>
316 ether: Karen Etheridge <ether@cpan.org>
317
318 evdb: Edmund von der Burg <evdb@ecclestoad.co.uk>
319
320 faxm0dem: Fabien Wernli <cpan@faxm0dem.org>
321
322 felliott: Fitz Elliott <fitz.elliott@gmail.com>
323
324 freetime: Bill Moseley <moseley@hank.org>
325
326 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
327
328 gbjk: Gareth Kirwan <gbjk@thermeon.com>
329
330 Getty: Torsten Raudssus <torsten@raudss.us>
331
332 goraxe: Gordon Irving <goraxe@cpan.org>
333
334 gphat: Cory G Watson <gphat@cpan.org>
329335
330336 Grant Street Group <http://www.grantstreet.com/>
331337
332 groditi:Guillermo Roditi <groditi@cpan.org>
333
334 gshank:Gerda Shank <gshank@cpan.org>
335
336 guacamole:Fred Steinberg <fred.steinberg@gmail.com>
337
338 Haarg:Graham Knop <haarg@haarg.org>
339
340 hobbs:Andrew Rodland <andrew@cleverdomain.org>
338 groditi: Guillermo Roditi <groditi@cpan.org>
339
340 gshank: Gerda Shank <gshank@cpan.org>
341
342 guacamole: Fred Steinberg <fred.steinberg@gmail.com>
343
344 Haarg: Graham Knop <haarg@haarg.org>
345
346 hobbs: Andrew Rodland <andrew@cleverdomain.org>
341347
342348 Ian Wells <ijw@cack.org.uk>
343349
344 idn:Ian Norton <i.norton@shadowcat.co.uk>
345
346 ilmari:Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
347
348 initself:Mike Baas <mike@initselftech.com>
349
350 ironcamel:Naveed Massjouni <naveedm9@gmail.com>
351
352 jasonmay:Jason May <jason.a.may@gmail.com>
353
354 jawnsy:Jonathan Yu <jawnsy@cpan.org>
355
356 jegade:Jens Gassmann <jens.gassmann@atomix.de>
357
358 jeneric:Eric A. Miller <emiller@cpan.org>
359
360 jesper:Jesper Krogh <jesper@krogh.cc>
350 idn: Ian Norton <i.norton@shadowcat.co.uk>
351
352 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
353
354 ingy: Ingy döt Net <ingy@ingy.net>
355
356 initself: Mike Baas <mike@initselftech.com>
357
358 ironcamel: Naveed Massjouni <naveedm9@gmail.com>
359
360 jasonmay: Jason May <jason.a.may@gmail.com>
361
362 jawnsy: Jonathan Yu <jawnsy@cpan.org>
363
364 jegade: Jens Gassmann <jens.gassmann@atomix.de>
365
366 jeneric: Eric A. Miller <emiller@cpan.org>
367
368 jesper: Jesper Krogh <jesper@krogh.cc>
361369
362370 Jesse Sheidlower <jester@panix.com>
363371
364 jgoulah:John Goulah <jgoulah@cpan.org>
365
366 jguenther:Justin Guenther <jguenther@cpan.org>
367
368 jhannah:Jay Hannah <jay@jays.net>
369
370 jmac:Jason McIntosh <jmac@appleseed-sc.com>
371
372 jmmills:Jason M. Mills <jmmills@cpan.org>
373
374 jnapiorkowski:John Napiorkowski <jjn1056@yahoo.com>
372 jgoulah: John Goulah <jgoulah@cpan.org>
373
374 jguenther: Justin Guenther <jguenther@cpan.org>
375
376 jhannah: Jay Hannah <jay@jays.net>
377
378 jmac: Jason McIntosh <jmac@appleseed-sc.com>
379
380 jmmills: Jason M. Mills <jmmills@cpan.org>
381
382 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
375383
376384 Joe Carlson <jwcarlson@lbl.gov>
377385
378 jon:Jon Schutz <jjschutz@cpan.org>
386 jon: Jon Schutz <jjschutz@cpan.org>
379387
380388 Jordan Metzmeier <jmetzmeier@magazines.com>
381389
382 jshirley:J. Shirley <jshirley@gmail.com>
383
384 kaare:Kaare Rasmussen
385
386 kd:Kieren Diment <diment@gmail.com>
387
388 konobi:Scott McWhirter <konobi@cpan.org>
389
390 lejeunerenard:Sean Zellmer <sean@lejeunerenard.com>
391
392 littlesavage:Alexey Illarionov <littlesavage@orionet.ru>
393
394 lukes:Luke Saunders <luke.saunders@gmail.com>
395
396 marcus:Marcus Ramberg <mramberg@cpan.org>
397
398 mateu:Mateu X. Hunter <hunter@missoula.org>
390 jshirley: J. Shirley <jshirley@gmail.com>
391
392 kaare: Kaare Rasmussen
393
394 kd: Kieren Diment <diment@gmail.com>
395
396 kkane: Kevin L. Kane <kevin.kane@gmail.com>
397
398 konobi: Scott McWhirter <konobi@cpan.org>
399
400 lejeunerenard: Sean Zellmer <sean@lejeunerenard.com>
401
402 littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
403
404 lukes: Luke Saunders <luke.saunders@gmail.com>
405
406 marcus: Marcus Ramberg <mramberg@cpan.org>
407
408 mateu: Mateu X. Hunter <hunter@missoula.org>
399409
400410 Matt LeBlanc <antirice@gmail.com>
401411
402412 Matt Sickler <imMute@msk4.com>
403413
404 mattlaw:Matt Lawrence
405
406 mattp:Matt Phillips <mattp@cpan.org>
407
408 mdk:Mark Keating <m.keating@shadowcat.co.uk>
409
410 melo:Pedro Melo <melo@simplicidade.org>
411
412 metaperl:Terrence Brannon <metaperl@gmail.com>
413
414 michaelr:Michael Reddick <michael.reddick@gmail.com>
415
416 milki:Jonathan Chu <milki@rescomp.berkeley.edu>
417
418 minty:Murray Walker <perl@minty.org>
419
420 mithaldu:Christian Walde <walde.christian@gmail.com>
421
422 mjemmeson:Michael Jemmeson <michael.jemmeson@gmail.com>
423
424 mna:Maya
425
426 mo:Moritz Onken <onken@netcubed.de>
427
428 moltar:Roman Filippov <romanf@cpan.org>
429
430 moritz:Moritz Lenz <moritz@faui2k3.org>
431
432 mrf:Mike Francis <ungrim97@gmail.com>
433
434 mst:Matt S. Trout <mst@shadowcat.co.uk>
435
436 mstratman:Mark A. Stratman <stratman@gmail.com>
437
438 ned:Neil de Carteret <n3dst4@gmail.com>
439
440 nigel:Nigel Metheringham <nigelm@cpan.org>
441
442 ningu:David Kamholz <dkamholz@cpan.org>
443
444 Nniuq:Ron "Quinn" Straight" <quinnfazigu@gmail.org>
445
446 norbi:Norbert Buchmuller <norbi@nix.hu>
447
448 nothingmuch:Yuval Kogman <nothingmuch@woobling.org>
449
450 nuba:Nuba Princigalli <nuba@cpan.org>
451
452 Numa:Dan Sully <daniel@cpan.org>
453
454 oalders:Olaf Alders <olaf@wundersolutions.com>
414 mattlaw: Matt Lawrence
415
416 mattp: Matt Phillips <mattp@cpan.org>
417
418 mdk: Mark Keating <m.keating@shadowcat.co.uk>
419
420 melo: Pedro Melo <melo@simplicidade.org>
421
422 metaperl: Terrence Brannon <metaperl@gmail.com>
423
424 michaelr: Michael Reddick <michael.reddick@gmail.com>
425
426 milki: Jonathan Chu <milki@rescomp.berkeley.edu>
427
428 minty: Murray Walker <perl@minty.org>
429
430 mithaldu: Christian Walde <walde.christian@gmail.com>
431
432 mjemmeson: Michael Jemmeson <michael.jemmeson@gmail.com>
433
434 mna: Maya
435
436 mo: Moritz Onken <onken@netcubed.de>
437
438 moltar: Roman Filippov <romanf@cpan.org>
439
440 moritz: Moritz Lenz <moritz@faui2k3.org>
441
442 mrf: Mike Francis <ungrim97@gmail.com>
443
444 mst: Matt S. Trout <mst@shadowcat.co.uk>
445
446 mstratman: Mark A. Stratman <stratman@gmail.com>
447
448 ned: Neil de Carteret <n3dst4@gmail.com>
449
450 nigel: Nigel Metheringham <nigelm@cpan.org>
451
452 ningu: David Kamholz <dkamholz@cpan.org>
453
454 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
455
456 norbi: Norbert Buchmuller <norbi@nix.hu>
457
458 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
459
460 nuba: Nuba Princigalli <nuba@cpan.org>
461
462 Numa: Dan Sully <daniel@cpan.org>
463
464 oalders: Olaf Alders <olaf@wundersolutions.com>
455465
456466 Olly Betts <olly@survex.com>
457467
458 osfameron:Hakim Cassimally <osfameron@cpan.org>
459
460 ovid:Curtis "Ovid" Poe <ovid@cpan.org>
461
462 oyse:Øystein Torget <oystein.torget@dnv.com>
463
464 paulm:Paul Makepeace <paulm+pause@paulm.com>
465
466 penguin:K J Cheetham <jamie@shadowcatsystems.co.uk>
467
468 perigrin:Chris Prather <chris@prather.org>
468 osfameron: Hakim Cassimally <osfameron@cpan.org>
469
470 ovid: Curtis "Ovid" Poe <ovid@cpan.org>
471
472 oyse: Øystein Torget <oystein.torget@dnv.com>
473
474 paulm: Paul Makepeace <paulm+pause@paulm.com>
475
476 penguin: K J Cheetham <jamie@shadowcatsystems.co.uk>
477
478 perigrin: Chris Prather <chris@prather.org>
469479
470480 Peter Siklósi <einon@einon.hu>
471481
472482 Peter Valdemar Mørch <peter@morch.com>
473483
474 peter:Peter Collingbourne <peter@pcc.me.uk>
475
476 phaylon:Robert Sedlacek <phaylon@dunkelheit.at>
477
478 plu:Johannes Plunien <plu@cpan.org>
479
480 Possum:Daniel LeWarne <possum@cpan.org>
481
482 pplu:Jose Luis Martinez <jlmartinez@capside.com>
483
484 quicksilver:Jules Bean <jules@jellybean.co.uk>
485
486 racke:Stefan Hornburg <racke@linuxia.de>
487
488 rafl:Florian Ragwitz <rafl@debian.org>
489
490 rainboxx:Matthias Dietrich <perl@rb.ly>
491
492 rbo:Robert Bohne <rbo@cpan.org>
493
494 rbuels:Robert Buels <rmb32@cornell.edu>
495
496 rdj:Ryan D Johnson <ryan@innerfence.com>
497
498 Relequestual:Ben Hutton <relequestual@gmail.com>
499
500 renormalist:Steffen Schwigon <schwigon@cpan.org>
501
502 ribasushi:Peter Rabbitson <ribasushi@cpan.org>
503
504 rjbs:Ricardo Signes <rjbs@cpan.org>
484 peter: Peter Collingbourne <peter@pcc.me.uk>
485
486 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
487
488 plu: Johannes Plunien <plu@cpan.org>
489
490 Possum: Daniel LeWarne <possum@cpan.org>
491
492 pplu: Jose Luis Martinez <jlmartinez@capside.com>
493
494 quicksilver: Jules Bean <jules@jellybean.co.uk>
495
496 racke: Stefan Hornburg <racke@linuxia.de>
497
498 rafl: Florian Ragwitz <rafl@debian.org>
499
500 rainboxx: Matthias Dietrich <perl@rb.ly>
501
502 rbo: Robert Bohne <rbo@cpan.org>
503
504 rbuels: Robert Buels <rmb32@cornell.edu>
505
506 rdj: Ryan D Johnson <ryan@innerfence.com>
507
508 Relequestual: Ben Hutton <relequestual@gmail.com>
509
510 renormalist: Steffen Schwigon <schwigon@cpan.org>
511
512 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
513
514 rjbs: Ricardo Signes <rjbs@cpan.org>
505515
506516 Robert Krimen <rkrimen@cpan.org>
507517
508518 Robert Olson <bob@rdolson.org>
509519
510 robkinyon:Rob Kinyon <rkinyon@cpan.org>
520 robkinyon: Rob Kinyon <rkinyon@cpan.org>
511521
512522 Roman Ardern-Corris <spam_in@3legs.com>
513523
514 ruoso:Daniel Ruoso <daniel@ruoso.com>
515
516 Sadrak:Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
517
518 sc_:Just Another Perl Hacker
519
520 schwern:Michael G Schwern <mschwern@cpan.org>
524 ruoso: Daniel Ruoso <daniel@ruoso.com>
525
526 Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
527
528 sc_: Just Another Perl Hacker
529
530 schwern: Michael G Schwern <mschwern@cpan.org>
521531
522532 Scott R. Godin <webdragon.net@gmail.com>
523533
524 scotty:Scotty Allen <scotty@scottyallen.com>
525
526 semifor:Marc Mims <marc@questright.com>
534 scotty: Scotty Allen <scotty@scottyallen.com>
535
536 semifor: Marc Mims <marc@questright.com>
527537
528538 Simon Elliott <cpan@browsing.co.uk>
529539
530 SineSwiper:Brendan Byrd <perl@resonatorsoft.org>
531
532 skaufman:Samuel Kaufman <sam@socialflow.com>
533
534 solomon:Jared Johnson <jaredj@nmgi.com>
535
536 spb:Stephen Bennett <stephen@freenode.net>
540 SineSwiper: Brendan Byrd <perl@resonatorsoft.org>
541
542 skaufman: Samuel Kaufman <sam@socialflow.com>
543
544 solomon: Jared Johnson <jaredj@nmgi.com>
545
546 spb: Stephen Bennett <stephen@freenode.net>
537547
538548 Squeeks <squeek@cpan.org>
539549
540 srezic:Slaven Rezic <slaven@rezic.de>
541
542 sszabo:Stephan Szabo <sszabo@bigpanda.com>
550 srezic: Slaven Rezic <slaven@rezic.de>
551
552 sszabo: Stephan Szabo <sszabo@bigpanda.com>
543553
544554 Stephen Peters <steve@stephenpeters.me>
545555
546 stonecolddevin:Devin Austin <dhoss@cpan.org>
547
548 talexb:Alex Beamish <talexb@gmail.com>
549
550 tamias:Ronald J Kimball <rjk@tamias.net>
551
552 TBSliver:Tom Bloor <t.bloor@shadowcat.co.uk>
553
554 teejay:Aaron Trevena <teejay@cpan.org>
555
556 theorbtwo:James Mastros <james@mastros.biz>
556 stonecolddevin: Devin Austin <dhoss@cpan.org>
557
558 talexb: Alex Beamish <talexb@gmail.com>
559
560 tamias: Ronald J Kimball <rjk@tamias.net>
561
562 TBSliver: Tom Bloor <t.bloor@shadowcat.co.uk>
563
564 teejay: Aaron Trevena <teejay@cpan.org>
565
566 theorbtwo: James Mastros <james@mastros.biz>
557567
558568 Thomas Kratz <tomk@cpan.org>
559569
560 timbunce:Tim Bunce <tim.bunce@pobox.com>
570 timbunce: Tim Bunce <tim.bunce@pobox.com>
561571
562572 Todd Lipcon
563573
564574 Tom Hukins <tom@eborcom.com>
565575
566 tommy:Tommy Butler <tbutler.cpan.org@internetalias.net>
567
568 tonvoon:Ton Voon <ton.voon@opsview.com>
569
570 triode:Pete Gamache <gamache@cpan.org>
571
572 typester:Daisuke Murase <typester@cpan.org>
573
574 uree:Oriol Soriano <oriol.soriano@capside.com>
575
576 uwe:Uwe Voelker <uwe@uwevoelker.de>
577
578 victori:Victor Igumnov <victori@cpan.org>
579
580 wdh:Will Hawes <wdhawes@gmail.com>
581
582 wesm:Wes Malone <wes@mitsi.com>
583
584 willert:Sebastian Willert <willert@cpan.org>
585
586 wintermute:Toby Corkindale <tjc@cpan.org>
587
588 wreis:Wallace Reis <wreis@cpan.org>
589
590 xenoterracide:Caleb Cushing <xenoterracide@gmail.com>
591
592 yrlnry:Mark Jason Dominus <mjd@plover.com>
593
594 zamolxes:Bogdan Lucaciu <bogdan@wiz.ro>
595
596 Zefram:Andrew Main <zefram@fysh.org>
576 tommy: Tommy Butler <tbutler.cpan.org@internetalias.net>
577
578 tonvoon: Ton Voon <ton.voon@opsview.com>
579
580 triode: Pete Gamache <gamache@cpan.org>
581
582 typester: Daisuke Murase <typester@cpan.org>
583
584 uree: Oriol Soriano <oriol.soriano@capside.com>
585
586 uwe: Uwe Voelker <uwe@uwevoelker.de>
587
588 vanstyn: Henry Van Styn <vanstyn@cpan.org>
589
590 victori: Victor Igumnov <victori@cpan.org>
591
592 wdh: Will Hawes <wdhawes@gmail.com>
593
594 wesm: Wes Malone <wes@mitsi.com>
595
596 willert: Sebastian Willert <willert@cpan.org>
597
598 wintermute: Toby Corkindale <tjc@cpan.org>
599
600 wreis: Wallace Reis <wreis@cpan.org>
601
602 xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
603
604 xmikew: Mike Wisener <xmikew@32ths.com>
605
606 yrlnry: Mark Jason Dominus <mjd@plover.com>
607
608 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
609
610 Zefram: Andrew Main <zefram@fysh.org>
597611
598612 The canonical source of authors and their details is the AUTHORS file at
599613 the root of this distribution (or repository). The canonical source of
2020
2121 __PACKAGE__->add_unique_constraint([qw( name )]);
2222
23 __PACKAGE__->has_many('cds' => 'MyApp::Schema::Result::Cd');
23 __PACKAGE__->has_many('cds' => 'MyApp::Schema::Result::Cd', 'artistid');
2424
2525 1;
2626
1111 data_type => 'integer',
1212 is_auto_increment => 1
1313 },
14 artist => {
14 artistid => {
1515 data_type => 'integer',
1616 },
1717 title => {
2525
2626 __PACKAGE__->set_primary_key('cdid');
2727
28 __PACKAGE__->add_unique_constraint([qw( title artist )]);
28 __PACKAGE__->add_unique_constraint([qw( title artistid )]);
2929
30 __PACKAGE__->belongs_to('artist' => 'MyApp::Schema::Result::Artist');
31 __PACKAGE__->has_many('tracks' => 'MyApp::Schema::Result::Track');
30 __PACKAGE__->belongs_to('artist' => 'MyApp::Schema::Result::Artist', 'artistid');
31 __PACKAGE__->has_many('tracks' => 'MyApp::Schema::Result::Track', 'cdid');
3232
3333 1;
1111 data_type => 'integer',
1212 is_auto_increment => 1
1313 },
14 cd => {
14 cdid => {
1515 data_type => 'integer',
1616 },
1717 title => {
2121
2222 __PACKAGE__->set_primary_key('trackid');
2323
24 __PACKAGE__->add_unique_constraint([qw( title cd )]);
24 __PACKAGE__->add_unique_constraint([qw( title cdid )]);
2525
26 __PACKAGE__->belongs_to('cd' => 'MyApp::Schema::Result::Cd');
26 __PACKAGE__->belongs_to('cd' => 'MyApp::Schema::Result::Cd', 'cdid');
2727
2828 1;
66
77 CREATE TABLE "cd" (
88 "cdid" INTEGER PRIMARY KEY NOT NULL,
9 "artist" integer NOT NULL,
9 "artistid" integer NOT NULL,
1010 "title" text NOT NULL,
1111 "year" datetime,
12 FOREIGN KEY ("artist") REFERENCES "artist"("artistid") ON DELETE CASCADE ON UPDATE CASCADE
12 FOREIGN KEY ("artistid") REFERENCES "artist"("artistid") ON DELETE CASCADE ON UPDATE CASCADE
1313 );
1414
15 CREATE INDEX "cd_idx_artist" ON "cd" ("artist");
15 CREATE INDEX "cd_idx_artistid" ON "cd" ("artistid");
1616
17 CREATE UNIQUE INDEX "cd_title_artist" ON "cd" ("title", "artist");
17 CREATE UNIQUE INDEX "cd_title_artistid" ON "cd" ("title", "artistid");
1818
1919 CREATE TABLE "track" (
2020 "trackid" INTEGER PRIMARY KEY NOT NULL,
21 "cd" integer NOT NULL,
21 "cdid" integer NOT NULL,
2222 "title" text NOT NULL,
23 FOREIGN KEY ("cd") REFERENCES "cd"("cdid") ON DELETE CASCADE ON UPDATE CASCADE
23 FOREIGN KEY ("cdid") REFERENCES "cd"("cdid") ON DELETE CASCADE ON UPDATE CASCADE
2424 );
2525
26 CREATE INDEX "track_idx_cd" ON "track" ("cd");
26 CREATE INDEX "track_idx_cdid" ON "track" ("cdid");
2727
28 CREATE UNIQUE INDEX "track_title_cd" ON "track" ("title", "cd");
28 CREATE UNIQUE INDEX "track_title_cdid" ON "track" ("title", "cdid");
3030 }
3131
3232 $schema->populate('Cd', [
33 [qw/title artist/],
33 [qw/title artistid/],
3434 @cds,
3535 ]);
3636
5454 }
5555
5656 $schema->populate('Track',[
57 [qw/cd title/],
57 [qw/cdid title/],
5858 @tracks,
5959 ]);
5252 }
5353 );
5454 while (my $track = $rs->next) {
55 print $track->title . "\n";
55 print $track->title . " (from the CD '" . $track->cd->title
56 . "')\n";
5657 }
5758 print "\n";
5859 }
6970 }
7071 );
7172 my $cd = $rs->first;
72 print $cd->title . "\n\n";
73 print $cd->title . " has the track '$tracktitle'.\n\n";
7374 }
7475
7576 sub get_cds_by_artist {
103104 }
104105 );
105106 my $artist = $rs->first;
106 print $artist->name . "\n\n";
107 print $artist->name . " recorded the track '$tracktitle'.\n\n";
107108 }
108109
109110 sub get_artist_by_cd {
118119 }
119120 );
120121 my $artist = $rs->first;
121 print $artist->name . "\n\n";
122 print $artist->name . " recorded the CD '$cdtitle'.\n\n";
122123 }
22
33 use strict;
44 use warnings;
5 use DBIx::Class::_Util 'detected_reinvoked_destructor';
6 use namespace::clean;
57
68 sub DESTROY {
9 return if &detected_reinvoked_destructor;
10
711 my ($self) = @_;
812 my $class = ref $self;
913 warn "$class $self destroyed without saving changes to "
17691769 =head2 Formatting DateTime objects in queries
17701770
17711771 To ensure C<WHERE> conditions containing L<DateTime> arguments are properly
1772 formatted to be understood by your RDBMS, you must use the C<DateTime>
1772 formatted to be understood by your RDBMS, you must use the L<DateTime>
17731773 formatter returned by L<DBIx::Class::Storage::DBI/datetime_parser> to format
17741774 any L<DateTime> objects you pass to L<search|DBIx::Class::ResultSet/search>
17751775 conditions. Any L<Storage|DBIx::Class::Storage> object attached to your
1776 L<Schema|DBIx::Class::Schema> provides a correct C<DateTime> formatter, so
1776 L<Schema|DBIx::Class::Schema> provides a correct L<DateTime> formatter, so
17771777 all you have to do is:
17781778
17791779 my $dtf = $schema->storage->datetime_parser;
17921792 C<DateTime> object, which almost never matches the RDBMS expectations.
17931793
17941794 This kludge is necessary only for conditions passed to
1795 L<DBIx::Class::ResultSet/search>, whereas
1796 L<create|DBIx::Class::ResultSet/create>,
1797 L<find|DBIx::Class::ResultSet/find>,
1798 L<DBIx::Class::Row/update> (but not L<DBIx::Class::ResultSet/update>) are all
1795 L<search|DBIx::Class::ResultSet/search> and L<DBIx::Class::ResultSet/find>,
1796 whereas L<create|DBIx::Class::ResultSet/create> and
1797 L<DBIx::Class::Row/update> (but not L<DBIx::Class::ResultSet/update>) are
17991798 L<DBIx::Class::InflateColumn>-aware and will do the right thing when supplied
1800 an inflated C<DateTime> object.
1799 an inflated L<DateTime> object.
18011800
18021801 =head2 Using Unicode
18031802
77 testing a very basic CD database using SQLite, with DBIx::Class::Schema
88 as the database frontend.
99
10 The database consists of the following:
10 The database structure is based on the following rules:
11
12 An artist can have many cds, and each cd belongs to just one artist.
13 A cd can have many tracks, and each track belongs to just one cd.
14
15 The database is implemented with the following:
1116
1217 table 'artist' with columns: artistid, name
13 table 'cd' with columns: cdid, artist, title, year
14 table 'track' with columns: trackid, cd, title
18 table 'cd' with columns: cdid, artistid, title, year
19 table 'track' with columns: trackid, cdid, title
1520
16
17 And these rules exists:
18
19 one artist can have many cds
20 one cd belongs to one artist
21 one cd can have many tracks
22 one track belongs to one cd
23
21 Each of the table's first columns is the primary key; any subsequent
22 keys are foreign keys.
2423
2524 =head2 Installation
2625
27 Install DBIx::Class via CPAN should be sufficient.
26 You'll need to install DBIx::Class via CPAN, and you'll also need to
27 install sqlite3 (not sqlite) if it's not already intalled.
2828
29 =head3 Create the database/tables
29 =head3 The database/tables/data
3030
31 First make and change the directory:
31 Your distribution already comes with a pre-filled SQLite database
32 F<examples/Schema/db/example.db>. You can see it by e.g.
3233
33 mkdir app
34 cd app
35 mkdir db
36 cd db
34 cpanm --look DBIx::Class
3735
38 This example uses SQLite which is a dependency of DBIx::Class, so you
39 shouldn't have to install extra software.
36 If for some reason the file is unreadable on your system, you can
37 recreate it as follows:
4038
41 Save the following into a example.sql in the directory db
39 cp -a <unpacked-DBIC-tarball>/examples/Schema dbicapp
40 cd dbicapp
41 rm db/example.db
42 sqlite3 db/example.db < db/example.sql
43 perl insertdb.pl
4244
43 CREATE TABLE artist (
44 artistid INTEGER PRIMARY KEY,
45 name TEXT NOT NULL
46 );
45 =head3 Testing the database
4746
48 CREATE TABLE cd (
49 cdid INTEGER PRIMARY KEY,
50 artist INTEGER NOT NULL REFERENCES artist(artistid),
51 title TEXT NOT NULL
52 );
47 Enter the example Schema directory
5348
54 CREATE TABLE track (
55 trackid INTEGER PRIMARY KEY,
56 cd INTEGER NOT NULL REFERENCES cd(cdid),
57 title TEXT NOT NULL
58 );
49 cd <unpacked-DBIC-tarball>/examples/Schema
5950
60 and create the SQLite database file:
51 Run the script testdb.pl, which will test that the database has
52 successfully been filled.
6153
62 sqlite3 example.db < example.sql
54 When this script is run, it should output the following:
6355
64 =head3 Set up DBIx::Class::Schema
56 get_tracks_by_cd(Bad):
57 Leave Me Alone
58 Smooth Criminal
59 Dirty Diana
6560
66 Change directory back from db to the directory app:
61 get_tracks_by_artist(Michael Jackson):
62 Billie Jean (from the CD 'Thriller')
63 Beat It (from the CD 'Thriller')
64 Leave Me Alone (from the CD 'Bad')
65 Smooth Criminal (from the CD 'Bad')
66 Dirty Diana (from the CD 'Bad')
6767
68 cd ../
68 get_cd_by_track(Stan):
69 The Marshall Mathers LP has the track 'Stan'.
6970
70 Now create some more directories:
71 get_cds_by_artist(Michael Jackson):
72 Thriller
73 Bad
7174
72 mkdir MyApp
73 mkdir MyApp/Schema
74 mkdir MyApp/Schema/Result
75 mkdir MyApp/Schema/ResultSet
75 get_artist_by_track(Dirty Diana):
76 Michael Jackson recorded the track 'Dirty Diana'.
7677
77 Then, create the following DBIx::Class::Schema classes:
78
79 MyApp/Schema.pm:
80
81 package MyApp::Schema;
82 use base qw/DBIx::Class::Schema/;
83 __PACKAGE__->load_namespaces;
84
85 1;
78 get_artist_by_cd(The Marshall Mathers LP):
79 Eminem recorded the CD 'The Marshall Mathers LP'.
8680
8781
88 MyApp/Schema/Result/Artist.pm:
82 =head3 Discussion about the results
8983
90 package MyApp::Schema::Result::Artist;
91 use base qw/DBIx::Class::Core/;
92 __PACKAGE__->table('artist');
93 __PACKAGE__->add_columns(qw/ artistid name /);
94 __PACKAGE__->set_primary_key('artistid');
95 __PACKAGE__->has_many('cds' => 'MyApp::Schema::Result::Cd');
84 The data model defined in this example has an artist with multiple CDs,
85 and a CD with multiple tracks; thus, it's simple to traverse from a
86 track back to a CD, and from there back to an artist. This is
87 demonstrated in the get_tracks_by_artist routine, where we easily walk
88 from the individual track back to the title of the CD that the track
89 came from ($track->cd->title).
9690
97 1;
98
99
100 MyApp/Schema/Result/Cd.pm:
101
102 package MyApp::Schema::Result::Cd;
103 use base qw/DBIx::Class::Core/;
104 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
105 __PACKAGE__->table('cd');
106 __PACKAGE__->add_columns(qw/ cdid artist title year/);
107 __PACKAGE__->set_primary_key('cdid');
108 __PACKAGE__->belongs_to('artist' => 'MyApp::Schema::Result::Artist');
109 __PACKAGE__->has_many('tracks' => 'MyApp::Schema::Result::Track');
110
111 1;
112
113
114 MyApp/Schema/Result/Track.pm:
115
116 package MyApp::Schema::Result::Track;
117 use base qw/DBIx::Class::Core/;
118 __PACKAGE__->table('track');
119 __PACKAGE__->add_columns(qw/ trackid cd title /);
120 __PACKAGE__->set_primary_key('trackid');
121 __PACKAGE__->belongs_to('cd' => 'MyApp::Schema::Result::Cd');
122
123 1;
124
125
126 =head3 Write a script to insert some records
127
128 insertdb.pl
129
130 #!/usr/bin/perl
131
132 use strict;
133 use warnings;
134
135 use MyApp::Schema;
136
137 my $schema = MyApp::Schema->connect('dbi:SQLite:db/example.db');
138
139 my @artists = (['Michael Jackson'], ['Eminem']);
140 $schema->populate('Artist', [
141 [qw/name/],
142 @artists,
143 ]);
144
145 my %albums = (
146 'Thriller' => 'Michael Jackson',
147 'Bad' => 'Michael Jackson',
148 'The Marshall Mathers LP' => 'Eminem',
149 );
150
151 my @cds;
152 foreach my $lp (keys %albums) {
153 my $artist = $schema->resultset('Artist')->find({
154 name => $albums{$lp}
155 });
156 push @cds, [$lp, $artist->id];
157 }
158
159 $schema->populate('Cd', [
160 [qw/title artist/],
161 @cds,
162 ]);
163
164
165 my %tracks = (
166 'Beat It' => 'Thriller',
167 'Billie Jean' => 'Thriller',
168 'Dirty Diana' => 'Bad',
169 'Smooth Criminal' => 'Bad',
170 'Leave Me Alone' => 'Bad',
171 'Stan' => 'The Marshall Mathers LP',
172 'The Way I Am' => 'The Marshall Mathers LP',
173 );
174
175 my @tracks;
176 foreach my $track (keys %tracks) {
177 my $cdname = $schema->resultset('Cd')->find({
178 title => $tracks{$track},
179 });
180 push @tracks, [$cdname->id, $track];
181 }
182
183 $schema->populate('Track',[
184 [qw/cd title/],
185 @tracks,
186 ]);
187
188 =head3 Create and run the test scripts
189
190 testdb.pl:
191
192 #!/usr/bin/perl
193
194 use strict;
195 use warnings;
196
197 use MyApp::Schema;
198
199 my $schema = MyApp::Schema->connect('dbi:SQLite:db/example.db');
200 # for other DSNs, e.g. MySQL, see the perldoc for the relevant dbd
201 # driver, e.g perldoc L<DBD::mysql>.
202
203 get_tracks_by_cd('Bad');
204 get_tracks_by_artist('Michael Jackson');
205
206 get_cd_by_track('Stan');
207 get_cds_by_artist('Michael Jackson');
208
209 get_artist_by_track('Dirty Diana');
210 get_artist_by_cd('The Marshall Mathers LP');
211
212
213 sub get_tracks_by_cd {
214 my $cdtitle = shift;
215 print "get_tracks_by_cd($cdtitle):\n";
216 my $rs = $schema->resultset('Track')->search(
217 {
218 'cd.title' => $cdtitle
219 },
220 {
221 join => [qw/ cd /],
222 }
223 );
224 while (my $track = $rs->next) {
225 print $track->title . "\n";
226 }
227 print "\n";
228 }
229
230 sub get_tracks_by_artist {
231 my $artistname = shift;
232 print "get_tracks_by_artist($artistname):\n";
233 my $rs = $schema->resultset('Track')->search(
234 {
235 'artist.name' => $artistname
236 },
237 {
238 join => {
239 'cd' => 'artist'
240 },
241 }
242 );
243 while (my $track = $rs->next) {
244 print $track->title . "\n";
245 }
246 print "\n";
247 }
248
249
250 sub get_cd_by_track {
251 my $tracktitle = shift;
252 print "get_cd_by_track($tracktitle):\n";
253 my $rs = $schema->resultset('Cd')->search(
254 {
255 'tracks.title' => $tracktitle
256 },
257 {
258 join => [qw/ tracks /],
259 }
260 );
261 my $cd = $rs->first;
262 print $cd->title . "\n\n";
263 }
264
265 sub get_cds_by_artist {
266 my $artistname = shift;
267 print "get_cds_by_artist($artistname):\n";
268 my $rs = $schema->resultset('Cd')->search(
269 {
270 'artist.name' => $artistname
271 },
272 {
273 join => [qw/ artist /],
274 }
275 );
276 while (my $cd = $rs->next) {
277 print $cd->title . "\n";
278 }
279 print "\n";
280 }
281
282
283
284 sub get_artist_by_track {
285 my $tracktitle = shift;
286 print "get_artist_by_track($tracktitle):\n";
287 my $rs = $schema->resultset('Artist')->search(
288 {
289 'tracks.title' => $tracktitle
290 },
291 {
292 join => {
293 'cds' => 'tracks'
294 }
295 }
296 );
297 my $artist = $rs->first;
298 print $artist->name . "\n\n";
299 }
300
301 sub get_artist_by_cd {
302 my $cdtitle = shift;
303 print "get_artist_by_cd($cdtitle):\n";
304 my $rs = $schema->resultset('Artist')->search(
305 {
306 'cds.title' => $cdtitle
307 },
308 {
309 join => [qw/ cds /],
310 }
311 );
312 my $artist = $rs->first;
313 print $artist->name . "\n\n";
314 }
315
316
317
318 It should output:
319
320 get_tracks_by_cd(Bad):
321 Dirty Diana
322 Smooth Criminal
323 Leave Me Alone
324
325 get_tracks_by_artist(Michael Jackson):
326 Beat it
327 Billie Jean
328 Dirty Diana
329 Smooth Criminal
330 Leave Me Alone
331
332 get_cd_by_track(Stan):
333 The Marshall Mathers LP
334
335 get_cds_by_artist(Michael Jackson):
336 Thriller
337 Bad
338
339 get_artist_by_track(Dirty Diana):
340 Michael Jackson
341
342 get_artist_by_cd(The Marshall Mathers LP):
343 Eminem
344
345 =head1 Notes
346
347 A reference implementation of the database and scripts in this example
348 are available in the main distribution for DBIx::Class under the
349 directory F<examples/Schema>.
350
351 With these scripts we're relying on @INC looking in the current
352 working directory. You may want to add the MyApp namespaces to
353 @INC in a different way when it comes to deployment.
354
355 The F<testdb.pl> script is an excellent start for testing your database
356 model.
91 Note also that in the get_tracks_by_cd and get_tracks_by_artist
92 routines, the result set is called multiple times with the 'next'
93 iterator. In contrast, get_cd_by_track uses the 'first' result set
94 method, since only one CD is expected to have a specific track.
35795
35896 This example uses L<DBIx::Class::Schema/load_namespaces> to load in the
35997 appropriate L<Result|DBIx::Class::Manual::ResultClass> classes from the
36098 C<MyApp::Schema::Result> namespace, and any required
36199 L<ResultSet|DBIx::Class::ResultSet> classes from the
362 C<MyApp::Schema::ResultSet> namespace (although we created the directory
363 in the directions above we did not add, or need to add, any resultset
364 classes).
100 C<MyApp::Schema::ResultSet> namespace (although we did not add, nor needed
101 any such classes in this example).
365102
366103 =head1 FURTHER QUESTIONS?
367104
8181
8282 __PACKAGE__->table('mydb.mytablename');
8383
84 And load all the Result classes for both / all databases using one
85 L<DBIx::Class::Schema/load_namespaces> call.
84 And load all the Result classes for both / all databases by calling
85 L<DBIx::Class::Schema/load_namespaces>.
8686
8787 =item .. use DBIx::Class across PostgreSQL/DB2/Oracle schemas?
8888
261261 ->on_connect_do("ALTER SESSION SET NLS_SORT = 'BINARY_CI'");
262262 ->on_connect_do("ALTER SESSION SET NLS_SORT = 'GERMAN_CI'");
263263
264 =item .. format a DateTime object for searching?
265
266 L<search|DBIx::Class::ResultSet/search> and L<find|DBIx::Class::ResultSet/find>
267 do not take L<DBIx::Class::InflateColumn> into account, and so your L<DateTime>
268 object will not be correctly deflated into a format your RDBMS expects.
269
270 The L<datetime_parser|DBIx::Class::Storage::DBI/datetime_parser> method on your
271 storage object can be used to return the object that would normally do this, so
272 it's easy to do it manually:
273
274 my $dtf = $schema->storage->datetime_parser;
275 my $rs = $schema->resultset('users')->search(
276 {
277 signup_date => {
278 -between => [
279 $dtf->format_datetime($dt_start),
280 $dtf->format_datetime($dt_end),
281 ],
282 }
283 },
284 );
285
286 With in a Result Class method, you can get this from the
287 L<C<result_source>|DBIx::Class::Row/result_source>.
288
289 my $dtf = $self->result_source->storage->datetime_parser;
290
291 This kludge is necessary only for conditions passed to
292 L<search|DBIx::Class::ResultSet/search> and L<DBIx::Class::ResultSet/find>,
293 whereas L<create|DBIx::Class::ResultSet/create> and L<DBIx::Class::Row/update>
294 (but not L<DBIx::Class::ResultSet/update>) are
295 L<DBIx::Class::InflateColumn>-aware and will do the right thing when supplied
296 an inflated L<DateTime> object.
264297
265298 =back
266299
1717
1818 ...
1919
20 configure_requires 'DBIx::Class' => '0.082810';
20 configure_requires 'DBIx::Class' => '0.082820';
2121
2222 require DBIx::Class::Optional::Dependencies;
2323
33223322 });
33233323 }
33243324
3325 The alias of L<newly created resultsets|/search> can be altered by the
3326 L<alias attribute|/alias>.
3327
33253328 =cut
33263329
33273330 sub current_source_alias {
38153818
38163819 if (ref $b eq 'HASH') {
38173820 my ($b_key) = keys %{$b};
3821 $b_key = '' if ! defined $b_key;
38183822 if (ref $a eq 'HASH') {
38193823 my ($a_key) = keys %{$a};
3824 $a_key = '' if ! defined $a_key;
38203825 if ($a_key eq $b_key) {
38213826 return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
38223827 } else {
40834088 as => [qw(some_column dbic_slot)]
40844089
40854090 If you want to individually retrieve related columns (in essence perform
4086 manual prefetch) you have to make sure to specify the correct inflation slot
4091 manual L</prefetch>) you have to make sure to specify the correct inflation slot
40874092 chain such that it matches existing relationships:
40884093
40894094 my $rs = $schema->resultset('Artist')->search({}, {
40904095 # required to tell DBIC to collapse has_many relationships
40914096 collapse => 1,
4092 join => { cds => 'tracks'},
4097 join => { cds => 'tracks' },
40934098 '+columns' => {
40944099 'cds.cdid' => 'cds.cdid',
40954100 'cds.tracks.title' => 'tracks.title',
209209 The length of your column, if it is a column type that can have a size
210210 restriction. This is currently only used to create tables from your
211211 schema, see L<DBIx::Class::Schema/deploy>.
212
213 { size => [ 9, 6 ] }
214
215 For decimal or float values you can specify an ArrayRef in order to
216 control precision, assuming your database's
217 L<SQL::Translator::Producer> supports it.
212218
213219 =item is_nullable
214220
19031909
19041910 $args->{condition} ||= $rel_info->{cond};
19051911
1906 $self->throw_exception( "Argument 'self_result_object' must be an object of class '@{[ $self->result_class ]}'" )
1912 $self->throw_exception( "Argument 'self_result_object' must be an object inheriting from DBIx::Class::Row" )
19071913 if (
19081914 exists $args->{self_result_object}
19091915 and
1910 ( ! defined blessed $args->{self_result_object} or ! $args->{self_result_object}->isa($self->result_class) )
1916 ( ! defined blessed $args->{self_result_object} or ! $args->{self_result_object}->isa('DBIx::Class::Row') )
19111917 )
19121918 ;
19131919
23052311
23062312 my $global_phase_destroy;
23072313 sub DESTROY {
2314 ### NO detected_reinvoked_destructor check
2315 ### This code very much relies on being called multuple times
2316
23082317 return if $global_phase_destroy ||= in_global_destruction;
23092318
23102319 ######
12121212 sub thaw {
12131213 my ($self, $obj) = @_;
12141214 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1215 require Storable;
12161215 return Storable::thaw($obj);
12171216 }
12181217
12241223 =cut
12251224
12261225 sub freeze {
1227 require Storable;
12281226 return Storable::nfreeze($_[1]);
12291227 }
12301228
12471245 sub dclone {
12481246 my ($self, $obj) = @_;
12491247 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1250 require Storable;
12511248 return Storable::dclone($obj);
12521249 }
12531250
13871384
13881385 my $global_phase_destroy;
13891386 sub DESTROY {
1387 ### NO detected_reinvoked_destructor check
1388 ### This code very much relies on being called multuple times
1389
13901390 return if $global_phase_destroy ||= in_global_destruction;
13911391
13921392 my $self = shift;
99 use DBIx::Class::_Util qw(is_exception qsub);
1010 use Scalar::Util qw(weaken blessed reftype);
1111 use Try::Tiny;
12
13 # DO NOT edit away without talking to riba first, he will just put it back
14 # BEGIN pre-Moo2 import block
15 BEGIN {
16 my $initial_fatal_bits = (${^WARNING_BITS}||'') & $warnings::DeadBits{all};
17
18 local $ENV{PERL_STRICTURES_EXTRA} = 0;
19 # load all of these now, so that lazy-loading does not escape
20 # the current PERL_STRICTURES_EXTRA setting
21 require Sub::Quote;
22 require Sub::Defer;
23 require Moo;
24 require Moo::Object;
25 require Method::Generate::Accessor;
26 require Method::Generate::Constructor;
27
28 Moo->import;
29 ${^WARNING_BITS} &= ( $initial_fatal_bits | ~ $warnings::DeadBits{all} );
30 }
31 # END pre-Moo2 import block
32
12 use Moo;
3313 use namespace::clean;
3414
3515 =head1 NAME
77 use Try::Tiny;
88 use Scalar::Util qw(refaddr weaken);
99 use List::Util 'shuffle';
10 use DBIx::Class::_Util 'detected_reinvoked_destructor';
1011 use namespace::clean;
1112
1213 __PACKAGE__->mk_group_accessors('simple' =>
232233
233234
234235 sub DESTROY {
236 return if &detected_reinvoked_destructor;
237
235238 $_[0]->__finish_sth if $_[0]->{sth};
236239 }
237240
418418
419419 my $attrs = $self->next::method($ident, $bind);
420420
421 for my $i (0 .. $#$attrs) {
422 if (keys %{$attrs->[$i]||{}} and my $col = $bind->[$i][0]{dbic_colname}) {
423 $attrs->[$i]{ora_field} = $col;
424 }
425 }
421 # Push the column name into all bind attrs, make sure to *NOT* write into
422 # the existing $attrs->[$idx]{..} hashref, as it is cached by the call to
423 # next::method above.
424 $attrs->[$_]
425 and
426 keys %{ $attrs->[$_] }
427 and
428 $bind->[$_][0]{dbic_colname}
429 and
430 $attrs->[$_] = { %{$attrs->[$_]}, ora_field => $bind->[$_][0]{dbic_colname} }
431 for 0 .. $#$attrs;
426432
427433 $attrs;
428434 }
306306 _parse_connect_do
307307 savepoints
308308 _sql_maker_opts
309 _use_multicolumn_in
309310 _conn_pid
310311 _dbh_autocommit
311312 _native_data_type
362363 # the capability framework
363364 # not sure if CMOP->initialize does evil things to DBIC::S::DBI, fix if a problem
364365 grep
365 { $_ =~ /^ _ (?: use | supports | determine_supports ) _ /x }
366 { $_ =~ /^ _ (?: use | supports | determine_supports ) _ /x and $_ ne '_use_multicolumn_in' }
366367 ( Class::MOP::Class->initialize('DBIx::Class::Storage::DBI')->get_all_method_names )
367368 )],
368369 };
6060
6161 Even if you upgrade DBIx::Class (which works around the bug starting from
6262 version 0.08210) you may still have corrupted/incorrect data in your database.
63 DBIx::Class will currently detect when this condition (more than one
64 stringifiable object in one CRUD call) is encountered and will issue a warning
65 pointing to this section. This warning will be removed 2 years from now,
66 around April 2015, You can disable it after you've audited your data by
67 setting the C<DBIC_RT79576_NOWARN> environment variable. Note - the warning
68 is emitted only once per callsite per process and only when the condition in
69 question is encountered. Thus it is very unlikely that your logsystem will be
70 flooded as a result of this.
63 DBIx::Class warned about this condition for several years, hoping to give
64 anyone affected sufficient notice of the potential issues. The warning was
65 removed in version 0.082900.
7166
7267 =back
7368
316311 = modver_gt_or_eq('DBD::SQLite', '1.37') ? 1 : 0;
317312 }
318313
319 # an attempt to detect former effects of RT#79576, bug itself present between
320 # 0.08191 and 0.08209 inclusive (fixed in 0.08210 and higher)
321 my $stringifiable = 0;
322
323314 for my $i (0.. $#$bindattrs) {
324
325 $stringifiable++ if ( length ref $bind->[$i][1] and is_plain_value($bind->[$i][1]) );
326
327315 if (
328316 defined $bindattrs->[$i]
329317 and
366354 }
367355 }
368356
369 carp_unique(
370 'POSSIBLE *PAST* DATA CORRUPTION detected - see '
371 . 'DBIx::Class::Storage::DBI::SQLite/RT79576 or '
372 . 'http://v.gd/DBIC_SQLite_RT79576 for further details or set '
373 . '$ENV{DBIC_RT79576_NOWARN} to disable this warning. Trigger '
374 . 'condition encountered'
375 ) if (!$ENV{DBIC_RT79576_NOWARN} and $stringifiable > 1);
376
377357 return $bindattrs;
378358 }
379359
1212 use Context::Preserve 'preserve_context';
1313 use Try::Tiny;
1414 use SQL::Abstract qw(is_plain_value is_literal_value);
15 use DBIx::Class::_Util qw(quote_sub perlstring serialize);
15 use DBIx::Class::_Util qw(quote_sub perlstring serialize detected_reinvoked_destructor);
1616 use namespace::clean;
1717
1818 # default cursor class, overridable in connect_info attributes
252252 }
253253
254254 sub DESTROY {
255 return if &detected_reinvoked_destructor;
256
255257 $_[0]->_verify_pid unless DBIx::Class::_ENV_::BROKEN_FORK;
256258 # some databases spew warnings on implicit disconnect
257259 local $SIG{__WARN__} = sub {};
16661668 ) {
16671669 carp_unique 'DateTime objects passed to search() are not supported '
16681670 . 'properly (InflateColumn::DateTime formats and settings are not '
1669 . 'respected.) See "Formatting DateTime objects in queries" in '
1670 . 'DBIx::Class::Manual::Cookbook. To disable this warning for good '
1671 . 'respected.) See ".. format a DateTime object for searching?" in '
1672 . 'DBIx::Class::Manual::FAQ. To disable this warning for good '
16711673 . 'set $ENV{DBIC_DT_SEARCH_OK} to true'
16721674 }
16731675
44
55 use DBIx::Class::_Util qw(sigwarn_silencer qsub);
66 use IO::Handle ();
7
8 # DO NOT edit away without talking to riba first, he will just put it back
9 # BEGIN pre-Moo2 import block
10 BEGIN {
11 my $initial_fatal_bits = (${^WARNING_BITS}||'') & $warnings::DeadBits{all};
12
13 local $ENV{PERL_STRICTURES_EXTRA} = 0;
14 # load all of these now, so that lazy-loading does not escape
15 # the current PERL_STRICTURES_EXTRA setting
16 require Sub::Quote;
17 require Sub::Defer;
18 require Moo;
19 require Moo::Object;
20 require Method::Generate::Accessor;
21 require Method::Generate::Constructor;
22
23 Moo->import;
24 ${^WARNING_BITS} &= ( $initial_fatal_bits | ~ $warnings::DeadBits{all} );
25 }
26 # END pre-Moo2 import block
27
7 use Moo;
288 extends 'DBIx::Class';
299 use namespace::clean;
3010
22 use strict;
33 use warnings;
44 use Try::Tiny;
5 use Scalar::Util qw/weaken blessed refaddr/;
5 use Scalar::Util qw(weaken blessed refaddr);
66 use DBIx::Class;
7 use DBIx::Class::_Util 'is_exception';
7 use DBIx::Class::_Util qw(is_exception detected_reinvoked_destructor);
88 use DBIx::Class::Carp;
99 use namespace::clean;
1010
4949 }
5050
5151 sub DESTROY {
52 return if &detected_reinvoked_destructor;
53
5254 my $self = shift;
5355
5456 return if $self->{inactivated};
5454 # Carp::Skip to the rescue soon
5555 use DBIx::Class::Carp '^DBIx::Class|^DBICTest';
5656
57 use B ();
5758 use Carp 'croak';
58 use Scalar::Util qw(weaken blessed reftype);
59 use Storable 'nfreeze';
60 use Scalar::Util qw(weaken blessed reftype refaddr);
5961 use List::Util qw(first);
60
61 # DO NOT edit away without talking to riba first, he will just put it back
62 # BEGIN pre-Moo2 import block
63 BEGIN {
64 my $initial_fatal_bits = (${^WARNING_BITS}||'') & $warnings::DeadBits{all};
65
66 local $ENV{PERL_STRICTURES_EXTRA} = 0;
67 # load all of these now, so that lazy-loading does not escape
68 # the current PERL_STRICTURES_EXTRA setting
69 require Sub::Quote;
70 require Sub::Defer;
71
72 Sub::Quote->import('quote_sub');
73 ${^WARNING_BITS} &= ( $initial_fatal_bits | ~ $warnings::DeadBits{all} );
74 }
75 sub qsub ($) { goto &quote_sub } # no point depping on new Moo just for this
76 # END pre-Moo2 import block
62 use Sub::Quote qw(qsub quote_sub);
7763
7864 use base 'Exporter';
7965 our @EXPORT_OK = qw(
80 sigwarn_silencer modver_gt_or_eq
66 sigwarn_silencer modver_gt_or_eq modver_gt_or_eq_and_lt
8167 fail_on_internal_wantarray fail_on_internal_call
82 refdesc refcount hrefaddr is_exception
68 refdesc refcount hrefaddr is_exception detected_reinvoked_destructor
8369 quote_sub qsub perlstring serialize
8470 UNRESOLVABLE_CONDITION
8571 );
9884
9985 sub perlstring ($) { q{"}. quotemeta( shift ). q{"} };
10086
101 sub hrefaddr ($) { sprintf '0x%x', &Scalar::Util::refaddr||0 }
87 sub hrefaddr ($) { sprintf '0x%x', &refaddr||0 }
10288
10389 sub refdesc ($) {
10490 croak "Expecting a reference" if ! length ref $_[0];
10894 sprintf '%s%s(0x%x)',
10995 ( defined( $_[1] = blessed $_[0]) ? "$_[1]=" : '' ),
11096 reftype $_[0],
111 Scalar::Util::refaddr($_[0]),
97 refaddr($_[0]),
11298 ;
11399 }
114100
115101 sub refcount ($) {
116102 croak "Expecting a reference" if ! length ref $_[0];
117103
118 require B;
119104 # No tempvars - must operate on $_[0], otherwise the pad
120105 # will count as an extra ref
121106 B::svref_2object($_[0])->REFCNT;
122107 }
123108
124109 sub serialize ($) {
125 require Storable;
126110 local $Storable::canonical = 1;
127 Storable::nfreeze($_[0]);
111 nfreeze($_[0]);
128112 }
129113
130114 sub is_exception ($) {
179163 return $not_blank;
180164 }
181165
166 {
167 my $destruction_registry = {};
168
169 sub CLONE {
170 $destruction_registry = { map
171 { defined $_ ? ( refaddr($_) => $_ ) : () }
172 values %$destruction_registry
173 };
174 }
175
176 # This is almost invariably invoked from within DESTROY
177 # throwing exceptions won't work
178 sub detected_reinvoked_destructor {
179
180 # quick "garbage collection" pass - prevents the registry
181 # from slowly growing with a bunch of undef-valued keys
182 defined $destruction_registry->{$_} or delete $destruction_registry->{$_}
183 for keys %$destruction_registry;
184
185 if (! length ref $_[0]) {
186 printf STDERR '%s() expects a blessed reference %s',
187 (caller(0))[3],
188 Carp::longmess,
189 ;
190 return undef; # don't know wtf to do
191 }
192 elsif (! defined $destruction_registry->{ my $addr = refaddr($_[0]) } ) {
193 weaken( $destruction_registry->{$addr} = $_[0] );
194 return 0;
195 }
196 else {
197 carp_unique ( sprintf (
198 'Preventing *MULTIPLE* DESTROY() invocations on %s - an *EXTREMELY '
199 . 'DANGEROUS* condition which is *ALMOST CERTAINLY GLOBAL* within your '
200 . 'application, affecting *ALL* classes without active protection against '
201 . 'this. Diagnose and fix the root cause ASAP!!!%s',
202 refdesc $_[0],
203 ( ( $INC{'Devel/StackTrace.pm'} and ! do { local $@; eval { Devel::StackTrace->VERSION(2) } } )
204 ? " (likely culprit Devel::StackTrace\@@{[ Devel::StackTrace->VERSION ]} found in %INC, http://is.gd/D_ST_refcap)"
205 : ''
206 )
207 ));
208
209 return 1;
210 }
211 }
212 }
213
182214 sub modver_gt_or_eq ($$) {
183215 my ($mod, $ver) = @_;
184216
196228
197229 local $@;
198230 eval { $mod->VERSION($ver) } ? 1 : 0;
231 }
232
233 sub modver_gt_or_eq_and_lt ($$$) {
234 my ($mod, $v_ge, $v_lt) = @_;
235
236 croak "Nonsensical maximum version supplied"
237 if ! defined $v_lt or $v_lt =~ /[^0-9\.\_]/;
238
239 return (
240 modver_gt_or_eq($mod, $v_ge)
241 and
242 ! modver_gt_or_eq($mod, $v_lt)
243 ) ? 1 : 0;
199244 }
200245
201246 {
1010 # $VERSION declaration must stay up here, ahead of any other package
1111 # declarations, as to not confuse various modules attempting to determine
1212 # this ones version, whether that be s.c.o. or Module::Metadata, etc
13 $VERSION = '0.082810';
13 $VERSION = '0.082820';
1414
1515 $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
1616
2525
2626 __PACKAGE__->mk_group_accessors(inherited => '_skip_namespace_frames');
2727 __PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve');
28
29 # FIXME - this is not really necessary, and is in
30 # fact going to slow things down a bit
31 # However it is the right thing to do in order to get
32 # various install bases to highlight their brokenness
33 # Remove at some unknown point in the future
34 sub DESTROY { &DBIx::Class::_Util::detected_reinvoked_destructor }
2835
2936 sub mk_classdata {
3037 shift->mk_classaccessor(@_);
278285 =item * Travis-CI log: L<https://travis-ci.org/dbsrgits/dbix-class/builds>
279286
280287 =for html
281 &#x21AA; Stable branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
288 &#x21AA; Main dev branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=current/blead"></img>
289 &#x21AA; Release branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=current/for_cpan_index"></img>
282290
283291 =back
284292
210210 =item * Travis-CI log: L<https://travis-ci.org/dbsrgits/dbix-class/builds>
211211
212212 =for html
213 &#x21AA; Stable branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
213 &#x21AA; Main dev branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=current/blead"></img>
214 &#x21AA; Release branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=current/for_cpan_index"></img>
214215
215216 =back
216217
224225 the seemingly most insignificant questions and suggestions have been shown
225226 to catalyze monumental improvements in consistency, accuracy and performance.
226227
227 List of the awesome contributors who made DBIC v0.082810 possible
228 List of the awesome contributors who made DBIC v0.082820 possible
228229
229230 =encoding utf8
230231
231232 =over
232233
233 B<abraxxa>:Alexander Hartmaier <abraxxa@cpan.org>
234
235 B<acca>:Alexander Kuznetsov <acca@cpan.org>
236
237 B<aherzog>:Adam Herzog <adam@herzogdesigns.com>
234 B<abraxxa>: Alexander Hartmaier <abraxxa@cpan.org>
235
236 B<acca>: Alexander Kuznetsov <acca@cpan.org>
237
238 B<aherzog>: Adam Herzog <adam@herzogdesigns.com>
238239
239240 Alexander Keusch <cpan@keusch.at>
240241
241 B<alexrj>:Alessandro Ranellucci <aar@cpan.org>
242
243 B<alnewkirk>:Al Newkirk <github@alnewkirk.com>
244
245 B<amiri>:Amiri Barksdale <amiribarksdale@gmail.com>
246
247 B<amoore>:Andrew Moore <amoore@cpan.org>
242 B<alexrj>: Alessandro Ranellucci <aar@cpan.org>
243
244 B<alnewkirk>: Al Newkirk <github@alnewkirk.com>
245
246 B<Altreus>: Alastair McGowan-Douglas <alastair.mcgowan@opusvl.com>
247
248 B<amiri>: Amiri Barksdale <amiribarksdale@gmail.com>
249
250 B<amoore>: Andrew Moore <amoore@cpan.org>
248251
249252 Andrew Mehta <Andrew@unitedgames.co.uk>
250253
251 B<andrewalker>:Andre Walker <andre@andrewalker.net>
252
253 B<andyg>:Andy Grundman <andy@hybridized.org>
254
255 B<ank>:Andres Kievsky <ank@ank.com.ar>
256
257 B<arc>:Aaron Crane <arc@cpan.org>
258
259 B<arcanez>:Justin Hunter <justin.d.hunter@gmail.com>
260
261 B<ash>:Ash Berlin <ash@cpan.org>
262
263 B<bert>:Norbert Csongrádi <bert@cpan.org>
264
265 B<bfwg>:Colin Newell <colin.newell@gmail.com>
266
267 B<blblack>:Brandon L. Black <blblack@gmail.com>
268
269 B<bluefeet>:Aran Deltac <bluefeet@cpan.org>
270
271 B<boghead>:Bryan Beeley <cpan@beeley.org>
272
273 B<bphillips>:Brian Phillips <bphillips@cpan.org>
274
275 B<brd>:Brad Davis <brd@FreeBSD.org>
254 B<andrewalker>: Andre Walker <andre@andrewalker.net>
255
256 B<andyg>: Andy Grundman <andy@hybridized.org>
257
258 B<ank>: Andres Kievsky <ank@ank.com.ar>
259
260 B<arc>: Aaron Crane <arc@cpan.org>
261
262 B<arcanez>: Justin Hunter <justin.d.hunter@gmail.com>
263
264 B<ash>: Ash Berlin <ash@cpan.org>
265
266 B<bert>: Norbert Csongrádi <bert@cpan.org>
267
268 B<bfwg>: Colin Newell <colin.newell@gmail.com>
269
270 B<blblack>: Brandon L. Black <blblack@gmail.com>
271
272 B<bluefeet>: Aran Deltac <bluefeet@cpan.org>
273
274 B<boghead>: Bryan Beeley <cpan@beeley.org>
275
276 B<bphillips>: Brian Phillips <bphillips@cpan.org>
277
278 B<brd>: Brad Davis <brd@FreeBSD.org>
276279
277280 Brian Kirkbride <brian.kirkbride@deeperbydesign.com>
278281
279 B<bricas>:Brian Cassidy <bricas@cpan.org>
280
281 B<brunov>:Bruno Vecchi <vecchi.b@gmail.com>
282
283 B<caelum>:Rafael Kitover <rkitover@cpan.org>
284
285 B<caldrin>:Maik Hentsche <maik.hentsche@amd.com>
286
287 B<castaway>:Jess Robinson <castaway@desert-island.me.uk>
288
289 B<chorny>:Alexandr Ciornii <alexchorny@gmail.com>
290
291 B<claco>:Christopher H. Laco <claco@cpan.org>
292
293 B<clkao>:CL Kao <clkao@clkao.org>
282 B<bricas>: Brian Cassidy <bricas@cpan.org>
283
284 B<brunov>: Bruno Vecchi <vecchi.b@gmail.com>
285
286 B<caelum>: Rafael Kitover <rkitover@cpan.org>
287
288 B<caldrin>: Maik Hentsche <maik.hentsche@amd.com>
289
290 B<castaway>: Jess Robinson <castaway@desert-island.me.uk>
291
292 B<chorny>: Alexandr Ciornii <alexchorny@gmail.com>
293
294 B<cj>: C.J. Adams-Collier <cjcollier@cpan.org>
295
296 B<claco>: Christopher H. Laco <claco@cpan.org>
297
298 B<clkao>: CL Kao <clkao@clkao.org>
294299
295300 Ctrl-O L<http://ctrlo.com/|http://ctrlo.com/>
296301
297 B<da5id>:David Jack Olrik <david@olrik.dk>
298
299 B<dams>:Damien Krotkine <dams@cpan.org>
300
301 B<dandv>:Dan Dascalescu <ddascalescu+github@gmail.com>
302
303 B<dariusj>:Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
304
305 B<davewood>:David Schmidt <mail@davidschmidt.at>
306
307 B<daxim>:Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
308
309 B<dduncan>:Darren Duncan <darren@darrenduncan.net>
310
311 B<debolaz>:Anders Nor Berle <berle@cpan.org>
312
313 B<dew>:Dan Thomas <dan@godders.org>
314
315 B<dim0xff>:Dmitry Latin <dim0xff@gmail.com>
316
317 B<dkubb>:Dan Kubb <dan.kubb-cpan@onautopilot.com>
318
319 B<dnm>:Justin Wheeler <jwheeler@datademons.com>
320
321 B<dpetrov>:Dimitar Petrov <mitakaa@gmail.com>
322
323 B<dsteinbrunner>:David Steinbrunner <dsteinbrunner@pobox.com>
324
325 B<duncan_dmg>:Duncan Garland <Duncan.Garland@motortrak.com>
326
327 B<dwc>:Daniel Westermann-Clark <danieltwc@cpan.org>
328
329 B<dyfrgi>:Michael Leuchtenburg <michael@slashhome.org>
330
331 B<edenc>:Eden Cardim <edencardim@gmail.com>
302 B<da5id>: David Jack Olrik <david@olrik.dk>
303
304 B<dams>: Damien Krotkine <dams@cpan.org>
305
306 B<dandv>: Dan Dascalescu <ddascalescu+github@gmail.com>
307
308 B<dariusj>: Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
309
310 B<davewood>: David Schmidt <mail@davidschmidt.at>
311
312 B<daxim>: Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
313
314 B<dduncan>: Darren Duncan <darren@darrenduncan.net>
315
316 B<debolaz>: Anders Nor Berle <berle@cpan.org>
317
318 B<dew>: Dan Thomas <dan@godders.org>
319
320 B<dim0xff>: Dmitry Latin <dim0xff@gmail.com>
321
322 B<dkubb>: Dan Kubb <dan.kubb-cpan@onautopilot.com>
323
324 B<dnm>: Justin Wheeler <jwheeler@datademons.com>
325
326 B<dpetrov>: Dimitar Petrov <mitakaa@gmail.com>
327
328 B<Dr^ZigMan>: Robert Stone <drzigman@drzigman.com>
329
330 B<dsteinbrunner>: David Steinbrunner <dsteinbrunner@pobox.com>
331
332 B<duncan_dmg>: Duncan Garland <Duncan.Garland@motortrak.com>
333
334 B<dwc>: Daniel Westermann-Clark <danieltwc@cpan.org>
335
336 B<dyfrgi>: Michael Leuchtenburg <michael@slashhome.org>
337
338 B<edenc>: Eden Cardim <edencardim@gmail.com>
332339
333340 Eligo L<http://eligo.co.uk/|http://eligo.co.uk/>
334341
335 B<ether>:Karen Etheridge <ether@cpan.org>
336
337 B<evdb>:Edmund von der Burg <evdb@ecclestoad.co.uk>
338
339 B<faxm0dem>:Fabien Wernli <cpan@faxm0dem.org>
340
341 B<felliott>:Fitz Elliott <fitz.elliott@gmail.com>
342
343 B<freetime>:Bill Moseley <moseley@hank.org>
344
345 B<frew>:Arthur Axel "fREW" Schmidt <frioux@gmail.com>
346
347 B<gbjk>:Gareth Kirwan <gbjk@thermeon.com>
348
349 B<Getty>:Torsten Raudssus <torsten@raudss.us>
350
351 B<goraxe>:Gordon Irving <goraxe@cpan.org>
352
353 B<gphat>:Cory G Watson <gphat@cpan.org>
342 B<ether>: Karen Etheridge <ether@cpan.org>
343
344 B<evdb>: Edmund von der Burg <evdb@ecclestoad.co.uk>
345
346 B<faxm0dem>: Fabien Wernli <cpan@faxm0dem.org>
347
348 B<felliott>: Fitz Elliott <fitz.elliott@gmail.com>
349
350 B<freetime>: Bill Moseley <moseley@hank.org>
351
352 B<frew>: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
353
354 B<gbjk>: Gareth Kirwan <gbjk@thermeon.com>
355
356 B<Getty>: Torsten Raudssus <torsten@raudss.us>
357
358 B<goraxe>: Gordon Irving <goraxe@cpan.org>
359
360 B<gphat>: Cory G Watson <gphat@cpan.org>
354361
355362 Grant Street Group L<http://www.grantstreet.com/|http://www.grantstreet.com/>
356363
357 B<groditi>:Guillermo Roditi <groditi@cpan.org>
358
359 B<gshank>:Gerda Shank <gshank@cpan.org>
360
361 B<guacamole>:Fred Steinberg <fred.steinberg@gmail.com>
362
363 B<Haarg>:Graham Knop <haarg@haarg.org>
364
365 B<hobbs>:Andrew Rodland <andrew@cleverdomain.org>
364 B<groditi>: Guillermo Roditi <groditi@cpan.org>
365
366 B<gshank>: Gerda Shank <gshank@cpan.org>
367
368 B<guacamole>: Fred Steinberg <fred.steinberg@gmail.com>
369
370 B<Haarg>: Graham Knop <haarg@haarg.org>
371
372 B<hobbs>: Andrew Rodland <andrew@cleverdomain.org>
366373
367374 Ian Wells <ijw@cack.org.uk>
368375
369 B<idn>:Ian Norton <i.norton@shadowcat.co.uk>
370
371 B<ilmari>:Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
372
373 B<initself>:Mike Baas <mike@initselftech.com>
374
375 B<ironcamel>:Naveed Massjouni <naveedm9@gmail.com>
376
377 B<jasonmay>:Jason May <jason.a.may@gmail.com>
378
379 B<jawnsy>:Jonathan Yu <jawnsy@cpan.org>
380
381 B<jegade>:Jens Gassmann <jens.gassmann@atomix.de>
382
383 B<jeneric>:Eric A. Miller <emiller@cpan.org>
384
385 B<jesper>:Jesper Krogh <jesper@krogh.cc>
376 B<idn>: Ian Norton <i.norton@shadowcat.co.uk>
377
378 B<ilmari>: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
379
380 B<ingy>: Ingy döt Net <ingy@ingy.net>
381
382 B<initself>: Mike Baas <mike@initselftech.com>
383
384 B<ironcamel>: Naveed Massjouni <naveedm9@gmail.com>
385
386 B<jasonmay>: Jason May <jason.a.may@gmail.com>
387
388 B<jawnsy>: Jonathan Yu <jawnsy@cpan.org>
389
390 B<jegade>: Jens Gassmann <jens.gassmann@atomix.de>
391
392 B<jeneric>: Eric A. Miller <emiller@cpan.org>
393
394 B<jesper>: Jesper Krogh <jesper@krogh.cc>
386395
387396 Jesse Sheidlower <jester@panix.com>
388397
389 B<jgoulah>:John Goulah <jgoulah@cpan.org>
390
391 B<jguenther>:Justin Guenther <jguenther@cpan.org>
392
393 B<jhannah>:Jay Hannah <jay@jays.net>
394
395 B<jmac>:Jason McIntosh <jmac@appleseed-sc.com>
396
397 B<jmmills>:Jason M. Mills <jmmills@cpan.org>
398
399 B<jnapiorkowski>:John Napiorkowski <jjn1056@yahoo.com>
398 B<jgoulah>: John Goulah <jgoulah@cpan.org>
399
400 B<jguenther>: Justin Guenther <jguenther@cpan.org>
401
402 B<jhannah>: Jay Hannah <jay@jays.net>
403
404 B<jmac>: Jason McIntosh <jmac@appleseed-sc.com>
405
406 B<jmmills>: Jason M. Mills <jmmills@cpan.org>
407
408 B<jnapiorkowski>: John Napiorkowski <jjn1056@yahoo.com>
400409
401410 Joe Carlson <jwcarlson@lbl.gov>
402411
403 B<jon>:Jon Schutz <jjschutz@cpan.org>
412 B<jon>: Jon Schutz <jjschutz@cpan.org>
404413
405414 Jordan Metzmeier <jmetzmeier@magazines.com>
406415
407 B<jshirley>:J. Shirley <jshirley@gmail.com>
408
409 B<kaare>:Kaare Rasmussen
410
411 B<kd>:Kieren Diment <diment@gmail.com>
412
413 B<konobi>:Scott McWhirter <konobi@cpan.org>
414
415 B<lejeunerenard>:Sean Zellmer <sean@lejeunerenard.com>
416
417 B<littlesavage>:Alexey Illarionov <littlesavage@orionet.ru>
418
419 B<lukes>:Luke Saunders <luke.saunders@gmail.com>
420
421 B<marcus>:Marcus Ramberg <mramberg@cpan.org>
422
423 B<mateu>:Mateu X. Hunter <hunter@missoula.org>
416 B<jshirley>: J. Shirley <jshirley@gmail.com>
417
418 B<kaare>: Kaare Rasmussen
419
420 B<kd>: Kieren Diment <diment@gmail.com>
421
422 B<kkane>: Kevin L. Kane <kevin.kane@gmail.com>
423
424 B<konobi>: Scott McWhirter <konobi@cpan.org>
425
426 B<lejeunerenard>: Sean Zellmer <sean@lejeunerenard.com>
427
428 B<littlesavage>: Alexey Illarionov <littlesavage@orionet.ru>
429
430 B<lukes>: Luke Saunders <luke.saunders@gmail.com>
431
432 B<marcus>: Marcus Ramberg <mramberg@cpan.org>
433
434 B<mateu>: Mateu X. Hunter <hunter@missoula.org>
424435
425436 Matt LeBlanc <antirice@gmail.com>
426437
427438 Matt Sickler <imMute@msk4.com>
428439
429 B<mattlaw>:Matt Lawrence
430
431 B<mattp>:Matt Phillips <mattp@cpan.org>
432
433 B<mdk>:Mark Keating <m.keating@shadowcat.co.uk>
434
435 B<melo>:Pedro Melo <melo@simplicidade.org>
436
437 B<metaperl>:Terrence Brannon <metaperl@gmail.com>
438
439 B<michaelr>:Michael Reddick <michael.reddick@gmail.com>
440
441 B<milki>:Jonathan Chu <milki@rescomp.berkeley.edu>
442
443 B<minty>:Murray Walker <perl@minty.org>
444
445 B<mithaldu>:Christian Walde <walde.christian@gmail.com>
446
447 B<mjemmeson>:Michael Jemmeson <michael.jemmeson@gmail.com>
448
449 B<mna>:Maya
450
451 B<mo>:Moritz Onken <onken@netcubed.de>
452
453 B<moltar>:Roman Filippov <romanf@cpan.org>
454
455 B<moritz>:Moritz Lenz <moritz@faui2k3.org>
456
457 B<mrf>:Mike Francis <ungrim97@gmail.com>
458
459 B<mst>:Matt S. Trout <mst@shadowcat.co.uk>
460
461 B<mstratman>:Mark A. Stratman <stratman@gmail.com>
462
463 B<ned>:Neil de Carteret <n3dst4@gmail.com>
464
465 B<nigel>:Nigel Metheringham <nigelm@cpan.org>
466
467 B<ningu>:David Kamholz <dkamholz@cpan.org>
468
469 B<Nniuq>:Ron "Quinn" Straight" <quinnfazigu@gmail.org>
470
471 B<norbi>:Norbert Buchmuller <norbi@nix.hu>
472
473 B<nothingmuch>:Yuval Kogman <nothingmuch@woobling.org>
474
475 B<nuba>:Nuba Princigalli <nuba@cpan.org>
476
477 B<Numa>:Dan Sully <daniel@cpan.org>
478
479 B<oalders>:Olaf Alders <olaf@wundersolutions.com>
440 B<mattlaw>: Matt Lawrence
441
442 B<mattp>: Matt Phillips <mattp@cpan.org>
443
444 B<mdk>: Mark Keating <m.keating@shadowcat.co.uk>
445
446 B<melo>: Pedro Melo <melo@simplicidade.org>
447
448 B<metaperl>: Terrence Brannon <metaperl@gmail.com>
449
450 B<michaelr>: Michael Reddick <michael.reddick@gmail.com>
451
452 B<milki>: Jonathan Chu <milki@rescomp.berkeley.edu>
453
454 B<minty>: Murray Walker <perl@minty.org>
455
456 B<mithaldu>: Christian Walde <walde.christian@gmail.com>
457
458 B<mjemmeson>: Michael Jemmeson <michael.jemmeson@gmail.com>
459
460 B<mna>: Maya
461
462 B<mo>: Moritz Onken <onken@netcubed.de>
463
464 B<moltar>: Roman Filippov <romanf@cpan.org>
465
466 B<moritz>: Moritz Lenz <moritz@faui2k3.org>
467
468 B<mrf>: Mike Francis <ungrim97@gmail.com>
469
470 B<mst>: Matt S. Trout <mst@shadowcat.co.uk>
471
472 B<mstratman>: Mark A. Stratman <stratman@gmail.com>
473
474 B<ned>: Neil de Carteret <n3dst4@gmail.com>
475
476 B<nigel>: Nigel Metheringham <nigelm@cpan.org>
477
478 B<ningu>: David Kamholz <dkamholz@cpan.org>
479
480 B<Nniuq>: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
481
482 B<norbi>: Norbert Buchmuller <norbi@nix.hu>
483
484 B<nothingmuch>: Yuval Kogman <nothingmuch@woobling.org>
485
486 B<nuba>: Nuba Princigalli <nuba@cpan.org>
487
488 B<Numa>: Dan Sully <daniel@cpan.org>
489
490 B<oalders>: Olaf Alders <olaf@wundersolutions.com>
480491
481492 Olly Betts <olly@survex.com>
482493
483 B<osfameron>:Hakim Cassimally <osfameron@cpan.org>
484
485 B<ovid>:Curtis "Ovid" Poe <ovid@cpan.org>
486
487 B<oyse>:Øystein Torget <oystein.torget@dnv.com>
488
489 B<paulm>:Paul Makepeace <paulm+pause@paulm.com>
490
491 B<penguin>:K J Cheetham <jamie@shadowcatsystems.co.uk>
492
493 B<perigrin>:Chris Prather <chris@prather.org>
494 B<osfameron>: Hakim Cassimally <osfameron@cpan.org>
495
496 B<ovid>: Curtis "Ovid" Poe <ovid@cpan.org>
497
498 B<oyse>: Øystein Torget <oystein.torget@dnv.com>
499
500 B<paulm>: Paul Makepeace <paulm+pause@paulm.com>
501
502 B<penguin>: K J Cheetham <jamie@shadowcatsystems.co.uk>
503
504 B<perigrin>: Chris Prather <chris@prather.org>
494505
495506 Peter Siklósi <einon@einon.hu>
496507
497508 Peter Valdemar Mørch <peter@morch.com>
498509
499 B<peter>:Peter Collingbourne <peter@pcc.me.uk>
500
501 B<phaylon>:Robert Sedlacek <phaylon@dunkelheit.at>
502
503 B<plu>:Johannes Plunien <plu@cpan.org>
504
505 B<Possum>:Daniel LeWarne <possum@cpan.org>
506
507 B<pplu>:Jose Luis Martinez <jlmartinez@capside.com>
508
509 B<quicksilver>:Jules Bean <jules@jellybean.co.uk>
510
511 B<racke>:Stefan Hornburg <racke@linuxia.de>
512
513 B<rafl>:Florian Ragwitz <rafl@debian.org>
514
515 B<rainboxx>:Matthias Dietrich <perl@rb.ly>
516
517 B<rbo>:Robert Bohne <rbo@cpan.org>
518
519 B<rbuels>:Robert Buels <rmb32@cornell.edu>
520
521 B<rdj>:Ryan D Johnson <ryan@innerfence.com>
522
523 B<Relequestual>:Ben Hutton <relequestual@gmail.com>
524
525 B<renormalist>:Steffen Schwigon <schwigon@cpan.org>
526
527 B<ribasushi>:Peter Rabbitson <ribasushi@cpan.org>
528
529 B<rjbs>:Ricardo Signes <rjbs@cpan.org>
510 B<peter>: Peter Collingbourne <peter@pcc.me.uk>
511
512 B<phaylon>: Robert Sedlacek <phaylon@dunkelheit.at>
513
514 B<plu>: Johannes Plunien <plu@cpan.org>
515
516 B<Possum>: Daniel LeWarne <possum@cpan.org>
517
518 B<pplu>: Jose Luis Martinez <jlmartinez@capside.com>
519
520 B<quicksilver>: Jules Bean <jules@jellybean.co.uk>
521
522 B<racke>: Stefan Hornburg <racke@linuxia.de>
523
524 B<rafl>: Florian Ragwitz <rafl@debian.org>
525
526 B<rainboxx>: Matthias Dietrich <perl@rb.ly>
527
528 B<rbo>: Robert Bohne <rbo@cpan.org>
529
530 B<rbuels>: Robert Buels <rmb32@cornell.edu>
531
532 B<rdj>: Ryan D Johnson <ryan@innerfence.com>
533
534 B<Relequestual>: Ben Hutton <relequestual@gmail.com>
535
536 B<renormalist>: Steffen Schwigon <schwigon@cpan.org>
537
538 B<ribasushi>: Peter Rabbitson <ribasushi@cpan.org>
539
540 B<rjbs>: Ricardo Signes <rjbs@cpan.org>
530541
531542 Robert Krimen <rkrimen@cpan.org>
532543
533544 Robert Olson <bob@rdolson.org>
534545
535 B<robkinyon>:Rob Kinyon <rkinyon@cpan.org>
546 B<robkinyon>: Rob Kinyon <rkinyon@cpan.org>
536547
537548 Roman Ardern-Corris <spam_in@3legs.com>
538549
539 B<ruoso>:Daniel Ruoso <daniel@ruoso.com>
540
541 B<Sadrak>:Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
542
543 B<sc_>:Just Another Perl Hacker
544
545 B<schwern>:Michael G Schwern <mschwern@cpan.org>
550 B<ruoso>: Daniel Ruoso <daniel@ruoso.com>
551
552 B<Sadrak>: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
553
554 B<sc_>: Just Another Perl Hacker
555
556 B<schwern>: Michael G Schwern <mschwern@cpan.org>
546557
547558 Scott R. Godin <webdragon.net@gmail.com>
548559
549 B<scotty>:Scotty Allen <scotty@scottyallen.com>
550
551 B<semifor>:Marc Mims <marc@questright.com>
560 B<scotty>: Scotty Allen <scotty@scottyallen.com>
561
562 B<semifor>: Marc Mims <marc@questright.com>
552563
553564 Simon Elliott <cpan@browsing.co.uk>
554565
555 B<SineSwiper>:Brendan Byrd <perl@resonatorsoft.org>
556
557 B<skaufman>:Samuel Kaufman <sam@socialflow.com>
558
559 B<solomon>:Jared Johnson <jaredj@nmgi.com>
560
561 B<spb>:Stephen Bennett <stephen@freenode.net>
566 B<SineSwiper>: Brendan Byrd <perl@resonatorsoft.org>
567
568 B<skaufman>: Samuel Kaufman <sam@socialflow.com>
569
570 B<solomon>: Jared Johnson <jaredj@nmgi.com>
571
572 B<spb>: Stephen Bennett <stephen@freenode.net>
562573
563574 Squeeks <squeek@cpan.org>
564575
565 B<srezic>:Slaven Rezic <slaven@rezic.de>
566
567 B<sszabo>:Stephan Szabo <sszabo@bigpanda.com>
576 B<srezic>: Slaven Rezic <slaven@rezic.de>
577
578 B<sszabo>: Stephan Szabo <sszabo@bigpanda.com>
568579
569580 Stephen Peters <steve@stephenpeters.me>
570581
571 B<stonecolddevin>:Devin Austin <dhoss@cpan.org>
572
573 B<talexb>:Alex Beamish <talexb@gmail.com>
574
575 B<tamias>:Ronald J Kimball <rjk@tamias.net>
576
577 B<TBSliver>:Tom Bloor <t.bloor@shadowcat.co.uk>
578
579 B<teejay>:Aaron Trevena <teejay@cpan.org>
580
581 B<theorbtwo>:James Mastros <james@mastros.biz>
582 B<stonecolddevin>: Devin Austin <dhoss@cpan.org>
583
584 B<talexb>: Alex Beamish <talexb@gmail.com>
585
586 B<tamias>: Ronald J Kimball <rjk@tamias.net>
587
588 B<TBSliver>: Tom Bloor <t.bloor@shadowcat.co.uk>
589
590 B<teejay>: Aaron Trevena <teejay@cpan.org>
591
592 B<theorbtwo>: James Mastros <james@mastros.biz>
582593
583594 Thomas Kratz <tomk@cpan.org>
584595
585 B<timbunce>:Tim Bunce <tim.bunce@pobox.com>
596 B<timbunce>: Tim Bunce <tim.bunce@pobox.com>
586597
587598 Todd Lipcon
588599
589600 Tom Hukins <tom@eborcom.com>
590601
591 B<tommy>:Tommy Butler <tbutler.cpan.org@internetalias.net>
592
593 B<tonvoon>:Ton Voon <ton.voon@opsview.com>
594
595 B<triode>:Pete Gamache <gamache@cpan.org>
596
597 B<typester>:Daisuke Murase <typester@cpan.org>
598
599 B<uree>:Oriol Soriano <oriol.soriano@capside.com>
600
601 B<uwe>:Uwe Voelker <uwe@uwevoelker.de>
602
603 B<victori>:Victor Igumnov <victori@cpan.org>
604
605 B<wdh>:Will Hawes <wdhawes@gmail.com>
606
607 B<wesm>:Wes Malone <wes@mitsi.com>
608
609 B<willert>:Sebastian Willert <willert@cpan.org>
610
611 B<wintermute>:Toby Corkindale <tjc@cpan.org>
612
613 B<wreis>:Wallace Reis <wreis@cpan.org>
614
615 B<xenoterracide>:Caleb Cushing <xenoterracide@gmail.com>
616
617 B<yrlnry>:Mark Jason Dominus <mjd@plover.com>
618
619 B<zamolxes>:Bogdan Lucaciu <bogdan@wiz.ro>
620
621 B<Zefram>:Andrew Main <zefram@fysh.org>
602 B<tommy>: Tommy Butler <tbutler.cpan.org@internetalias.net>
603
604 B<tonvoon>: Ton Voon <ton.voon@opsview.com>
605
606 B<triode>: Pete Gamache <gamache@cpan.org>
607
608 B<typester>: Daisuke Murase <typester@cpan.org>
609
610 B<uree>: Oriol Soriano <oriol.soriano@capside.com>
611
612 B<uwe>: Uwe Voelker <uwe@uwevoelker.de>
613
614 B<vanstyn>: Henry Van Styn <vanstyn@cpan.org>
615
616 B<victori>: Victor Igumnov <victori@cpan.org>
617
618 B<wdh>: Will Hawes <wdhawes@gmail.com>
619
620 B<wesm>: Wes Malone <wes@mitsi.com>
621
622 B<willert>: Sebastian Willert <willert@cpan.org>
623
624 B<wintermute>: Toby Corkindale <tjc@cpan.org>
625
626 B<wreis>: Wallace Reis <wreis@cpan.org>
627
628 B<xenoterracide>: Caleb Cushing <xenoterracide@gmail.com>
629
630 B<xmikew>: Mike Wisener <xmikew@32ths.com>
631
632 B<yrlnry>: Mark Jason Dominus <mjd@plover.com>
633
634 B<zamolxes>: Bogdan Lucaciu <bogdan@wiz.ro>
635
636 B<Zefram>: Andrew Main <zefram@fysh.org>
622637
623638 =back
624639
99 map { chomp; ( ( ! $_ or $_ =~ /^\s*\#/ ) ? () : $_ ) } <$fh>;
1010 } or die "Known AUTHORS file seems empty... can't happen...";
1111
12 $_ =~ s!^ ( [^\:]+ ) : \s !B<$1>:!x
12 $_ =~ s!^ ( [^\:]+ ) : \s !B<$1>: !x
1313 for @known_authors;
1414
1515 $_ =~ s!( \b https? :// [^\s\>]+ )!L<$1|$1>!x
0 ###
1 ### This version is rather 5.8-centric, because DBIC itself is 5.8
2 ### It certainly can be rewritten to degrade well on 5.6
3 ###
4
5
6 BEGIN {
7 if ($] < 5.010) {
8
9 # Pre-5.10 perls pollute %INC on unsuccesfull module
10 # require, making it appear as if the module is already
11 # loaded on subsequent require()s
12 # Can't seem to find the exact RT/perldelta entry
13 #
14 # The reason we can't just use a sane, clean loader, is because
15 # if a Module require()s another module the %INC will still
16 # get filled with crap and we are back to square one. A global
17 # fix is really the only way for this test, as we try to load
18 # each available module separately, and have no control (nor
19 # knowledge) over their common dependencies.
20 #
21 # we want to do this here, in the very beginning, before even
22 # warnings/strict are loaded
23
24 unshift @INC, 't/lib';
25 require DBICTest::Util::OverrideRequire;
26
27 DBICTest::Util::OverrideRequire::override_global_require( sub {
28 my $res = eval { $_[0]->() };
29 if ($@ ne '') {
30 delete $INC{$_[1]};
31 die $@;
32 }
33 return $res;
34 } );
35 }
36 }
37
38 # Explicitly add 'lib' to the front of INC - this way we will
39 # know without ambiguity what was loaded from the local untar
40 # and what came from elsewhere
41 use lib qw(lib t/lib);
42
43 use strict;
44 use warnings;
45
46 use Test::More 'no_plan';
47 use Config;
48 use File::Find 'find';
49 use Module::Runtime 'module_notional_filename';
50 use List::Util qw(max min);
51 use ExtUtils::MakeMaker;
52 use DBICTest::Util 'visit_namespaces';
53
54 # load these two to pull in the t/lib armada
55 use DBICTest;
56 use DBICTest::Schema;
57 DBICTest->init_schema;
58
59 # do !!!NOT!!! use Module::Runtime's require_module - it breaks CORE::require
60 sub req_mod ($) {
61 # trap deprecation warnings and whatnot
62 local $SIG{__WARN__} = sub {};
63 local $@;
64 eval "require $_[0]";
65 }
66
67 sub say_err {
68 print STDERR "\n", @_, "\n";
69 }
70
71 # needed for WeirdOS
72 sub fixup_path ($) {
73 return $_[0] unless ( $^O eq 'MSWin32' and $_[0] );
74
75 # sometimes we can get a short/longname mix, normalize everything to longnames
76 my $fn = Win32::GetLongPathName($_[0]);
77
78 # Fixup (native) slashes in Config not matching (unixy) slashes in INC
79 $fn =~ s|\\|/|g;
80
81 $fn;
82 }
83
84 my @lib_display_order = qw(
85 sitearch
86 sitelib
87 vendorarch
88 vendorlib
89 archlib
90 privlib
91 );
92 my $lib_paths = {
93 (map
94 { $Config{$_}
95 ? ( $_ => fixup_path( $Config{"${_}exp"} || $Config{$_} ) )
96 : ()
97 }
98 @lib_display_order
99 ),
100
101 # synthetic, for display
102 './lib' => 'lib',
103 };
104
105 sub describe_fn {
106 my $fn = shift;
107
108 return '' if !defined $fn;
109
110 $fn = fixup_path( $fn );
111
112 $lib_paths->{$_} and $fn =~ s/^\Q$lib_paths->{$_}/<<$_>>/ and last
113 for @lib_display_order;
114
115 $fn;
116 }
117
118 sub md5_of_fn {
119 # we already checked for -r/-f, just bail if can't open
120 open my $fh, '<:raw', $_[0] or return '';
121 require Digest::MD5;
122 Digest::MD5->new->addfile($fh)->hexdigest;
123 }
124
125 # first run through lib and *try* to load anything we can find
126 # within our own project
127 find({
128 wanted => sub {
129 -f $_ or return;
130
131 # can't just `require $fn`, as we need %INC to be
132 # populated properly
133 my ($mod) = $_ =~ /^ lib [\/\\] (.+) \.pm $/x
134 or return;
135
136 req_mod join ('::', File::Spec->splitdir($mod));
137 },
138 no_chdir => 1,
139 }, 'lib' );
140
141 # now run through OptDeps and attempt loading everything else
142 #
143 # some things needs to be sorted before other things
144 # positive - load first
145 # negative - load last
146 my $load_weights = {
147 # Make sure oracle is tried last - some clients (e.g. 10.2) have symbol
148 # clashes with libssl, and will segfault everything coming after them
149 "DBD::Oracle" => -999,
150 };
151
152 my $optdeps = {
153 map
154 { $_ => 1 }
155 map
156 { keys %{DBIx::Class::Optional::Dependencies->req_list_for($_)} }
157 grep
158 { $_ !~ /rdbms/ }
159 keys %{DBIx::Class::Optional::Dependencies->req_group_list}
160 };
161 req_mod $_ for sort
162 { ($load_weights->{$b}||0) <=> ($load_weights->{$a}||0) }
163 keys %$optdeps
164 ;
165
166 my $has_versionpm = eval { require version };
167
168 # at this point we've loaded everything we ever could, let's drill through
169 # the *ENTIRE* symtable and build a map of versions
170 my $version_list = { perl => $] };
171 visit_namespaces( action => sub {
172 no strict 'refs';
173 my $pkg = shift;
174
175 # keep going, but nothing to see here
176 return 1 if $pkg eq 'main';
177
178 # private - not interested, including no further descent
179 return 0 if $pkg =~ / (?: ^ | :: ) _ /x;
180
181 # not interested in no-VERSION-containing modules, nor synthetic classes
182 return 1 if (
183 ! defined ${"${pkg}::VERSION"}
184 or
185 ${"${pkg}::VERSION"} =~ /\Qset by base.pm/
186 );
187
188 # make sure a version can be extracted, be noisy when it doesn't work
189 # do this even if we are throwing away the result below in lieu of EUMM
190 my $mod_ver = eval { $pkg->VERSION };
191 if (my $err = $@) {
192 $err =~ s/^/ /mg;
193 say_err
194 "Calling `$pkg->VERSION` resulted in an exception, which should never "
195 . "happen - please file a bug with the distribution containing $pkg. "
196 . "Complete exception text below:\n\n$err"
197 ;
198 }
199 elsif( ! defined $mod_ver or ! length $mod_ver ) {
200 my $ret = defined $mod_ver
201 ? "the empty string ''"
202 : "'undef'"
203 ;
204
205 say_err
206 "Calling `$pkg->VERSION` returned $ret, even though \$${pkg}::VERSION "
207 . "is defined, which should never happen - please file a bug with the "
208 . "distribution containing $pkg."
209 ;
210
211 undef $mod_ver;
212 }
213
214 # if this is a real file - extract the version via EUMM whenever possible
215 my $fn = $INC{module_notional_filename($pkg)};
216
217 my $eumm_ver = (
218 $fn
219 and
220 -f $fn
221 and
222 -r $fn
223 and
224 eval { MM->parse_version( $fn ) }
225 ) || undef;
226
227 if (
228 $has_versionpm
229 and
230 defined $eumm_ver
231 and
232 defined $mod_ver
233 and
234 $eumm_ver ne $mod_ver
235 and
236 (
237 ( eval { version->parse( do { (my $v = $eumm_ver) =~ s/_//g; $v } ) } || 0 )
238 !=
239 ( eval { version->parse( do { (my $v = $mod_ver) =~ s/_//g; $v } ) } || 0 )
240 )
241 ) {
242 say_err
243 "Mismatch of versions '$mod_ver' and '$eumm_ver', obtained respectively "
244 . "via `$pkg->VERSION` and parsing the version out of @{[ describe_fn $fn ]} "
245 . "with ExtUtils::MakeMaker\@@{[ ExtUtils::MakeMaker->VERSION ]}. "
246 . "This should never happen - please check whether this is still present "
247 . "in the latest version, and then file a bug with the distribution "
248 . "containing $pkg."
249 ;
250 }
251
252 if( defined $eumm_ver ) {
253 $version_list->{$pkg} = $eumm_ver;
254 }
255 elsif( defined $mod_ver ) {
256 $version_list->{$pkg} = $mod_ver;
257 }
258
259 1;
260 });
261
262 # In retrospect it makes little sense to omit this information - just
263 # show everything at all times.
264 # Nevertheless leave the dead code, in case it turns out to be a bad idea...
265 my $show_all = 1;
266 #my $show_all = $ENV{PERL_DESCRIBE_ALL_DEPS} || !DBICTest::RunMode->is_plain;
267
268 # compress identical versions as close to the root as we can
269 # unless we are dealing with a smoker - in which case we want
270 # to see every MD5 there is
271 unless ($show_all) {
272 for my $mod ( sort { length($b) <=> length($a) } keys %$version_list ) {
273 my $parent = $mod;
274
275 while ( $parent =~ s/ :: (?: . (?! :: ) )+ $ //x ) {
276 $version_list->{$parent}
277 and
278 $version_list->{$parent} eq $version_list->{$mod}
279 and
280 ( ( delete $version_list->{$mod} ) or 1 )
281 and
282 last
283 }
284 }
285 }
286
287 ok 1, (scalar keys %$version_list) . " distinctly versioned modules";
288
289 exit if ($ENV{TRAVIS}||'') eq 'true';
290
291 # sort stuff into @INC segments
292 my $segments;
293
294 MODULE:
295 for my $mod ( sort { lc($a) cmp lc($b) } keys %$version_list ) {
296 my $fn = $INC{module_notional_filename($mod)};
297
298 my $tuple = [ $mod ];
299
300 if ( defined $fn && -f $fn && -r $fn ) {
301 push @$tuple, ( $fn = fixup_path($fn) );
302
303 for my $lib (@lib_display_order, './lib') {
304 if ( $lib_paths->{$lib} and index($fn, $lib_paths->{$lib}) == 0 ) {
305 push @{$segments->{$lib}}, $tuple;
306 next MODULE;
307 }
308 }
309 }
310
311 # fallthrough for anything without a physical filename, or unknown lib
312 push @{$segments->{''}}, $tuple;
313 }
314
315 # diag the result out
316 my $max_ver_len = max map
317 { length $_ }
318 ( values %$version_list, 'xxx.yyyzzz_bbb' )
319 ;
320 my $max_mod_len = max map { length $_ } keys %$version_list;
321
322 my $discl = <<'EOD';
323
324 Versions of all loadable modules within both the core and *OPTIONAL* dependency chains present on this system
325 Note that *MANY* of these modules will *NEVER* be loaded during normal operation of DBIx::Class
326 EOD
327
328 $discl .= "(modules with versions identical to their parent namespace were omitted - set PERL_DESCRIBE_ALL_DEPS to see them)\n"
329 unless $show_all;
330
331 diag $discl;
332
333 diag "\n";
334
335 for my $seg ( '', @lib_display_order, './lib' ) {
336 next unless $segments->{$seg};
337
338 diag sprintf "=== %s ===\n\n",
339 $seg
340 ? "Modules found in " . ( $Config{$seg} ? "\$Config{$seg}" : $seg )
341 : 'Misc versions'
342 ;
343
344 diag sprintf (
345 "%*s %*s%s\n",
346 $max_ver_len => $version_list->{$_->[0]},
347 -$max_mod_len => $_->[0],
348 ($_->[1]
349 ? ' ' x (80 - min(78, $max_mod_len)) . "[ MD5: @{[ md5_of_fn( $_->[1] ) ]} ]"
350 : ''
351 ),
352 ) for @{$segments->{$seg}};
353
354 diag "\n\n"
355 }
356
357 diag "$discl\n";
384384 # test all kinds of population with stringified objects
385385 # or with empty sets
386386 warnings_like {
387 local $ENV{DBIC_RT79576_NOWARN};
388
389387 my $rs = $schema->resultset('Artist')->search({}, { columns => [qw(name rank)], order_by => 'artistid' });
390388
391389 # the stringification has nothing to do with the artist name
506504 );
507505
508506 $rs->delete;
509 } [
510 # warning to be removed around Apr 1st 2015
511 # smokers start failing a month before that
512 (
513 ( DBICTest::RunMode->is_author and ( time() > 1427846400 ) )
514 or
515 ( DBICTest::RunMode->is_smoker and ( time() > 1425168000 ) )
516 )
517 ? ()
518 # one unique for populate() and create() each
519 : (qr/\QPOSSIBLE *PAST* DATA CORRUPTION detected \E.+\QTrigger condition encountered at @{[ __FILE__ ]} line\E \d/) x 4
520 ], 'Data integrity warnings as planned';
507 } [], 'Data integrity warnings gone as planned';
521508
522509 $schema->is_executed_sql_bind(
523510 sub {
1515
1616 cmp_ok(DBICTest->resultset('Artist')->count, '>', 0, 'count is valid');
1717
18 # cleanup globaly cached handle so we do not trigger the leaktest
19 DBICTest->schema->storage->disconnect;
20
2118 done_testing;
2222
2323 use lib qw(t/lib);
2424 use DBICTest::RunMode;
25
26 plan skip_all => "Temporarily no smoke testing of Test::More 1.3xx alphas" if (
27 DBICTest::RunMode->is_smoker
28 and
29 eval { Test::More->VERSION("1.300") }
30 and
31 require ExtUtils::MakeMaker
32 and
33 MM->parse_version($INC{"Test/Builder.pm"}) =~ / ^ 1 \. 3.. ... \_ /x
34 );
35
36 my $TB = Test::More->builder;
37 if ($ENV{DBICTEST_IN_PERSISTENT_ENV}) {
38 # without this explicit close older TBs warn in END after a ->reset
39 if ($TB->VERSION < 1.005) {
40 close ($TB->$_) for (qw/output failure_output todo_output/);
41 }
42
43 # if I do not do this, I get happy sigpipes on new TB, no idea why
44 # (the above close-and-forget doesn't work - new TB does *not* reopen
45 # its handles automatically anymore)
46 else {
47 for (qw/failure_output todo_output/) {
48 close $TB->$_;
49 open ($TB->$_, '>&', *STDERR);
50 }
51
52 close $TB->output;
53 open ($TB->output, '>&', *STDOUT);
54 }
55
56 # so done_testing can work on every persistent pass
57 $TB->reset;
58 }
59
6025 use DBICTest::Util::LeakTracer qw(populate_weakregistry assert_empty_weakregistry visit_refs);
6126 use Scalar::Util qw(weaken blessed reftype);
62 use DBIx::Class;
63 use DBIx::Class::_Util qw(hrefaddr sigwarn_silencer);
27 use DBIx::Class::_Util qw(hrefaddr sigwarn_silencer modver_gt_or_eq modver_gt_or_eq_and_lt);
6428 BEGIN {
6529 plan skip_all => "Your perl version $] appears to leak like a sieve - skipping test"
6630 if DBIx::Class::_ENV_::PEEPEENESS;
31 }
32
33
34 my $TB = Test::More->builder;
35 if ($ENV{DBICTEST_IN_PERSISTENT_ENV}) {
36 # without this explicit close TB warns in END after a ->reset
37 close ($TB->$_) for qw(output failure_output todo_output);
38
39 # newer TB does not auto-reopen handles
40 if ( modver_gt_or_eq( 'Test::More', '1.200' ) ) {
41 open ($TB->$_, '>&', *STDERR)
42 for qw( failure_output todo_output );
43 open ($TB->output, '>&', *STDOUT);
44 }
45
46 # so done_testing can work on every persistent pass
47 $TB->reset;
6748 }
6849
6950 # this is what holds all weakened refs to be checked for leakage
9778 # Test Builder is now making a new object for every pass/fail (que bloat?)
9879 # and as such we can't really store any of its objects (since it will
9980 # re-populate the registry while checking it, ewwww!)
100 return $obj if (ref $obj) =~ /^TB2::/;
81 return $obj if (ref $obj) =~ /^TB2::|^Test::Stream/;
10182
10283 # populate immediately to avoid weird side effects
10384 return populate_weakregistry ($weak_registry, $obj );
338319 ! DBICTest::RunMode->is_plain
339320 and
340321 ! $ENV{DBICTEST_IN_PERSISTENT_ENV}
341 and
342 # FIXME - investigate wtf is going on with 5.18
343 ! ( $] > 5.017 and $ENV{DBIC_TRACE_PROFILE} )
344322 ) {
345323
346324 # FIXME - ideally we should be able to just populate an alternative
468446 delete $weak_registry->{$addr}
469447 unless $cleared->{hash_merge_singleton}{$weak_registry->{$addr}{weakref}{behavior}}++;
470448 }
449 elsif ($names =~ /^DateTime::TimeZone::UTC/m) {
450 # DT is going through a refactor it seems - let it leak zones for now
451 delete $weak_registry->{$addr};
452 }
471453 elsif (
472454 # # if we can look at closed over pieces - we will register it as a global
473455 # !DBICTest::Util::LeakTracer::CV_TRACING
535517 ($ENV{PATH}) = $ENV{PATH} =~ /(.+)/;
536518
537519
538 my $persistence_tests = {
539 PPerl => {
540 cmd => [qw/pperl --prefork=1/, __FILE__],
541 },
542 'CGI::SpeedyCGI' => {
543 cmd => [qw/speedy -- -t5/, __FILE__],
544 },
545 };
546
547 # scgi is smart and will auto-reap after -t amount of seconds
548 # pperl needs an actual killer :(
549 $persistence_tests->{PPerl}{termcmd} = [
550 $persistence_tests->{PPerl}{cmd}[0],
551 '--kill',
552 @{$persistence_tests->{PPerl}{cmd}}[ 1 .. $#{$persistence_tests->{PPerl}{cmd}} ],
553 ];
554
520 my $persistence_tests;
555521 SKIP: {
556522 skip 'Test already in a persistent loop', 1
557523 if $ENV{DBICTEST_IN_PERSISTENT_ENV};
559525 skip 'Main test failed - skipping persistent env tests', 1
560526 unless $TB->is_passing;
561527
528 skip "Test::Builder\@@{[ Test::Builder->VERSION ]} known to break persistence tests", 1
529 if modver_gt_or_eq_and_lt( 'Test::More', '1.200', '1.301001_099' );
530
562531 local $ENV{DBICTEST_IN_PERSISTENT_ENV} = 1;
532
533 $persistence_tests = {
534 PPerl => {
535 cmd => [qw/pperl --prefork=1/, __FILE__],
536 },
537 'CGI::SpeedyCGI' => {
538 cmd => [qw/speedy -- -t5/, __FILE__],
539 },
540 };
541
542 # scgi is smart and will auto-reap after -t amount of seconds
543 # pperl needs an actual killer :(
544 $persistence_tests->{PPerl}{termcmd} = [
545 $persistence_tests->{PPerl}{cmd}[0],
546 '--kill',
547 @{$persistence_tests->{PPerl}{cmd}}[ 1 .. $#{$persistence_tests->{PPerl}{cmd}} ],
548 ];
563549
564550 require IPC::Open2;
565551
609595 # just an extra precaution in case we blew away from the SKIP - since there are no
610596 # PID files to go by (man does pperl really suck :(
611597 END {
612 unless ($ENV{DBICTEST_IN_PERSISTENT_ENV}) {
613 close $_ for (*STDIN, *STDOUT, *STDERR);
598 if ($persistence_tests->{PPerl}{termcmd}) {
614599 local $?; # otherwise test will inherit $? of the system()
615 system (@{$persistence_tests->{PPerl}{termcmd}})
616 if $persistence_tests->{PPerl}{termcmd};
617 }
618 }
600 require IPC::Open3;
601 open my $null, ">", File::Spec->devnull;
602 waitpid(
603 IPC::Open3::open3(undef, $null, $null, @{$persistence_tests->{PPerl}{termcmd}}),
604 0,
605 );
606 }
607 }
101101 namespace::clean
102102 Try::Tiny
103103 Sub::Name
104 strictures
105104 Sub::Defer
106105 Sub::Quote
107106
108107 Scalar::Util
109108 List::Util
109 Storable
110110
111111 Class::Accessor::Grouped
112112 Class::C3::Componentised
167167 my $s = DBICTest->init_schema;
168168 is ($s->resultset('Artist')->find(1)->name, 'Caterwauler McCrae');
169169 assert_no_missing_expected_requires();
170 }
171
172 # make sure we never loaded any of the strictures XS bullshit
173 {
174 ok( ! exists $INC{ Module::Runtime::module_notional_filename($_) }, "$_ load never attempted" )
175 for qw(indirect multidimensional bareword::filehandles);
176170 }
177171
178172 done_testing;
44 # there is talk of possible perl compilations where -T is fatal or just
55 # doesn't work. We don't want to have the user deal with that.
66 BEGIN { unless ($INC{'t/lib/DBICTest/WithTaint.pm'}) {
7
8 if ( $^O eq 'MSWin32' and $^X =~ /\x20/ ) {
9 print "1..0 # SKIP Running this test on Windows with spaces within the perl executable path (\$^X) is not possible due to https://rt.perl.org/Ticket/Display.html?id=123907\n";
10 exit 0;
11 }
712
813 # it is possible the test itself is initially invoked in taint mode
914 # and with relative paths *and* with a relative $^X and some other
391391 sub { die "DBICTestTimeout" },
392392 ));
393393
394 alarm(2);
395394 $artist2 = $schema2->resultset('Artist')->find(1);
396395 $artist2->name('fooey');
396
397 # FIXME - this needs to go away in lieu of a non-retrying runner
398 # ( i.e. after solving RT#47005 )
399 local *DBIx::Class::Storage::DBI::_ping = sub { 1 }, DBIx::Class::_ENV_::OLD_MRO && Class::C3->reinitialize()
400 if DBIx::Class::_Util::modver_gt_or_eq( 'DBD::Pg' => '3.5.0' );
401
402 alarm(1);
397403 $artist2->update;
398404 };
399405
77 use DBIx::Class::Optional::Dependencies ();
88
99 use lib qw(t/lib);
10
11 use DBICTest::Schema::BindType;
12 BEGIN {
13 DBICTest::Schema::BindType->add_columns(
14 'blb2' => {
15 data_type => 'blob',
16 is_nullable => 1,
17 },
18 'clb2' => {
19 data_type => 'clob',
20 is_nullable => 1,
21 }
22 );
23 }
24
1025 use DBICTest;
1126
1227 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_ORA_${_}" } qw/DSN USER PASS/};
85100
86101 my $str = $binstr{$size};
87102 lives_ok {
88 $rs->create( { 'id' => $id, blob => "blob:$str", clob => "clob:$str" } )
103 $rs->create( { 'id' => $id, blob => "blob:$str", clob => "clob:$str", blb2 => "blb2:$str", clb2 => "clb2:$str" } )
89104 } "inserted $size without dying";
90105
91106 my %kids = %{$schema->storage->_dbh->{CachedKids}};
98113 is @objs, 1, 'One row found matching on both LOBs';
99114 ok (try { $objs[0]->blob }||'' eq "blob:$str", 'blob inserted/retrieved correctly');
100115 ok (try { $objs[0]->clob }||'' eq "clob:$str", 'clob inserted/retrieved correctly');
116 ok (try { $objs[0]->clb2 }||'' eq "clb2:$str", "clb2 inserted correctly");
117 ok (try { $objs[0]->blb2 }||'' eq "blb2:$str", "blb2 inserted correctly");
101118
102119 {
103120 local $TODO = '-like comparison on blobs not tested before ora 10 (fails on 8i)'
122139
123140 lives_ok {
124141 $rs->search({ id => $id, blob => "blob:$str", clob => "clob:$str" })
125 ->update({ blob => 'updated blob', clob => 'updated clob' });
142 ->update({ blob => 'updated blob', clob => 'updated clob', clb2 => 'updated clb2', blb2 => 'updated blb2' });
126143 } 'blob UPDATE with blobs in WHERE clause survived';
127144
128145 @objs = $rs->search({ blob => "updated blob", clob => 'updated clob' })->all;
129146 is @objs, 1, 'found updated row';
130147 ok (try { $objs[0]->blob }||'' eq "updated blob", 'blob updated/retrieved correctly');
131148 ok (try { $objs[0]->clob }||'' eq "updated clob", 'clob updated/retrieved correctly');
149 ok (try { $objs[0]->clb2 }||'' eq "updated clb2", "clb2 updated correctly");
150 ok (try { $objs[0]->blb2 }||'' eq "updated blb2", "blb2 updated correctly");
132151
133152 lives_ok {
134153 $rs->search({ id => $id })
159178
160179 do_clean($dbh);
161180
162 $dbh->do("CREATE TABLE ${q}bindtype_test${q} (${q}id${q} integer NOT NULL PRIMARY KEY, ${q}bytea${q} integer NULL, ${q}blob${q} blob NULL, ${q}blob2${q} blob NULL, ${q}clob${q} clob NULL, ${q}clob2${q} clob NULL, ${q}a_memo${q} integer NULL)");
181 $dbh->do("CREATE TABLE ${q}bindtype_test${q} (${q}id${q} integer NOT NULL PRIMARY KEY, ${q}bytea${q} integer NULL, ${q}blob${q} blob NULL, ${q}blb2${q} blob NULL, ${q}clob${q} clob NULL, ${q}clb2${q} clob NULL, ${q}a_memo${q} integer NULL)");
163182 }
164183
165184 # clean up our mess
88
99 use lib qw(t/lib);
1010 use DBICTest;
11 use DBIx::Class::_Util qw(sigwarn_silencer modver_gt_or_eq);
11 use DBIx::Class::_Util qw( sigwarn_silencer modver_gt_or_eq modver_gt_or_eq_and_lt );
1212
1313 # check that we work somewhat OK with braindead SQLite transaction handling
1414 #
159159 $_[1]->do('ALTER TABLE artist ADD COLUMN bigint BIGINT');
160160 });
161161
162 my $sqlite_broken_bigint = (
163 modver_gt_or_eq('DBD::SQLite', '1.34') and ! modver_gt_or_eq('DBD::SQLite', '1.37')
164 );
162 my $sqlite_broken_bigint = modver_gt_or_eq_and_lt( 'DBD::SQLite', '1.34', '1.37' );
165163
166164 # 63 bit integer
167165 my $many_bits = (Math::BigInt->new(2) ** 62);
44 use lib qw(t/lib);
55 use DBICTest;
66 use Test::More;
7
8 plan tests => 15;
97
108 my $schema = DBICTest->init_schema();
119 my $rs = $schema->resultset( 'CD' );
130128 is_deeply( $result, $expected );
131129 }
132130
131 {
132 my $a = [ { 'artist' => { 'manager' => {} } }, 'cd' ];
133 my $b = [ 'artist', { 'artist' => { 'manager' => {} } } ];
134 my $expected = [ { 'artist' => { 'manager' => {} } }, 'cd', { 'artist' => { 'manager' => {} } } ];
135 my $result = $rs->_merge_joinpref_attr($a, $b);
136 is_deeply( $result, $expected );
137 }
133138
134 1;
139 {
140 my $a = [ { 'artist' => { 'manager' => undef } }, 'cd' ];
141 my $b = [ 'artist', { 'artist' => { 'manager' => undef } } ];
142 my $expected = [ { 'artist' => { 'manager' => undef } }, 'cd', { 'artist' => { 'manager' => undef } } ];
143 my $result = $rs->_merge_joinpref_attr($a, $b);
144 is_deeply( $result, $expected );
145 }
146
147 done_testing;
6060 );
6161 is( $it->count, 1, "complex abstract count ok" );
6262
63 # cleanup globals so we do not trigger the leaktest
64 for ( map { DBICTest->schema->class($_) } DBICTest->schema->sources ) {
65 $_->class_resolver(undef);
66 $_->resultset_instance(undef);
67 $_->result_source_instance(undef);
68 }
69 {
70 no warnings qw/redefine once/;
71 *DBICTest::schema = sub {};
72 }
73
7463 done_testing;
66 use lib qw(t/lib);
77 use DBICTest;
88
9 plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_oracle')
10 unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_oracle');
11
129 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_ORA_${_}" } qw/DSN USER PASS/};
1310
1411 if (not ($dsn && $user && $pass)) {
1512 plan skip_all => 'Set $ENV{DBICTEST_ORA_DSN}, _USER and _PASS to run this test. ' .
1613 'Warning: This test drops and creates a table called \'event\'';
1714 }
15
16 plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_oracle')
17 unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_oracle');
18
1819
1920 # DateTime::Format::Oracle needs this set
2021 $ENV{NLS_DATE_FORMAT} = 'DD-MON-YY';
22
33 use Test::More;
44
5 use DBIx::Class::_Util 'modver_gt_or_eq';
5 use DBIx::Class::_Util 'modver_gt_or_eq_and_lt';
66 use base();
77 BEGIN {
88 plan skip_all => 'base.pm 2.20 (only present in perl 5.19.7) is known to break this test'
9 if modver_gt_or_eq(base => '2.19_01') and ! modver_gt_or_eq(base => '2.21');
9 if modver_gt_or_eq_and_lt( 'base', '2.19_01', '2.21' );
1010 }
1111
1212 use Test::Exception;
197197
198198 sub is_smoker {
199199 return
200 ( ($ENV{TRAVIS}||'') eq 'true' )
200 ( ($ENV{TRAVIS}||'') eq 'true' and ($ENV{TRAVIS_REPO_SLUG}||'') eq 'dbsrgits/dbix-class' )
201201 ||
202202 ( $ENV{AUTOMATED_TESTING} && ! $ENV{PERL5_CPANM_IS_RUNNING} && ! $ENV{RELEASE_TESTING} )
203203 ;
77 use DBIx::Class::_Util qw(refcount hrefaddr refdesc);
88 use DBIx::Class::Optional::Dependencies;
99 use Data::Dumper::Concise;
10 use DBICTest::Util 'stacktrace';
10 use DBICTest::Util qw( stacktrace visit_namespaces );
1111 use constant {
1212 CV_TRACING => DBIx::Class::Optional::Dependencies->req_ok_for ('test_leaks_heavy'),
13 SKIP_SCALAR_REFS => ( $] > 5.017 ) ? 1 : 0,
1413 };
1514
1615 use base 'Exporter';
4140 (defined $reg->{$_}{weakref}) or delete $reg->{$_}
4241 for keys %$reg;
4342 }
44
45 # FIXME/INVESTIGATE - something fishy is going on with refs to plain
46 # strings, perhaps something to do with the CoW work etc...
47 return $target if SKIP_SCALAR_REFS and reftype($target) eq 'SCALAR';
4843
4944 if (! defined $weak_registry->{$refaddr}{weakref}) {
5045 $weak_registry->{$refaddr} = {
140135 elsif (CV_TRACING and $type eq 'CODE') {
141136 $visited_cnt += visit_refs({ %$args, refs => [ map {
142137 ( !isweak($_) ) ? $_ : ()
143 } scalar PadWalker::closed_over($r) ] }); # scalar due to RT#92269
138 } values %{ scalar PadWalker::closed_over($r) } ] }); # scalar due to RT#92269
144139 }
145140 1;
146141 } or warn "Could not descend into @{[ refdesc $r ]}: $@\n";
147142 }
148143 $visited_cnt;
149 }
150
151 sub visit_namespaces {
152 my $args = { (ref $_[0]) ? %{$_[0]} : @_ };
153
154 my $visited = 1;
155
156 $args->{package} ||= '::';
157 $args->{package} = '::' if $args->{package} eq 'main';
158
159 if ( $args->{action}->($args->{package}) ) {
160
161 my $base = $args->{package};
162 $base = '' if $base eq '::';
163
164
165 $visited += visit_namespaces({ %$args, package => $_ }) for map
166 { $_ =~ /(.+?)::$/ ? "${base}::$1" : () }
167 grep
168 { $_ =~ /(?<!^main)::$/ }
169 do { no strict 'refs'; keys %{ $base . '::'} }
170 }
171
172 return $visited;
173144 }
174145
175146 # compiles a list of addresses stored as globals (possibly even catching
178149
179150 my $refs_per_pkg;
180151
181 my $dummy_addresslist;
182
183152 my $seen_refs = {};
184153 visit_namespaces(
185154 action => sub {
187156 no strict 'refs';
188157
189158 my $pkg = shift;
190 $pkg = '' if $pkg eq '::';
191 $pkg .= '::';
192159
193160 # the unless regex at the end skips some dangerous namespaces outright
194161 # (but does not prevent descent)
195162 $refs_per_pkg->{$pkg} += visit_refs (
196163 seen_refs => $seen_refs,
197164
198 # FIXME FIXME FIXME
199 # This is so damn odd - if we feed a constsub {1} (or in fact almost
200 # anything other than the actionsub below, any scalarref will show
201 # up as a leak, trapped by... something...
202 # Ideally we should be able to const this to sub{1} and just return
203 # $seen_refs (in fact it is identical to the dummy list at the end of
204 # a run here). Alas this doesn't seem to work, so punt for now...
205 action => sub { ++$dummy_addresslist->{ hrefaddr $_[0] } },
165 action => sub { 1 },
206166
207167 refs => [ map { my $sym = $_;
208 # *{"$pkg$sym"}{CODE} won't simply work - MRO-cached CVs are invisible there
209 ( CV_TRACING ? Class::MethodCache::get_cv("${pkg}$sym") : () ),
210
211 ( defined *{"$pkg$sym"}{SCALAR} and length ref ${"$pkg$sym"} and ! isweak( ${"$pkg$sym"} ) )
212 ? ${"$pkg$sym"} : ()
168 # *{"${pkg}::$sym"}{CODE} won't simply work - MRO-cached CVs are invisible there
169 ( CV_TRACING ? Class::MethodCache::get_cv("${pkg}::$sym") : () ),
170
171 ( defined *{"${pkg}::$sym"}{SCALAR} and length ref ${"${pkg}::$sym"} and ! isweak( ${"${pkg}::$sym"} ) )
172 ? ${"${pkg}::$sym"} : ()
213173 ,
214174
215175 ( map {
216 ( defined *{"$pkg$sym"}{$_} and ! isweak(defined *{"$pkg$sym"}{$_}) )
217 ? *{"$pkg$sym"}{$_}
176 ( defined *{"${pkg}::$sym"}{$_} and ! isweak(defined *{"${pkg}::$sym"}{$_}) )
177 ? *{"${pkg}::$sym"}{$_}
218178 : ()
219179 } qw(HASH ARRAY IO GLOB) ),
220180
221 } keys %$pkg ],
222 ) unless $pkg =~ /^ :: (?:
181 } keys %{"${pkg}::"} ],
182 ) unless $pkg =~ /^ (?:
223183 DB | next | B | .+? ::::ISA (?: ::CACHE ) | Class::C3
224 ) :: $/x;
184 ) $/x;
225185 }
226186 );
227187
238198
239199 sub assert_empty_weakregistry {
240200 my ($weak_registry, $quiet) = @_;
241
242 Sub::Defer::undefer_all();
243201
244202 # in case we hooked bless any extra object creation will wreak
245203 # havoc during the assert phase
365323 $tb->note("Auto checked $refs_traced references for leaks - none detected");
366324 }
367325
368 # Disable this until better times - SQLT and probably other things
369 # still load strictures. Let's just wait until Moo2.0 and go from there
370 =begin for tears
371326 # also while we are here and not in plain runmode: make sure we never
372327 # loaded any of the strictures XS bullshit (it's a leak in a sense)
373 unless (DBICTest::RunMode->is_plain) {
328 unless (
329 $ENV{MOO_FATAL_WARNINGS}
330 or
331 # FIXME - SQLT loads strictures explicitly, /facedesk
332 # remove this INC check when 0fb58589 and 45287c815 are rectified
333 $INC{'SQL/Translator.pm'}
334 or
335 DBICTest::RunMode->is_plain
336 ) {
374337 for (qw(indirect multidimensional bareword::filehandles)) {
375338 exists $INC{ Module::Runtime::module_notional_filename($_) }
376339 and
377340 $tb->ok(0, "$_ load should not have been attempted!!!" )
378341 }
379342 }
380 =cut
381
382343 }
383344 }
384345
1616 }
1717 }
1818
19 use Module::Runtime 'module_notional_filename';
20 BEGIN {
21 for my $mod (qw( SQL::Abstract::Test SQL::Abstract )) {
22 if ( $INC{ module_notional_filename($mod) } ) {
23 # FIXME this does not seem to work in BEGIN - why?!
24 #require Carp;
25 #$Carp::Internal{ (__PACKAGE__) }++;
26 #Carp::croak( __PACKAGE__ . " must be loaded before $mod" );
27
28 my ($fr, @frame) = 1;
29 while (@frame = caller($fr++)) {
30 last if $frame[1] !~ m|^t/lib/DBICTest|;
31 }
32
33 die __PACKAGE__ . " must be loaded before $mod (or modules using $mod) at $frame[1] line $frame[2]\n";
34 }
35 }
36 }
37
3819 use Config;
3920 use Carp 'confess';
4021 use Scalar::Util qw(blessed refaddr);
22 use DBIx::Class::_Util;
4123
4224 use base 'Exporter';
43 our @EXPORT_OK = qw(local_umask stacktrace check_customcond_args);
25 our @EXPORT_OK = qw(local_umask stacktrace check_customcond_args visit_namespaces);
4426
4527 sub local_umask {
4628 return unless defined $Config{d_umask};
5638 {
5739 package DBICTest::Util::UmaskGuard;
5840 sub DESTROY {
41 &DBIx::Class::_Util::detected_reinvoked_destructor;
42
5943 local ($@, $!);
6044 eval { defined (umask ${$_[0]}) or die };
6145 warn ( "Unable to reset old umask ${$_[0]}: " . ($!||'Unknown error') )
124108 $args;
125109 }
126110
111 sub visit_namespaces {
112 my $args = { (ref $_[0]) ? %{$_[0]} : @_ };
113
114 my $visited_count = 1;
115
116 # A package and a namespace are subtly different things
117 $args->{package} ||= 'main';
118 $args->{package} = 'main' if $args->{package} =~ /^ :: (?: main )? $/x;
119 $args->{package} =~ s/^:://;
120
121 if ( $args->{action}->($args->{package}) ) {
122 my $ns =
123 ( ($args->{package} eq 'main') ? '' : $args->{package} )
124 .
125 '::'
126 ;
127
128 $visited_count += visit_namespaces( %$args, package => $_ ) for
129 grep
130 # this happens sometimes on %:: traversal
131 { $_ ne '::main' }
132 map
133 { $_ =~ /^(.+?)::$/ ? "$ns$1" : () }
134 do { no strict 'refs'; keys %$ns }
135 ;
136 }
137
138 return $visited_count;
139 }
140
127141 1;
66 use DBICTest::Util 'local_umask';
77 use DBICTest::Schema;
88 use DBICTest::Util::LeakTracer qw/populate_weakregistry assert_empty_weakregistry/;
9 use DBIx::Class::_Util 'detected_reinvoked_destructor';
910 use Carp;
1011 use Path::Class::File ();
1112 use File::Spec;
141142
142143 $SIG{INT} = sub { _cleanup_dbfile(); exit 1 };
143144
145 my $need_global_cleanup;
144146 sub _cleanup_dbfile {
145147 # cleanup if this is us
146148 if (
150152 or
151153 $ENV{DBICTEST_LOCK_HOLDER} == $$
152154 ) {
155 if ($need_global_cleanup and my $dbh = DBICTest->schema->storage->_dbh) {
156 $dbh->disconnect;
157 }
158
153159 my $db_file = _sqlite_dbfilename();
154160 unlink $_ for ($db_file, "${db_file}-journal");
155161 }
216222 $dbh->{Callbacks} = {
217223 connect => sub { $guard_cb->('connect') },
218224 disconnect => sub { $guard_cb->('disconnect') },
219 DESTROY => sub { $guard_cb->('DESTROY') },
225 DESTROY => sub { &detected_reinvoked_destructor; $guard_cb->('DESTROY') },
220226 };
221227 }
222228 },
314320 my $schema;
315321
316322 if ($args{compose_connection}) {
323 $need_global_cleanup = 1;
317324 $schema = DBICTest::Schema->compose_connection(
318325 'DBICTest', $self->_database(%args)
319326 );
127127 ],
128128 'Expected SQL on correlated realiased subquery'
129129 );
130
131 $schema->storage->disconnect;
130132
131133 # test for subselect identifier leakage
132134 # NOTE - the hodge-podge mix of literal and regular identifuers is *deliberate*
145145 );
146146 }
147147
148 $schema->storage->_dbh->disconnect;
149
148150 # make sure connection-less storages do not throw on _determine_driver
149151 # but work with ENV at the same time
150152 SKIP: for my $env_dsn (undef, (DBICTest->_database)[0] ) {
216216 is(scalar @w, 0, 'no warnings \o/');
217217 }
218218
219 # ensure Devel::StackTrace-refcapture-like effects are countered
220 {
221 my $s = DBICTest::Schema->connect('dbi:SQLite::memory:');
222 my $g = $s->txn_scope_guard;
223
224 my @arg_capture;
225 {
226 local $SIG{__WARN__} = sub {
227 package DB;
228 my $frnum;
229 while (my @f = caller(++$frnum) ) {
230 push @arg_capture, @DB::args;
231 }
232 };
233
234 undef $g;
235 1;
236 }
237
238 warnings_exist
239 { @arg_capture = () }
240 qr/\QPreventing *MULTIPLE* DESTROY() invocations on DBIx::Class::Storage::TxnScopeGuard/
241 ;
242 }
243
219244 done_testing;
0 use warnings;
1 use strict;
2
3 use Test::More 'no_plan';
4
5 my $authorcount = scalar do {
6 open (my $fh, '<', 'AUTHORS') or die "Unable to open AUTHORS - can't happen: $!\n";
7 map { chomp; ( ( ! $_ or $_ =~ /^\s*\#/ ) ? () : $_ ) } <$fh>;
8 } or die "Known AUTHORS file seems empty... can't happen...";
9
10 # do not announce anything under travis - we are watching for STDERR silence
11 diag "\n\n$authorcount contributors made this library what it is today\n\n"
12 unless ($ENV{TRAVIS}||'') eq 'true';
13
14 ok 1;
3737
3838 my $email_re = qr/( \< [^\<\>]+ \> ) $/x;
3939
40 my (%known_authors, $count);
40 my %known_authors;
4141 for (@known_authors) {
4242 my ($name_email) = m/ ^ (?: [^\:]+ \: \s )? (.+) /x;
4343 my ($email) = $name_email =~ $email_re;
4444
45 if (
45 fail "Duplicate found: $name_email" if (
4646 $known_authors{$name_email}++
4747 or
4848 ( $email and $known_authors{$email}++ )
49 ) {
50 fail "Duplicate found: $name_email";
51 }
52 else {
53 $count++;
54 }
49 );
5550 }
56
57 # do not announce anything under travis - we are watching for STDERR silence
58 diag "\n\n$count contributors made this library what it is today\n\n"
59 unless ($ENV{TRAVIS}||'') eq 'true';
6051
6152 # augh taint mode
6253 if (length $ENV{PATH}) {