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