9 use base qw/Class::C3::Componentised Class::Accessor::Grouped/;
10 use DBIx::Class::StartupCheck;
13 shift->mk_classaccessor(@_);
16 sub mk_classaccessor {
18 $self->mk_group_accessors('inherited', $_[0]);
19 $self->set_inherited(@_) if @_ > 1;
22 sub component_base_class { 'DBIx::Class' }
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
29 $VERSION = eval $VERSION; # numify for warning-free dev releases
31 sub MODIFY_CODE_ATTRIBUTES {
32 my ($class,$code,@attrs) = @_;
33 $class->mk_classdata('__attr_cache' => {})
34 unless $class->can('__attr_cache');
35 $class->__attr_cache->{$code} = [@attrs];
41 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
42 my $rest = eval { $self->next::method };
43 return $@ ? $cache : { %$cache, %$rest };
46 # Pretty printer for debug messages
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;
56 return Data::Dumper::Dumper ($_[1]);
63 DBIx::Class - Extensible and flexible object <-> relational mapper.
65 =head1 GETTING HELP/SUPPORT
67 The community can be found via:
69 Mailing list: http://lists.scsys.co.uk/mailman/listinfo/dbix-class/
71 SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
73 SVNWeb: http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/
75 IRC: irc.perl.org#dbix-class
79 Create a schema class called MyDB/Schema.pm:
82 use base qw/DBIx::Class::Schema/;
84 __PACKAGE__->load_namespaces();
88 Create a result class to represent artists, who have many CDs, in
89 MyDB/Schema/Result/Artist.pm:
91 See L<DBIx::Class::ResultSource> for docs on defining result classes.
93 package MyDB::Schema::Result::Artist;
94 use base qw/DBIx::Class/;
96 __PACKAGE__->load_components(qw/Core/);
97 __PACKAGE__->table('artist');
98 __PACKAGE__->add_columns(qw/ artistid name /);
99 __PACKAGE__->set_primary_key('artistid');
100 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
104 A result class to represent a CD, which belongs to an artist, in
105 MyDB/Schema/Result/CD.pm:
107 package MyDB::Schema::Result::CD;
108 use base qw/DBIx::Class/;
110 __PACKAGE__->load_components(qw/Core/);
111 __PACKAGE__->table('cd');
112 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
113 __PACKAGE__->set_primary_key('cdid');
114 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
118 Then you can use these classes in your application's code:
120 # Connect to your database.
122 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
124 # Query for all artists and put them in an array,
125 # or retrieve them as a result set object.
126 # $schema->resultset returns a DBIx::Class::ResultSet
127 my @all_artists = $schema->resultset('Artist')->all;
128 my $all_artists_rs = $schema->resultset('Artist');
130 # Output all artists names
131 # $artist here is a DBIx::Class::Row, which has accessors
132 # for all its columns. Rows are also subclasses of your Result class.
133 foreach $artist (@artists) {
134 print $artist->name, "\n";
137 # Create a result set to search for artists.
138 # This does not query the DB.
139 my $johns_rs = $schema->resultset('Artist')->search(
140 # Build your WHERE using an SQL::Abstract structure:
141 { name => { like => 'John%' } }
144 # Execute a joined query to get the cds.
145 my @all_john_cds = $johns_rs->search_related('cds')->all;
147 # Fetch the next available row.
148 my $first_john = $johns_rs->next;
150 # Specify ORDER BY on the query.
151 my $first_john_cds_by_title_rs = $first_john->cds(
153 { order_by => 'title' }
156 # Create a result set that will fetch the artist data
157 # at the same time as it fetches CDs, using only one query.
158 my $millennium_cds_rs = $schema->resultset('CD')->search(
160 { prefetch => 'artist' }
163 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
164 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
166 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
167 # create() is the same as new() then insert().
168 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
169 $new_cd->artist($cd->artist);
170 $new_cd->insert; # Auto-increment primary key filled in after INSERT
171 $new_cd->title('Fork');
173 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
175 # change the year of all the millennium CDs at once
176 $millennium_cds_rs->update({ year => 2002 });
180 This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
181 (with a compatibility layer as a springboard for porting) and a resultset API
182 that allows abstract encapsulation of database operations. It aims to make
183 representing queries in your code as perl-ish as possible while still
184 providing access to as many of the capabilities of the database as possible,
185 including retrieving related records from multiple tables in a single query,
186 JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
188 DBIx::Class can handle multi-column primary and foreign keys, complex
189 queries and database-level paging, and does its best to only query the
190 database in order to return something you've directly asked for. If a
191 resultset is used as an iterator it only fetches rows off the statement
192 handle as requested in order to minimise memory usage. It has auto-increment
193 support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
194 known to be used in production on at least the first four, and is fork-
195 and thread-safe out of the box (although your DBD may not be).
197 This project is still under rapid development, so large new features may be
198 marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
199 Failing test cases are *always* welcome and point releases are put out rapidly
200 as bugs are found and fixed.
202 We do our best to maintain full backwards compatibility for published
203 APIs, since DBIx::Class is used in production in many organisations,
204 and even backwards incompatible changes to non-published APIs will be fixed
205 if they're reported and doing so doesn't cost the codebase anything.
207 The test suite is quite substantial, and several developer releases
208 are generally made to CPAN before the branch for the next release is
209 merged back to trunk for a major release.
211 =head1 WHERE TO GO NEXT
213 L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
214 the modules where you will find documentation.
218 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
220 (I mostly consider myself "project founder" these days but the AUTHOR heading
225 abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
227 aherzog: Adam Herzog <adam@herzogdesigns.com>
229 andyg: Andy Grundman <andy@hybridized.org>
233 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
235 ash: Ash Berlin <ash@cpan.org>
237 bert: Norbert Csongradi <bert@cpan.org>
239 blblack: Brandon L. Black <blblack@gmail.com>
241 bluefeet: Aran Deltac <bluefeet@cpan.org>
243 bricas: Brian Cassidy <bricas@cpan.org>
245 brunov: Bruno Vecchi <vecchi.b@gmail.com>
247 caelum: Rafael Kitover <rkitover@cpan.org>
249 castaway: Jess Robinson
251 claco: Christopher H. Laco
255 da5id: David Jack Olrik <djo@cpan.org>
257 debolaz: Anders Nor Berle <berle@cpan.org>
259 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
261 dnm: Justin Wheeler <jwheeler@datademons.com>
263 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
265 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
267 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
269 gphat: Cory G Watson <gphat@cpan.org>
271 groditi: Guillermo Roditi <groditi@cpan.org>
273 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
275 jasonmay: Jason May <jason.a.may@gmail.com>
279 jgoulah: John Goulah <jgoulah@cpan.org>
281 jguenther: Justin Guenther <jguenther@cpan.org>
283 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
285 jon: Jon Schutz <jjschutz@cpan.org>
287 jshirley: J. Shirley <jshirley@gmail.com>
289 konobi: Scott McWhirter
291 lukes: Luke Saunders <luke.saunders@gmail.com>
293 marcus: Marcus Ramberg <mramberg@cpan.org>
295 mattlaw: Matt Lawrence
297 michaelr: Michael Reddick <michael.reddick@gmail.com>
299 ned: Neil de Carteret
301 nigel: Nigel Metheringham <nigelm@cpan.org>
303 ningu: David Kamholz <dkamholz@cpan.org>
305 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
307 norbi: Norbert Buchmuller <norbi@nix.hu>
309 Numa: Dan Sully <daniel@cpan.org>
311 oyse: Øystein Torget <oystein.torget@dnv.com>
313 paulm: Paul Makepeace
315 penguin: K J Cheetham
317 perigrin: Chris Prather <chris@prather.org>
319 peter: Peter Collingbourne <peter@pcc.me.uk>
321 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
323 plu: Johannes Plunien <plu@cpan.org>
325 quicksilver: Jules Bean
327 rafl: Florian Ragwitz <rafl@debian.org>
329 rbuels: Robert Buels <rmb32@cornell.edu>
331 rdj: Ryan D Johnson <ryan@innerfence.com>
333 ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
335 rjbs: Ricardo Signes <rjbs@cpan.org>
337 robkinyon: Rob Kinyon <rkinyon@cpan.org>
339 sc_: Just Another Perl Hacker
341 scotty: Scotty Allen <scotty@scottyallen.com>
343 semifor: Marc Mims <marc@questright.com>
345 solomon: Jared Johnson <jaredj@nmgi.com>
347 spb: Stephen Bennett <stephen@freenode.net>
349 sszabo: Stephan Szabo <sszabo@bigpanda.com>
351 teejay : Aaron Trevena <teejay@cpan.org>
357 typester: Daisuke Murase <typester@cpan.org>
359 victori: Victor Igumnov <victori@cpan.org>
363 willert: Sebastian Willert <willert@cpan.org>
365 wreis: Wallace Reis <wreis@cpan.org>
367 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
371 Copyright (c) 2005 - 2009 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
376 This library is free software and may be distributed under the same terms