Cleanup C3 handling, require updated Class::C3::Componentised
[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);
d38cd95c 22use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
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
bee21976 321jasonmay: Jason May <jason.a.may@gmail.com>
322
d3b0e369 323jesper: Jesper Krogh
5fb0c64c 324
4a743a00 325jgoulah: John Goulah <jgoulah@cpan.org>
326
102a2984 327jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 328
a14a46e2 329jhannah: Jay Hannah <jay@jays.net>
330
8b93a938 331jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
332
11736b4c 333jon: Jon Schutz <jjschutz@cpan.org>
334
1aec4bac 335jshirley: J. Shirley <jshirley@gmail.com>
336
41519379 337kaare: Kaare Rasmussen
338
d3b0e369 339konobi: Scott McWhirter
535fc2ee 340
4e0a89e4 341littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
342
4367679a 343lukes: Luke Saunders <luke.saunders@gmail.com>
344
709ea492 345marcus: Marcus Ramberg <mramberg@cpan.org>
346
114780ee 347mattlaw: Matt Lawrence
348
58755bba 349michaelr: Michael Reddick <michael.reddick@gmail.com>
350
91d0c99f 351milki: Jonathan Chu <milki@rescomp.berkeley.edu>
352
77e7e47d 353ned: Neil de Carteret
354
266bdcc3 355nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 356
d3b0e369 357ningu: David Kamholz <dkamholz@cpan.org>
358
66cf3a84 359Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
360
20b4c148 361norbi: Norbert Buchmuller <norbi@nix.hu>
362
48580715 363nuba: Nuba Princigalli <nuba@cpan.org>
364
d3b0e369 365Numa: Dan Sully <daniel@cpan.org>
366
dc571b76 367ovid: Curtis "Ovid" Poe <ovid@cpan.org>
368
bf356c54 369oyse: Øystein Torget <oystein.torget@dnv.com>
370
266bdcc3 371paulm: Paul Makepeace
4763f4b7 372
d3b0e369 373penguin: K J Cheetham
374
8cfef6f5 375perigrin: Chris Prather <chris@prather.org>
376
14899528 377peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 378
266bdcc3 379phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 380
56fadd8f 381plu: Johannes Plunien <plu@cpan.org>
382
0c1a4a15 383Possum: Daniel LeWarne <possum@cpan.org>
384
d3b0e369 385quicksilver: Jules Bean
022e0893 386
4ed01b34 387rafl: Florian Ragwitz <rafl@debian.org>
388
0c1a4a15 389rainboxx: Matthias Dietrich <perl@rb.ly>
390
868a7b26 391rbo: Robert Bohne <rbo@cpan.org>
392
7ff0dace 393rbuels: Robert Buels <rmb32@cornell.edu>
394
0da8b7da 395rdj: Ryan D Johnson <ryan@innerfence.com>
396
66b1e361 397ribasushi: Peter Rabbitson <ribasushi@cpan.org>
d76e282a 398
b487918c 399rjbs: Ricardo Signes <rjbs@cpan.org>
400
6ffb5be5 401robkinyon: Rob Kinyon <rkinyon@cpan.org>
402
e4c9f3f0 403Roman: Roman Filippov <romanf@cpan.org>
404
dc81dba3 405Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
406
d3b0e369 407sc_: Just Another Perl Hacker
ba606e58 408
266bdcc3 409scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 410
1c133e22 411semifor: Marc Mims <marc@questright.com>
412
20b4c148 413solomon: Jared Johnson <jaredj@nmgi.com>
414
88f937fb 415spb: Stephen Bennett <stephen@freenode.net>
416
59187a3b 417Squeeks <squeek@cpan.org>
418
637ca936 419sszabo: Stephan Szabo <sszabo@bigpanda.com>
420
a9e8284f 421talexb: Alex Beamish <talexb@gmail.com>
422
7bf0d0d6 423tamias: Ronald J Kimball <rjk@tamias.net>
f92a9d79 424
386c2272 425teejay : Aaron Trevena <teejay@cpan.org>
426
84e3c114 427Todd Lipcon
e063fe2c 428
6eb6264e 429Tom Hukins
430
2e4b6d78 431tonvoon: Ton Voon <tonvoon@cpan.org>
432
d15e3fc5 433triode: Pete Gamache <gamache@cpan.org>
434
d3b0e369 435typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 436
4740bdb7 437victori: Victor Igumnov <victori@cpan.org>
438
d3b0e369 439wdh: Will Hawes
4c248161 440
00c03ced 441willert: Sebastian Willert <willert@cpan.org>
442
66d2a14e 443wreis: Wallace Reis <wreis@cpan.org>
444
d52d4d6e 445yrlnry: Mark Jason Dominus <mjd@plover.com>
446
d3b0e369 447zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 448
b38e10bd 449=head1 COPYRIGHT
450
48580715 451Copyright (c) 2005 - 2010 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
b38e10bd 452as listed above.
453
96154ef7 454=head1 LICENSE
455
456This library is free software and may be distributed under the same terms
457as perl itself.
458
34d52be2 459=cut