use more correct subsection links in POD
[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
30cfb462 14$VERSION = '0.08196';
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');
386c61f6 74__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped$');
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
307f1265 351felliott: Fitz Elliott <fitz.elliott@gmail.com>
352
0ffada27 353freetime: Bill Moseley <moseley@hank.org>
354
ade0fe3b 355frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
356
b4987ed0 357goraxe: Gordon Irving <goraxe@cpan.org>
358
d3b0e369 359gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 360
61f031bf 361Grant Street Group L<http://www.grantstreet.com/>
362
e758ffe6 363groditi: Guillermo Roditi <groditi@cpan.org>
364
6dad89f5 365Haarg: Graham Knop <haarg@haarg.org>
366
157ce0cf 367hobbs: Andrew Rodland <arodland@cpan.org>
368
5d779578 369ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
370
0ac0af6c 371initself: Mike Baas <mike@initselftech.com>
372
2bb4c37b 373ironcamel: Naveed Massjouni <naveedm9@gmail.com>
374
f165eda8 375jawnsy: Jonathan Yu <jawnsy@cpan.org>
376
bee21976 377jasonmay: Jason May <jason.a.may@gmail.com>
378
d3b0e369 379jesper: Jesper Krogh
5fb0c64c 380
4a743a00 381jgoulah: John Goulah <jgoulah@cpan.org>
382
102a2984 383jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 384
a14a46e2 385jhannah: Jay Hannah <jay@jays.net>
386
8b93a938 387jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
388
11736b4c 389jon: Jon Schutz <jjschutz@cpan.org>
390
1aec4bac 391jshirley: J. Shirley <jshirley@gmail.com>
392
41519379 393kaare: Kaare Rasmussen
394
d3b0e369 395konobi: Scott McWhirter
535fc2ee 396
4e0a89e4 397littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
398
4367679a 399lukes: Luke Saunders <luke.saunders@gmail.com>
400
709ea492 401marcus: Marcus Ramberg <mramberg@cpan.org>
402
114780ee 403mattlaw: Matt Lawrence
404
45bffdf0 405mattp: Matt Phillips <mattp@cpan.org>
406
58755bba 407michaelr: Michael Reddick <michael.reddick@gmail.com>
408
91d0c99f 409milki: Jonathan Chu <milki@rescomp.berkeley.edu>
410
167e7634 411mstratman: Mark A. Stratman <stratman@gmail.com>
412
77e7e47d 413ned: Neil de Carteret
414
266bdcc3 415nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 416
d3b0e369 417ningu: David Kamholz <dkamholz@cpan.org>
418
66cf3a84 419Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
420
20b4c148 421norbi: Norbert Buchmuller <norbi@nix.hu>
422
48580715 423nuba: Nuba Princigalli <nuba@cpan.org>
424
d3b0e369 425Numa: Dan Sully <daniel@cpan.org>
426
dc571b76 427ovid: Curtis "Ovid" Poe <ovid@cpan.org>
428
6c30f9c3 429oyse: E<Oslash>ystein Torget <oystein.torget@dnv.com>
bf356c54 430
266bdcc3 431paulm: Paul Makepeace
4763f4b7 432
d3b0e369 433penguin: K J Cheetham
434
8cfef6f5 435perigrin: Chris Prather <chris@prather.org>
436
14899528 437peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 438
6c30f9c3 439Peter Valdemar ME<oslash>rch <peter@morch.com>
440
266bdcc3 441phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 442
56fadd8f 443plu: Johannes Plunien <plu@cpan.org>
444
0c1a4a15 445Possum: Daniel LeWarne <possum@cpan.org>
446
d3b0e369 447quicksilver: Jules Bean
022e0893 448
4ed01b34 449rafl: Florian Ragwitz <rafl@debian.org>
450
0c1a4a15 451rainboxx: Matthias Dietrich <perl@rb.ly>
452
868a7b26 453rbo: Robert Bohne <rbo@cpan.org>
454
7ff0dace 455rbuels: Robert Buels <rmb32@cornell.edu>
456
0da8b7da 457rdj: Ryan D Johnson <ryan@innerfence.com>
458
66b1e361 459ribasushi: Peter Rabbitson <ribasushi@cpan.org>
d76e282a 460
b487918c 461rjbs: Ricardo Signes <rjbs@cpan.org>
462
6ffb5be5 463robkinyon: Rob Kinyon <rkinyon@cpan.org>
464
726c8f65 465Robert Olson <bob@rdolson.org>
466
e4c9f3f0 467Roman: Roman Filippov <romanf@cpan.org>
468
dc81dba3 469Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
470
d3b0e369 471sc_: Just Another Perl Hacker
ba606e58 472
266bdcc3 473scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 474
1c133e22 475semifor: Marc Mims <marc@questright.com>
476
20b4c148 477solomon: Jared Johnson <jaredj@nmgi.com>
478
88f937fb 479spb: Stephen Bennett <stephen@freenode.net>
480
59187a3b 481Squeeks <squeek@cpan.org>
482
637ca936 483sszabo: Stephan Szabo <sszabo@bigpanda.com>
484
a9e8284f 485talexb: Alex Beamish <talexb@gmail.com>
486
7bf0d0d6 487tamias: Ronald J Kimball <rjk@tamias.net>
f92a9d79 488
386c2272 489teejay : Aaron Trevena <teejay@cpan.org>
490
84e3c114 491Todd Lipcon
e063fe2c 492
6eb6264e 493Tom Hukins
494
2e4b6d78 495tonvoon: Ton Voon <tonvoon@cpan.org>
496
d15e3fc5 497triode: Pete Gamache <gamache@cpan.org>
498
d3b0e369 499typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 500
4740bdb7 501victori: Victor Igumnov <victori@cpan.org>
502
d3b0e369 503wdh: Will Hawes
4c248161 504
00c03ced 505willert: Sebastian Willert <willert@cpan.org>
506
66d2a14e 507wreis: Wallace Reis <wreis@cpan.org>
508
d52d4d6e 509yrlnry: Mark Jason Dominus <mjd@plover.com>
510
d3b0e369 511zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 512
b38e10bd 513=head1 COPYRIGHT
514
16be93fe 515Copyright (c) 2005 - 2011 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
b38e10bd 516as listed above.
517
96154ef7 518=head1 LICENSE
519
520This library is free software and may be distributed under the same terms
521as perl itself.
522
34d52be2 523=cut