Reorganize constants handling, add escapes for fork-less OSes
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
CommitLineData
ea2e61bf 1package DBIx::Class;
2
5d283305 3use strict;
4use warnings;
5
f9cc85ce 6our $VERSION;
7# Always remember to do all digits for the version even if they're 0
8# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
9# brain damage and presumably various other packaging systems too
10
11# $VERSION declaration must stay up here, ahead of any other package
12# declarations, as to not confuse various modules attempting to determine
13# this ones version, whether that be s.c.o. or Module::Metadata, etc
897f4ac8 14$VERSION = '0.08203_01';
f9cc85ce 15
16$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
17
87bf71d5 18BEGIN {
6cefa7ab 19 package # hide from pause
20 DBIx::Class::_ENV_;
e0b2dc74 21
0d8817bc 22 use Config;
4bea1fe7 23
0d8817bc 24 use constant {
e0b2dc74 25
0d8817bc 26 # but of course
27 BROKEN_FORK => ($^O eq 'MSWin32') ? 1 : 0,
b4ad8a74 28
0d8817bc 29 HAS_ITHREADS => $Config{useithreads} ? 1 : 0,
e0b2dc74 30
0d8817bc 31 # ::Runmode would only be loaded by DBICTest, which in turn implies t/
32 DBICTEST => eval { DBICTest::RunMode->is_author } ? 1 : 0,
e0b2dc74 33
0d8817bc 34 # During 5.13 dev cycle HELEMs started to leak on copy
35 PEEPEENESS =>
36 # request for all tests would force "non-leaky" illusion and vice-versa
37 defined $ENV{DBICTEST_ALL_LEAKS} ? !$ENV{DBICTEST_ALL_LEAKS}
38 # otherwise confess that this perl is busted ONLY on smokers
39 : eval { DBICTest::RunMode->is_smoker } && ($] >= 5.013005 and $] <= 5.013006) ? 1
40 # otherwise we are good
41 : 0
42 ,
e0b2dc74 43
0d8817bc 44 # There was a brief period of p5p insanity when $@ was invisible in a DESTROY
45 INVISIBLE_DOLLAR_AT => ($] >= 5.013001 and $] <= 5.013007) ? 1 : 0,
e0b2dc74 46
0d8817bc 47 };
b4ad8a74 48
0d8817bc 49 if ($] < 5.009_005) {
50 require MRO::Compat;
51 constant->import( OLD_MRO => 1 );
52 }
53 else {
54 require mro;
55 constant->import( OLD_MRO => 0 );
56 }
87bf71d5 57}
58
d38cd95c 59use mro 'c3';
329d7385 60
2527233b 61use DBIx::Class::Optional::Dependencies;
62
db29433c 63use base qw/DBIx::Class::Componentised DBIx::Class::AccessorGroup/;
11736b4c 64use DBIx::Class::StartupCheck;
3e110410 65
70c28808 66__PACKAGE__->mk_group_accessors(inherited => '_skip_namespace_frames');
9345b14c 67__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve');
70c28808 68
ade0fe3b 69sub mk_classdata {
77d518d1 70 shift->mk_classaccessor(@_);
71}
72
73sub mk_classaccessor {
74 my $self = shift;
ade0fe3b 75 $self->mk_group_accessors('inherited', $_[0]);
77d518d1 76 $self->set_inherited(@_) if @_ > 1;
3e110410 77}
3c0068c1 78
7411204b 79sub component_base_class { 'DBIx::Class' }
227d4dee 80
f0750722 81sub MODIFY_CODE_ATTRIBUTES {
b5d2c57f 82 my ($class,$code,@attrs) = @_;
83 $class->mk_classdata('__attr_cache' => {})
84 unless $class->can('__attr_cache');
85 $class->__attr_cache->{$code} = [@attrs];
86 return ();
f0750722 87}
88
da95b45f 89sub _attr_cache {
b5d2c57f 90 my $self = shift;
91 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
9780718f 92
93 return {
94 %$cache,
95 %{ $self->maybe::next::method || {} },
20674fcd 96 };
da95b45f 97}
98
ea2e61bf 991;
34d52be2 100
75d07914 101=head1 NAME
34d52be2 102
7e4b2f59 103DBIx::Class - Extensible and flexible object <-> relational mapper.
34d52be2 104
3b1c2bbd 105=head1 GETTING HELP/SUPPORT
106
107The community can be found via:
108
a06e1181 109=over
3b1c2bbd 110
054235c6 111=item * Web Site: L<http://www.dbix-class.org/>
112
c6fdaf2a 113=item * IRC: irc.perl.org#dbix-class
114
115=for html
e3194e31 116<a href="http://chat.mibbit.com/#dbix-class@irc.perl.org">(click for instant chatroom login)</a>
3b1c2bbd 117
a06e1181 118=item * Mailing list: L<http://lists.scsys.co.uk/mailman/listinfo/dbix-class>
3b1c2bbd 119
a06e1181 120=item * RT Bug Tracker: L<https://rt.cpan.org/Dist/Display.html?Queue=DBIx-Class>
121
aeb669b8 122=item * gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class.git>
a06e1181 123
aeb669b8 124=item * git: L<git://git.shadowcat.co.uk/dbsrgits/DBIx-Class.git>
a06e1181 125
43517a60 126=item * twitter L<http://www.twitter.com/dbix_class>
127
a06e1181 128=back
3b1c2bbd 129
34d52be2 130=head1 SYNOPSIS
131
03460bef 132Create a schema class called MyApp/Schema.pm:
34d52be2 133
03460bef 134 package MyApp::Schema;
a0638a7b 135 use base qw/DBIx::Class::Schema/;
34d52be2 136
f0bb26f3 137 __PACKAGE__->load_namespaces();
daec44b8 138
a0638a7b 139 1;
daec44b8 140
30e1753a 141Create a result class to represent artists, who have many CDs, in
03460bef 142MyApp/Schema/Result/Artist.pm:
daec44b8 143
30e1753a 144See L<DBIx::Class::ResultSource> for docs on defining result classes.
145
03460bef 146 package MyApp::Schema::Result::Artist;
d88ecca6 147 use base qw/DBIx::Class::Core/;
daec44b8 148
a0638a7b 149 __PACKAGE__->table('artist');
150 __PACKAGE__->add_columns(qw/ artistid name /);
151 __PACKAGE__->set_primary_key('artistid');
326dacbf 152 __PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD', 'artistid');
daec44b8 153
a0638a7b 154 1;
daec44b8 155
30e1753a 156A result class to represent a CD, which belongs to an artist, in
03460bef 157MyApp/Schema/Result/CD.pm:
39fe0e65 158
03460bef 159 package MyApp::Schema::Result::CD;
d88ecca6 160 use base qw/DBIx::Class::Core/;
39fe0e65 161
d88ecca6 162 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
a0638a7b 163 __PACKAGE__->table('cd');
bd077b47 164 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
a0638a7b 165 __PACKAGE__->set_primary_key('cdid');
03460bef 166 __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Result::Artist', 'artistid');
39fe0e65 167
a0638a7b 168 1;
39fe0e65 169
a0638a7b 170Then you can use these classes in your application's code:
39fe0e65 171
a0638a7b 172 # Connect to your database.
03460bef 173 use MyApp::Schema;
174 my $schema = MyApp::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
a0638a7b 175
176 # Query for all artists and put them in an array,
177 # or retrieve them as a result set object.
30e1753a 178 # $schema->resultset returns a DBIx::Class::ResultSet
2053ab2a 179 my @all_artists = $schema->resultset('Artist')->all;
180 my $all_artists_rs = $schema->resultset('Artist');
126042ee 181
30e1753a 182 # Output all artists names
4e8ffded 183 # $artist here is a DBIx::Class::Row, which has accessors
16ccb4fe 184 # for all its columns. Rows are also subclasses of your Result class.
85067746 185 foreach $artist (@all_artists) {
30e1753a 186 print $artist->name, "\n";
187 }
188
a0638a7b 189 # Create a result set to search for artists.
86beca1d 190 # This does not query the DB.
2053ab2a 191 my $johns_rs = $schema->resultset('Artist')->search(
6576ef54 192 # Build your WHERE using an SQL::Abstract structure:
2053ab2a 193 { name => { like => 'John%' } }
a0638a7b 194 );
39fe0e65 195
2053ab2a 196 # Execute a joined query to get the cds.
a0638a7b 197 my @all_john_cds = $johns_rs->search_related('cds')->all;
448c8424 198
f0bb26f3 199 # Fetch the next available row.
a0638a7b 200 my $first_john = $johns_rs->next;
448c8424 201
2053ab2a 202 # Specify ORDER BY on the query.
a0638a7b 203 my $first_john_cds_by_title_rs = $first_john->cds(
204 undef,
205 { order_by => 'title' }
206 );
448c8424 207
bd077b47 208 # Create a result set that will fetch the artist data
2053ab2a 209 # at the same time as it fetches CDs, using only one query.
884559b1 210 my $millennium_cds_rs = $schema->resultset('CD')->search(
a0638a7b 211 { year => 2000 },
212 { prefetch => 'artist' }
213 );
448c8424 214
880a1a0c 215 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
bd077b47 216 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
076652e8 217
264f1571 218 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
219 # create() is the same as new() then insert().
884559b1 220 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
f183eccd 221 $new_cd->artist($cd->artist);
f183eccd 222 $new_cd->insert; # Auto-increment primary key filled in after INSERT
f183eccd 223 $new_cd->title('Fork');
224
884559b1 225 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
f183eccd 226
bd077b47 227 # change the year of all the millennium CDs at once
228 $millennium_cds_rs->update({ year => 2002 });
f183eccd 229
230=head1 DESCRIPTION
231
232This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
bd077b47 233(with a compatibility layer as a springboard for porting) and a resultset API
f183eccd 234that allows abstract encapsulation of database operations. It aims to make
235representing queries in your code as perl-ish as possible while still
a0638a7b 236providing access to as many of the capabilities of the database as possible,
f183eccd 237including retrieving related records from multiple tables in a single query,
bd077b47 238JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
f183eccd 239
240DBIx::Class can handle multi-column primary and foreign keys, complex
241queries and database-level paging, and does its best to only query the
75d07914 242database in order to return something you've directly asked for. If a
243resultset is used as an iterator it only fetches rows off the statement
244handle as requested in order to minimise memory usage. It has auto-increment
2053ab2a 245support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
246known to be used in production on at least the first four, and is fork-
ec6415a9 247and thread-safe out of the box (although
9361b05d 248L<your DBD may not be|DBI/Threads and Thread Safety>).
f183eccd 249
dfccde48 250This project is still under rapid development, so large new features may be
251marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
252Failing test cases are *always* welcome and point releases are put out rapidly
253as bugs are found and fixed.
254
255We do our best to maintain full backwards compatibility for published
256APIs, since DBIx::Class is used in production in many organisations,
257and even backwards incompatible changes to non-published APIs will be fixed
258if they're reported and doing so doesn't cost the codebase anything.
259
264f1571 260The test suite is quite substantial, and several developer releases
261are generally made to CPAN before the branch for the next release is
262merged back to trunk for a major release.
f183eccd 263
f183eccd 264=head1 WHERE TO GO NEXT
265
2ca930b4 266L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
267the modules where you will find documentation.
076652e8 268
3942ab4d 269=head1 AUTHOR
34d52be2 270
266bdcc3 271mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 272
dfccde48 273(I mostly consider myself "project founder" these days but the AUTHOR heading
274is traditional :)
275
3942ab4d 276=head1 CONTRIBUTORS
277
907ed671 278abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
84e3c114 279
fd4b0742 280acca: Alexander Kuznetsov <acca@cpan.org>
281
6d84db2c 282aherzog: Adam Herzog <adam@herzogdesigns.com>
283
daeb1865 284Alexander Keusch <cpan@keusch.at>
285
630ba6e5 286alnewkirk: Al Newkirk <we@ana.im>
287
6ebf5cbb 288amiri: Amiri Barksdale <amiri@metalabel.com>
289
b703fec7 290amoore: Andrew Moore <amoore@cpan.org>
291
266bdcc3 292andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 293
266bdcc3 294ank: Andres Kievsky
3942ab4d 295
59ac6523 296arc: Aaron Crane <arc@cpan.org>
297
624764ae 298arcanez: Justin Hunter <justin.d.hunter@gmail.com>
299
ce4c07df 300ash: Ash Berlin <ash@cpan.org>
301
3d5bd2af 302bert: Norbert Csongradi <bert@cpan.org>
303
967a4c40 304blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 305
62eb8fe8 306bluefeet: Aran Deltac <bluefeet@cpan.org>
307
d6170b26 308bphillips: Brian Phillips <bphillips@cpan.org>
309
f856fe01 310boghead: Bryan Beeley <cpan@beeley.org>
311
23d9df41 312brd: Brad Davis <brd@FreeBSD.org>
313
bcb8f3ed 314bricas: Brian Cassidy <bricas@cpan.org>
315
3d7e3e05 316brunov: Bruno Vecchi <vecchi.b@gmail.com>
317
281719d2 318caelum: Rafael Kitover <rkitover@cpan.org>
319
f5f2af8f 320caldrin: Maik Hentsche <maik.hentsche@amd.com>
321
d3b0e369 322castaway: Jess Robinson
3942ab4d 323
266bdcc3 324claco: Christopher H. Laco
ccb9c9b1 325
266bdcc3 326clkao: CL Kao
3942ab4d 327
e21dfd6a 328da5id: David Jack Olrik <djo@cpan.org>
18360aed 329
13de943d 330debolaz: Anders Nor Berle <berle@cpan.org>
331
d1f542db 332dew: Dan Thomas <dan@godders.org>
333
266bdcc3 334dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 335
9382ad07 336dnm: Justin Wheeler <jwheeler@datademons.com>
337
0818c9a7 338dpetrov: Dimitar Petrov <mitakaa@gmail.com>
339
266bdcc3 340dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 341
5cffe785 342dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 343
7b71391b 344edenc: Eden Cardim <edencardim@gmail.com>
345
307f1265 346felliott: Fitz Elliott <fitz.elliott@gmail.com>
347
0ffada27 348freetime: Bill Moseley <moseley@hank.org>
349
ade0fe3b 350frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
351
b4987ed0 352goraxe: Gordon Irving <goraxe@cpan.org>
353
d3b0e369 354gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 355
61f031bf 356Grant Street Group L<http://www.grantstreet.com/>
357
e758ffe6 358groditi: Guillermo Roditi <groditi@cpan.org>
359
6dad89f5 360Haarg: Graham Knop <haarg@haarg.org>
361
157ce0cf 362hobbs: Andrew Rodland <arodland@cpan.org>
363
5d779578 364ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
365
0ac0af6c 366initself: Mike Baas <mike@initselftech.com>
367
2bb4c37b 368ironcamel: Naveed Massjouni <naveedm9@gmail.com>
369
f165eda8 370jawnsy: Jonathan Yu <jawnsy@cpan.org>
371
bee21976 372jasonmay: Jason May <jason.a.may@gmail.com>
373
d3b0e369 374jesper: Jesper Krogh
5fb0c64c 375
4a743a00 376jgoulah: John Goulah <jgoulah@cpan.org>
377
102a2984 378jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 379
a14a46e2 380jhannah: Jay Hannah <jay@jays.net>
381
8b93a938 382jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
383
11736b4c 384jon: Jon Schutz <jjschutz@cpan.org>
385
1aec4bac 386jshirley: J. Shirley <jshirley@gmail.com>
387
41519379 388kaare: Kaare Rasmussen
389
d3b0e369 390konobi: Scott McWhirter
535fc2ee 391
4e0a89e4 392littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
393
4367679a 394lukes: Luke Saunders <luke.saunders@gmail.com>
395
709ea492 396marcus: Marcus Ramberg <mramberg@cpan.org>
397
114780ee 398mattlaw: Matt Lawrence
399
45bffdf0 400mattp: Matt Phillips <mattp@cpan.org>
401
58755bba 402michaelr: Michael Reddick <michael.reddick@gmail.com>
403
91d0c99f 404milki: Jonathan Chu <milki@rescomp.berkeley.edu>
405
167e7634 406mstratman: Mark A. Stratman <stratman@gmail.com>
407
77e7e47d 408ned: Neil de Carteret
409
266bdcc3 410nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 411
d3b0e369 412ningu: David Kamholz <dkamholz@cpan.org>
413
66cf3a84 414Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
415
20b4c148 416norbi: Norbert Buchmuller <norbi@nix.hu>
417
48580715 418nuba: Nuba Princigalli <nuba@cpan.org>
419
d3b0e369 420Numa: Dan Sully <daniel@cpan.org>
421
dc571b76 422ovid: Curtis "Ovid" Poe <ovid@cpan.org>
423
6c30f9c3 424oyse: E<Oslash>ystein Torget <oystein.torget@dnv.com>
bf356c54 425
266bdcc3 426paulm: Paul Makepeace
4763f4b7 427
d3b0e369 428penguin: K J Cheetham
429
8cfef6f5 430perigrin: Chris Prather <chris@prather.org>
431
14899528 432peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 433
6c30f9c3 434Peter Valdemar ME<oslash>rch <peter@morch.com>
435
266bdcc3 436phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 437
56fadd8f 438plu: Johannes Plunien <plu@cpan.org>
439
0c1a4a15 440Possum: Daniel LeWarne <possum@cpan.org>
441
d3b0e369 442quicksilver: Jules Bean
022e0893 443
4ed01b34 444rafl: Florian Ragwitz <rafl@debian.org>
445
0c1a4a15 446rainboxx: Matthias Dietrich <perl@rb.ly>
447
868a7b26 448rbo: Robert Bohne <rbo@cpan.org>
449
7ff0dace 450rbuels: Robert Buels <rmb32@cornell.edu>
451
0da8b7da 452rdj: Ryan D Johnson <ryan@innerfence.com>
453
66b1e361 454ribasushi: Peter Rabbitson <ribasushi@cpan.org>
d76e282a 455
b487918c 456rjbs: Ricardo Signes <rjbs@cpan.org>
457
6ffb5be5 458robkinyon: Rob Kinyon <rkinyon@cpan.org>
459
726c8f65 460Robert Olson <bob@rdolson.org>
461
e4c9f3f0 462Roman: Roman Filippov <romanf@cpan.org>
463
dc81dba3 464Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
465
d3b0e369 466sc_: Just Another Perl Hacker
ba606e58 467
266bdcc3 468scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 469
1c133e22 470semifor: Marc Mims <marc@questright.com>
471
16667b3a 472SineSwiper: Brendan Byrd <bbyrd@cpan.org>
473
20b4c148 474solomon: Jared Johnson <jaredj@nmgi.com>
475
88f937fb 476spb: Stephen Bennett <stephen@freenode.net>
477
59187a3b 478Squeeks <squeek@cpan.org>
479
637ca936 480sszabo: Stephan Szabo <sszabo@bigpanda.com>
481
a9e8284f 482talexb: Alex Beamish <talexb@gmail.com>
483
7bf0d0d6 484tamias: Ronald J Kimball <rjk@tamias.net>
f92a9d79 485
386c2272 486teejay : Aaron Trevena <teejay@cpan.org>
487
84e3c114 488Todd Lipcon
e063fe2c 489
6eb6264e 490Tom Hukins
491
2e4b6d78 492tonvoon: Ton Voon <tonvoon@cpan.org>
493
d15e3fc5 494triode: Pete Gamache <gamache@cpan.org>
495
d3b0e369 496typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 497
4740bdb7 498victori: Victor Igumnov <victori@cpan.org>
499
d3b0e369 500wdh: Will Hawes
4c248161 501
124162a0 502wesm: Wes Malone <wes@mitsi.com>
503
00c03ced 504willert: Sebastian Willert <willert@cpan.org>
505
66d2a14e 506wreis: Wallace Reis <wreis@cpan.org>
507
d7c37d66 508xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
509
d52d4d6e 510yrlnry: Mark Jason Dominus <mjd@plover.com>
511
d3b0e369 512zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 513
b38e10bd 514=head1 COPYRIGHT
515
16be93fe 516Copyright (c) 2005 - 2011 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
b38e10bd 517as listed above.
518
96154ef7 519=head1 LICENSE
520
521This library is free software and may be distributed under the same terms
522as perl itself.
523
34d52be2 524=cut