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