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