7 # Always remember to do all digits for the version even if they're 0
8 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
9 # brain damage and presumably various other packaging systems too
11 # $VERSION declaration must stay up here, ahead of any other package
12 # declarations, as to not confuse various modules attempting to determine
13 # this ones version, whether that be s.c.o. or Module::Metadata, etc
14 $VERSION = '0.08203_01';
16 $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
19 package # hide from pause
27 BROKEN_FORK => ($^O eq 'MSWin32') ? 1 : 0,
29 HAS_ITHREADS => $Config{useithreads} ? 1 : 0,
31 # ::Runmode would only be loaded by DBICTest, which in turn implies t/
32 DBICTEST => eval { DBICTest::RunMode->is_author } ? 1 : 0,
34 # During 5.13 dev cycle HELEMs started to leak on copy
36 # request for all tests would force "non-leaky" illusion and vice-versa
37 defined $ENV{DBICTEST_ALL_LEAKS} ? !$ENV{DBICTEST_ALL_LEAKS}
38 # otherwise confess that this perl is busted ONLY on smokers
39 : eval { DBICTest::RunMode->is_smoker } && ($] >= 5.013005 and $] <= 5.013006) ? 1
40 # otherwise we are good
44 # There was a brief period of p5p insanity when $@ was invisible in a DESTROY
45 INVISIBLE_DOLLAR_AT => ($] >= 5.013001 and $] <= 5.013007) ? 1 : 0,
51 constant->import( OLD_MRO => 1 );
55 constant->import( OLD_MRO => 0 );
61 use DBIx::Class::Optional::Dependencies;
63 use base qw/DBIx::Class::Componentised DBIx::Class::AccessorGroup/;
64 use DBIx::Class::StartupCheck;
66 __PACKAGE__->mk_group_accessors(inherited => '_skip_namespace_frames');
67 __PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve');
70 shift->mk_classaccessor(@_);
73 sub mk_classaccessor {
75 $self->mk_group_accessors('inherited', $_[0]);
76 $self->set_inherited(@_) if @_ > 1;
79 sub component_base_class { 'DBIx::Class' }
81 sub MODIFY_CODE_ATTRIBUTES {
82 my ($class,$code,@attrs) = @_;
83 $class->mk_classdata('__attr_cache' => {})
84 unless $class->can('__attr_cache');
85 $class->__attr_cache->{$code} = [@attrs];
91 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
95 %{ $self->maybe::next::method || {} },
103 DBIx::Class - Extensible and flexible object <-> relational mapper.
105 =head1 GETTING HELP/SUPPORT
107 The community can be found via:
111 =item * Web Site: L<http://www.dbix-class.org/>
113 =item * IRC: irc.perl.org#dbix-class
116 <a href="http://chat.mibbit.com/#dbix-class@irc.perl.org">(click for instant chatroom login)</a>
118 =item * Mailing list: L<http://lists.scsys.co.uk/mailman/listinfo/dbix-class>
120 =item * RT Bug Tracker: L<https://rt.cpan.org/Dist/Display.html?Queue=DBIx-Class>
122 =item * gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class.git>
124 =item * git: L<git://git.shadowcat.co.uk/dbsrgits/DBIx-Class.git>
126 =item * twitter L<http://www.twitter.com/dbix_class>
132 Create a schema class called MyApp/Schema.pm:
134 package MyApp::Schema;
135 use base qw/DBIx::Class::Schema/;
137 __PACKAGE__->load_namespaces();
141 Create a result class to represent artists, who have many CDs, in
142 MyApp/Schema/Result/Artist.pm:
144 See L<DBIx::Class::ResultSource> for docs on defining result classes.
146 package MyApp::Schema::Result::Artist;
147 use base qw/DBIx::Class::Core/;
149 __PACKAGE__->table('artist');
150 __PACKAGE__->add_columns(qw/ artistid name /);
151 __PACKAGE__->set_primary_key('artistid');
152 __PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD', 'artistid');
156 A result class to represent a CD, which belongs to an artist, in
157 MyApp/Schema/Result/CD.pm:
159 package MyApp::Schema::Result::CD;
160 use base qw/DBIx::Class::Core/;
162 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
163 __PACKAGE__->table('cd');
164 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
165 __PACKAGE__->set_primary_key('cdid');
166 __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Result::Artist', 'artistid');
170 Then you can use these classes in your application's code:
172 # Connect to your database.
174 my $schema = MyApp::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
176 # Query for all artists and put them in an array,
177 # or retrieve them as a result set object.
178 # $schema->resultset returns a DBIx::Class::ResultSet
179 my @all_artists = $schema->resultset('Artist')->all;
180 my $all_artists_rs = $schema->resultset('Artist');
182 # Output all artists names
183 # $artist here is a DBIx::Class::Row, which has accessors
184 # for all its columns. Rows are also subclasses of your Result class.
185 foreach $artist (@all_artists) {
186 print $artist->name, "\n";
189 # Create a result set to search for artists.
190 # This does not query the DB.
191 my $johns_rs = $schema->resultset('Artist')->search(
192 # Build your WHERE using an SQL::Abstract structure:
193 { name => { like => 'John%' } }
196 # Execute a joined query to get the cds.
197 my @all_john_cds = $johns_rs->search_related('cds')->all;
199 # Fetch the next available row.
200 my $first_john = $johns_rs->next;
202 # Specify ORDER BY on the query.
203 my $first_john_cds_by_title_rs = $first_john->cds(
205 { order_by => 'title' }
208 # Create a result set that will fetch the artist data
209 # at the same time as it fetches CDs, using only one query.
210 my $millennium_cds_rs = $schema->resultset('CD')->search(
212 { prefetch => 'artist' }
215 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
216 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
218 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
219 # create() is the same as new() then insert().
220 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
221 $new_cd->artist($cd->artist);
222 $new_cd->insert; # Auto-increment primary key filled in after INSERT
223 $new_cd->title('Fork');
225 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
227 # change the year of all the millennium CDs at once
228 $millennium_cds_rs->update({ year => 2002 });
232 This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
233 (with a compatibility layer as a springboard for porting) and a resultset API
234 that allows abstract encapsulation of database operations. It aims to make
235 representing queries in your code as perl-ish as possible while still
236 providing access to as many of the capabilities of the database as possible,
237 including retrieving related records from multiple tables in a single query,
238 JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
240 DBIx::Class can handle multi-column primary and foreign keys, complex
241 queries and database-level paging, and does its best to only query the
242 database in order to return something you've directly asked for. If a
243 resultset is used as an iterator it only fetches rows off the statement
244 handle as requested in order to minimise memory usage. It has auto-increment
245 support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
246 known to be used in production on at least the first four, and is fork-
247 and thread-safe out of the box (although
248 L<your DBD may not be|DBI/Threads and Thread Safety>).
250 This project is still under rapid development, so large new features may be
251 marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
252 Failing test cases are *always* welcome and point releases are put out rapidly
253 as bugs are found and fixed.
255 We do our best to maintain full backwards compatibility for published
256 APIs, since DBIx::Class is used in production in many organisations,
257 and even backwards incompatible changes to non-published APIs will be fixed
258 if they're reported and doing so doesn't cost the codebase anything.
260 The test suite is quite substantial, and several developer releases
261 are generally made to CPAN before the branch for the next release is
262 merged back to trunk for a major release.
264 =head1 WHERE TO GO NEXT
266 L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
267 the modules where you will find documentation.
271 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
273 (I mostly consider myself "project founder" these days but the AUTHOR heading
278 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
280 acca: Alexander Kuznetsov <acca@cpan.org>
282 aherzog: Adam Herzog <adam@herzogdesigns.com>
284 Alexander Keusch <cpan@keusch.at>
286 alnewkirk: Al Newkirk <we@ana.im>
288 amiri: Amiri Barksdale <amiri@metalabel.com>
290 amoore: Andrew Moore <amoore@cpan.org>
292 andyg: Andy Grundman <andy@hybridized.org>
296 arc: Aaron Crane <arc@cpan.org>
298 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
300 ash: Ash Berlin <ash@cpan.org>
302 bert: Norbert Csongradi <bert@cpan.org>
304 blblack: Brandon L. Black <blblack@gmail.com>
306 bluefeet: Aran Deltac <bluefeet@cpan.org>
308 bphillips: Brian Phillips <bphillips@cpan.org>
310 boghead: Bryan Beeley <cpan@beeley.org>
312 brd: Brad Davis <brd@FreeBSD.org>
314 bricas: Brian Cassidy <bricas@cpan.org>
316 brunov: Bruno Vecchi <vecchi.b@gmail.com>
318 caelum: Rafael Kitover <rkitover@cpan.org>
320 caldrin: Maik Hentsche <maik.hentsche@amd.com>
322 castaway: Jess Robinson
324 claco: Christopher H. Laco
328 da5id: David Jack Olrik <djo@cpan.org>
330 debolaz: Anders Nor Berle <berle@cpan.org>
332 dew: Dan Thomas <dan@godders.org>
334 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
336 dnm: Justin Wheeler <jwheeler@datademons.com>
338 dpetrov: Dimitar Petrov <mitakaa@gmail.com>
340 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
342 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
344 edenc: Eden Cardim <edencardim@gmail.com>
346 felliott: Fitz Elliott <fitz.elliott@gmail.com>
348 freetime: Bill Moseley <moseley@hank.org>
350 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
352 goraxe: Gordon Irving <goraxe@cpan.org>
354 gphat: Cory G Watson <gphat@cpan.org>
356 Grant Street Group L<http://www.grantstreet.com/>
358 groditi: Guillermo Roditi <groditi@cpan.org>
360 Haarg: Graham Knop <haarg@haarg.org>
362 hobbs: Andrew Rodland <arodland@cpan.org>
364 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
366 initself: Mike Baas <mike@initselftech.com>
368 ironcamel: Naveed Massjouni <naveedm9@gmail.com>
370 jawnsy: Jonathan Yu <jawnsy@cpan.org>
372 jasonmay: Jason May <jason.a.may@gmail.com>
376 jgoulah: John Goulah <jgoulah@cpan.org>
378 jguenther: Justin Guenther <jguenther@cpan.org>
380 jhannah: Jay Hannah <jay@jays.net>
382 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
384 jon: Jon Schutz <jjschutz@cpan.org>
386 jshirley: J. Shirley <jshirley@gmail.com>
388 kaare: Kaare Rasmussen
390 konobi: Scott McWhirter
392 littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
394 lukes: Luke Saunders <luke.saunders@gmail.com>
396 marcus: Marcus Ramberg <mramberg@cpan.org>
398 mattlaw: Matt Lawrence
400 mattp: Matt Phillips <mattp@cpan.org>
402 michaelr: Michael Reddick <michael.reddick@gmail.com>
404 milki: Jonathan Chu <milki@rescomp.berkeley.edu>
406 mstratman: Mark A. Stratman <stratman@gmail.com>
408 ned: Neil de Carteret
410 nigel: Nigel Metheringham <nigelm@cpan.org>
412 ningu: David Kamholz <dkamholz@cpan.org>
414 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
416 norbi: Norbert Buchmuller <norbi@nix.hu>
418 nuba: Nuba Princigalli <nuba@cpan.org>
420 Numa: Dan Sully <daniel@cpan.org>
422 ovid: Curtis "Ovid" Poe <ovid@cpan.org>
424 oyse: E<Oslash>ystein Torget <oystein.torget@dnv.com>
426 paulm: Paul Makepeace
428 penguin: K J Cheetham
430 perigrin: Chris Prather <chris@prather.org>
432 peter: Peter Collingbourne <peter@pcc.me.uk>
434 Peter Valdemar ME<oslash>rch <peter@morch.com>
436 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
438 plu: Johannes Plunien <plu@cpan.org>
440 Possum: Daniel LeWarne <possum@cpan.org>
442 quicksilver: Jules Bean
444 rafl: Florian Ragwitz <rafl@debian.org>
446 rainboxx: Matthias Dietrich <perl@rb.ly>
448 rbo: Robert Bohne <rbo@cpan.org>
450 rbuels: Robert Buels <rmb32@cornell.edu>
452 rdj: Ryan D Johnson <ryan@innerfence.com>
454 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
456 rjbs: Ricardo Signes <rjbs@cpan.org>
458 robkinyon: Rob Kinyon <rkinyon@cpan.org>
460 Robert Olson <bob@rdolson.org>
462 Roman: Roman Filippov <romanf@cpan.org>
464 Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
466 sc_: Just Another Perl Hacker
468 scotty: Scotty Allen <scotty@scottyallen.com>
470 semifor: Marc Mims <marc@questright.com>
472 SineSwiper: Brendan Byrd <bbyrd@cpan.org>
474 solomon: Jared Johnson <jaredj@nmgi.com>
476 spb: Stephen Bennett <stephen@freenode.net>
478 Squeeks <squeek@cpan.org>
480 sszabo: Stephan Szabo <sszabo@bigpanda.com>
482 talexb: Alex Beamish <talexb@gmail.com>
484 tamias: Ronald J Kimball <rjk@tamias.net>
486 teejay : Aaron Trevena <teejay@cpan.org>
492 tonvoon: Ton Voon <tonvoon@cpan.org>
494 triode: Pete Gamache <gamache@cpan.org>
496 typester: Daisuke Murase <typester@cpan.org>
498 victori: Victor Igumnov <victori@cpan.org>
502 wesm: Wes Malone <wes@mitsi.com>
504 willert: Sebastian Willert <willert@cpan.org>
506 wreis: Wallace Reis <wreis@cpan.org>
508 xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
510 yrlnry: Mark Jason Dominus <mjd@plover.com>
512 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
516 Copyright (c) 2005 - 2011 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
521 This library is free software and may be distributed under the same terms