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