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