Merge 'trunk' into 'sybase_support'
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
CommitLineData
ea2e61bf 1package DBIx::Class;
2
5d283305 3use strict;
4use warnings;
5
329d7385 6use MRO::Compat;
7
5d283305 8use vars qw($VERSION);
48a76fcf 9use base qw/Class::C3::Componentised Class::Accessor::Grouped/;
11736b4c 10use DBIx::Class::StartupCheck;
3e110410 11
ade0fe3b 12sub mk_classdata {
77d518d1 13 shift->mk_classaccessor(@_);
14}
15
16sub mk_classaccessor {
17 my $self = shift;
ade0fe3b 18 $self->mk_group_accessors('inherited', $_[0]);
77d518d1 19 $self->set_inherited(@_) if @_ > 1;
3e110410 20}
3c0068c1 21
7411204b 22sub component_base_class { 'DBIx::Class' }
227d4dee 23
95da6f35 24# Always remember to do all digits for the version even if they're 0
25# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
26# brain damage and presumably various other packaging systems too
51845f96 27$VERSION = '0.08112';
748ab0dc 28
29$VERSION = eval $VERSION; # numify for warning-free dev releases
b8777a0d 30
f0750722 31sub MODIFY_CODE_ATTRIBUTES {
b5d2c57f 32 my ($class,$code,@attrs) = @_;
33 $class->mk_classdata('__attr_cache' => {})
34 unless $class->can('__attr_cache');
35 $class->__attr_cache->{$code} = [@attrs];
36 return ();
f0750722 37}
38
da95b45f 39sub _attr_cache {
b5d2c57f 40 my $self = shift;
41 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
42 my $rest = eval { $self->next::method };
43 return $@ ? $cache : { %$cache, %$rest };
da95b45f 44}
45
b561bb6f 46# Pretty printer for debug messages
47sub _pretty_print {
48
49 require Data::Dumper;
50 local $Data::Dumper::Terse = 1;
51 local $Data::Dumper::Indent = 1;
52 local $Data::Dumper::Useqq = 1;
53 local $Data::Dumper::Quotekeys = 0;
54 local $Data::Dumper::Sortkeys = 1;
55
56 return Data::Dumper::Dumper ($_[1]);
57}
58
ea2e61bf 591;
34d52be2 60
75d07914 61=head1 NAME
34d52be2 62
7e4b2f59 63DBIx::Class - Extensible and flexible object <-> relational mapper.
34d52be2 64
3b1c2bbd 65=head1 GETTING HELP/SUPPORT
66
67The community can be found via:
68
69 Mailing list: http://lists.scsys.co.uk/mailman/listinfo/dbix-class/
70
71 SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
72
73 SVNWeb: http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/
74
75 IRC: irc.perl.org#dbix-class
76
34d52be2 77=head1 SYNOPSIS
78
bd077b47 79Create a schema class called MyDB/Schema.pm:
34d52be2 80
bd077b47 81 package MyDB::Schema;
a0638a7b 82 use base qw/DBIx::Class::Schema/;
34d52be2 83
f0bb26f3 84 __PACKAGE__->load_namespaces();
daec44b8 85
a0638a7b 86 1;
daec44b8 87
30e1753a 88Create a result class to represent artists, who have many CDs, in
f0bb26f3 89MyDB/Schema/Result/Artist.pm:
daec44b8 90
30e1753a 91See L<DBIx::Class::ResultSource> for docs on defining result classes.
92
f0bb26f3 93 package MyDB::Schema::Result::Artist;
a0638a7b 94 use base qw/DBIx::Class/;
daec44b8 95
bd077b47 96 __PACKAGE__->load_components(qw/Core/);
a0638a7b 97 __PACKAGE__->table('artist');
98 __PACKAGE__->add_columns(qw/ artistid name /);
99 __PACKAGE__->set_primary_key('artistid');
f0bb26f3 100 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
daec44b8 101
a0638a7b 102 1;
daec44b8 103
30e1753a 104A result class to represent a CD, which belongs to an artist, in
f0bb26f3 105MyDB/Schema/Result/CD.pm:
39fe0e65 106
f0bb26f3 107 package MyDB::Schema::Result::CD;
a0638a7b 108 use base qw/DBIx::Class/;
39fe0e65 109
bd077b47 110 __PACKAGE__->load_components(qw/Core/);
a0638a7b 111 __PACKAGE__->table('cd');
bd077b47 112 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
a0638a7b 113 __PACKAGE__->set_primary_key('cdid');
bd077b47 114 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
39fe0e65 115
a0638a7b 116 1;
39fe0e65 117
a0638a7b 118Then you can use these classes in your application's code:
39fe0e65 119
a0638a7b 120 # Connect to your database.
bd077b47 121 use MyDB::Schema;
122 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
a0638a7b 123
124 # Query for all artists and put them in an array,
125 # or retrieve them as a result set object.
30e1753a 126 # $schema->resultset returns a DBIx::Class::ResultSet
2053ab2a 127 my @all_artists = $schema->resultset('Artist')->all;
128 my $all_artists_rs = $schema->resultset('Artist');
126042ee 129
30e1753a 130 # Output all artists names
131 # $artist here is a DBIx::Class::Row, which has accessors
16ccb4fe 132 # for all its columns. Rows are also subclasses of your Result class.
30e1753a 133 foreach $artist (@artists) {
134 print $artist->name, "\n";
135 }
136
a0638a7b 137 # Create a result set to search for artists.
86beca1d 138 # This does not query the DB.
2053ab2a 139 my $johns_rs = $schema->resultset('Artist')->search(
6576ef54 140 # Build your WHERE using an SQL::Abstract structure:
2053ab2a 141 { name => { like => 'John%' } }
a0638a7b 142 );
39fe0e65 143
2053ab2a 144 # Execute a joined query to get the cds.
a0638a7b 145 my @all_john_cds = $johns_rs->search_related('cds')->all;
448c8424 146
f0bb26f3 147 # Fetch the next available row.
a0638a7b 148 my $first_john = $johns_rs->next;
448c8424 149
2053ab2a 150 # Specify ORDER BY on the query.
a0638a7b 151 my $first_john_cds_by_title_rs = $first_john->cds(
152 undef,
153 { order_by => 'title' }
154 );
448c8424 155
bd077b47 156 # Create a result set that will fetch the artist data
2053ab2a 157 # at the same time as it fetches CDs, using only one query.
884559b1 158 my $millennium_cds_rs = $schema->resultset('CD')->search(
a0638a7b 159 { year => 2000 },
160 { prefetch => 'artist' }
161 );
448c8424 162
880a1a0c 163 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
bd077b47 164 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
076652e8 165
264f1571 166 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
167 # create() is the same as new() then insert().
884559b1 168 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
f183eccd 169 $new_cd->artist($cd->artist);
f183eccd 170 $new_cd->insert; # Auto-increment primary key filled in after INSERT
f183eccd 171 $new_cd->title('Fork');
172
884559b1 173 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
f183eccd 174
bd077b47 175 # change the year of all the millennium CDs at once
176 $millennium_cds_rs->update({ year => 2002 });
f183eccd 177
178=head1 DESCRIPTION
179
180This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
bd077b47 181(with a compatibility layer as a springboard for porting) and a resultset API
f183eccd 182that allows abstract encapsulation of database operations. It aims to make
183representing queries in your code as perl-ish as possible while still
a0638a7b 184providing access to as many of the capabilities of the database as possible,
f183eccd 185including retrieving related records from multiple tables in a single query,
bd077b47 186JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
f183eccd 187
188DBIx::Class can handle multi-column primary and foreign keys, complex
189queries and database-level paging, and does its best to only query the
75d07914 190database in order to return something you've directly asked for. If a
191resultset is used as an iterator it only fetches rows off the statement
192handle as requested in order to minimise memory usage. It has auto-increment
2053ab2a 193support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
194known to be used in production on at least the first four, and is fork-
75d07914 195and thread-safe out of the box (although your DBD may not be).
f183eccd 196
dfccde48 197This project is still under rapid development, so large new features may be
198marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
199Failing test cases are *always* welcome and point releases are put out rapidly
200as bugs are found and fixed.
201
202We do our best to maintain full backwards compatibility for published
203APIs, since DBIx::Class is used in production in many organisations,
204and even backwards incompatible changes to non-published APIs will be fixed
205if they're reported and doing so doesn't cost the codebase anything.
206
264f1571 207The test suite is quite substantial, and several developer releases
208are generally made to CPAN before the branch for the next release is
209merged back to trunk for a major release.
f183eccd 210
f183eccd 211=head1 WHERE TO GO NEXT
212
2ca930b4 213L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
214the modules where you will find documentation.
076652e8 215
3942ab4d 216=head1 AUTHOR
34d52be2 217
266bdcc3 218mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 219
dfccde48 220(I mostly consider myself "project founder" these days but the AUTHOR heading
221is traditional :)
222
3942ab4d 223=head1 CONTRIBUTORS
224
266bdcc3 225abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
84e3c114 226
6d84db2c 227aherzog: Adam Herzog <adam@herzogdesigns.com>
228
266bdcc3 229andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 230
266bdcc3 231ank: Andres Kievsky
3942ab4d 232
624764ae 233arcanez: Justin Hunter <justin.d.hunter@gmail.com>
234
ce4c07df 235ash: Ash Berlin <ash@cpan.org>
236
3d5bd2af 237bert: Norbert Csongradi <bert@cpan.org>
238
967a4c40 239blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 240
62eb8fe8 241bluefeet: Aran Deltac <bluefeet@cpan.org>
242
bcb8f3ed 243bricas: Brian Cassidy <bricas@cpan.org>
244
3d7e3e05 245brunov: Bruno Vecchi <vecchi.b@gmail.com>
246
281719d2 247caelum: Rafael Kitover <rkitover@cpan.org>
248
d3b0e369 249castaway: Jess Robinson
3942ab4d 250
266bdcc3 251claco: Christopher H. Laco
ccb9c9b1 252
266bdcc3 253clkao: CL Kao
3942ab4d 254
e21dfd6a 255da5id: David Jack Olrik <djo@cpan.org>
18360aed 256
13de943d 257debolaz: Anders Nor Berle <berle@cpan.org>
258
266bdcc3 259dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 260
9382ad07 261dnm: Justin Wheeler <jwheeler@datademons.com>
262
266bdcc3 263dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 264
5cffe785 265dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 266
ade0fe3b 267frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
268
d3b0e369 269gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 270
e758ffe6 271groditi: Guillermo Roditi <groditi@cpan.org>
272
5d779578 273ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
274
bee21976 275jasonmay: Jason May <jason.a.may@gmail.com>
276
d3b0e369 277jesper: Jesper Krogh
5fb0c64c 278
4a743a00 279jgoulah: John Goulah <jgoulah@cpan.org>
280
102a2984 281jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 282
8b93a938 283jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
284
11736b4c 285jon: Jon Schutz <jjschutz@cpan.org>
286
1aec4bac 287jshirley: J. Shirley <jshirley@gmail.com>
288
d3b0e369 289konobi: Scott McWhirter
535fc2ee 290
4367679a 291lukes: Luke Saunders <luke.saunders@gmail.com>
292
709ea492 293marcus: Marcus Ramberg <mramberg@cpan.org>
294
114780ee 295mattlaw: Matt Lawrence
296
58755bba 297michaelr: Michael Reddick <michael.reddick@gmail.com>
298
77e7e47d 299ned: Neil de Carteret
300
266bdcc3 301nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 302
d3b0e369 303ningu: David Kamholz <dkamholz@cpan.org>
304
66cf3a84 305Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
306
20b4c148 307norbi: Norbert Buchmuller <norbi@nix.hu>
308
d3b0e369 309Numa: Dan Sully <daniel@cpan.org>
310
bf356c54 311oyse: Øystein Torget <oystein.torget@dnv.com>
312
266bdcc3 313paulm: Paul Makepeace
4763f4b7 314
d3b0e369 315penguin: K J Cheetham
316
8cfef6f5 317perigrin: Chris Prather <chris@prather.org>
318
14899528 319peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 320
266bdcc3 321phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 322
56fadd8f 323plu: Johannes Plunien <plu@cpan.org>
324
d3b0e369 325quicksilver: Jules Bean
022e0893 326
4ed01b34 327rafl: Florian Ragwitz <rafl@debian.org>
328
7ff0dace 329rbuels: Robert Buels <rmb32@cornell.edu>
330
0da8b7da 331rdj: Ryan D Johnson <ryan@innerfence.com>
332
28ad4c43 333ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
d76e282a 334
b487918c 335rjbs: Ricardo Signes <rjbs@cpan.org>
336
6ffb5be5 337robkinyon: Rob Kinyon <rkinyon@cpan.org>
338
d3b0e369 339sc_: Just Another Perl Hacker
ba606e58 340
266bdcc3 341scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 342
1c133e22 343semifor: Marc Mims <marc@questright.com>
344
20b4c148 345solomon: Jared Johnson <jaredj@nmgi.com>
346
88f937fb 347spb: Stephen Bennett <stephen@freenode.net>
348
637ca936 349sszabo: Stephan Szabo <sszabo@bigpanda.com>
350
386c2272 351teejay : Aaron Trevena <teejay@cpan.org>
352
84e3c114 353Todd Lipcon
e063fe2c 354
6eb6264e 355Tom Hukins
356
d3b0e369 357typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 358
4740bdb7 359victori: Victor Igumnov <victori@cpan.org>
360
d3b0e369 361wdh: Will Hawes
4c248161 362
00c03ced 363willert: Sebastian Willert <willert@cpan.org>
364
66d2a14e 365wreis: Wallace Reis <wreis@cpan.org>
366
d3b0e369 367zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 368
b38e10bd 369=head1 COPYRIGHT
370
371Copyright (c) 2005 - 2009 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
372as listed above.
373
96154ef7 374=head1 LICENSE
375
376This library is free software and may be distributed under the same terms
377as perl itself.
378
34d52be2 379=cut