0649793003f7bd0da3ace0876c041b7bee01158c
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
1 package DBIx::Class;
2
3 use strict;
4 use warnings;
5
6 BEGIN {
7   if ($] < 5.009_005) {
8     require MRO::Compat;
9     *DBIx::Class::_ENV_::OLD_MRO = sub () { 1 };
10   }
11   else {
12     require mro;
13     *DBIx::Class::_ENV_::OLD_MRO = sub () { 0 };
14   }
15
16   # ::Runmode would only be loaded by DBICTest, which in turn implies t/
17   *DBIx::Class::_ENV_::DBICTEST = eval { DBICTest::RunMode->is_author }
18     ? sub () { 1 }
19     : sub () { 0 }
20   ;
21 }
22
23 use mro 'c3';
24
25 use DBIx::Class::Optional::Dependencies;
26
27 use vars qw($VERSION);
28 use base qw/DBIx::Class::Componentised DBIx::Class::AccessorGroup/;
29 use DBIx::Class::StartupCheck;
30
31 sub mk_classdata {
32   shift->mk_classaccessor(@_);
33 }
34
35 sub mk_classaccessor {
36   my $self = shift;
37   $self->mk_group_accessors('inherited', $_[0]);
38   $self->set_inherited(@_) if @_ > 1;
39 }
40
41 sub component_base_class { 'DBIx::Class' }
42
43 # Always remember to do all digits for the version even if they're 0
44 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
45 # brain damage and presumably various other packaging systems too
46 $VERSION = '0.08127';
47
48 $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
49
50 sub MODIFY_CODE_ATTRIBUTES {
51   my ($class,$code,@attrs) = @_;
52   $class->mk_classdata('__attr_cache' => {})
53     unless $class->can('__attr_cache');
54   $class->__attr_cache->{$code} = [@attrs];
55   return ();
56 }
57
58 sub _attr_cache {
59   my $self = shift;
60   my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
61
62   return {
63     %$cache,
64     %{ $self->maybe::next::method || {} },
65   };
66 }
67
68 1;
69
70 =head1 NAME
71
72 DBIx::Class - Extensible and flexible object <-> relational mapper.
73
74 =head1 GETTING HELP/SUPPORT
75
76 The community can be found via:
77
78 =over
79
80 =item * Web Site: L<http://www.dbix-class.org/>
81
82 =item * IRC: irc.perl.org#dbix-class
83
84 =for html
85 <a href="http://chat.mibbit.com/#dbix-class@irc.perl.org">(click for instant chatroom login)</a>
86
87 =item * Mailing list: L<http://lists.scsys.co.uk/mailman/listinfo/dbix-class>
88
89 =item * RT Bug Tracker: L<https://rt.cpan.org/Dist/Display.html?Queue=DBIx-Class>
90
91 =item * gitweb: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class.git>
92
93 =item * git: L<git://git.shadowcat.co.uk/dbsrgits/DBIx-Class.git>
94
95 =item * twitter L<http://www.twitter.com/dbix_class>
96
97 =back
98
99 =head1 SYNOPSIS
100
101 Create a schema class called MyDB/Schema.pm:
102
103   package MyDB::Schema;
104   use base qw/DBIx::Class::Schema/;
105
106   __PACKAGE__->load_namespaces();
107
108   1;
109
110 Create a result class to represent artists, who have many CDs, in
111 MyDB/Schema/Result/Artist.pm:
112
113 See L<DBIx::Class::ResultSource> for docs on defining result classes.
114
115   package MyDB::Schema::Result::Artist;
116   use base qw/DBIx::Class::Core/;
117
118   __PACKAGE__->table('artist');
119   __PACKAGE__->add_columns(qw/ artistid name /);
120   __PACKAGE__->set_primary_key('artistid');
121   __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
122
123   1;
124
125 A result class to represent a CD, which belongs to an artist, in
126 MyDB/Schema/Result/CD.pm:
127
128   package MyDB::Schema::Result::CD;
129   use base qw/DBIx::Class::Core/;
130
131   __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
132   __PACKAGE__->table('cd');
133   __PACKAGE__->add_columns(qw/ cdid artistid title year /);
134   __PACKAGE__->set_primary_key('cdid');
135   __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Result::Artist', 'artistid');
136
137   1;
138
139 Then you can use these classes in your application's code:
140
141   # Connect to your database.
142   use MyDB::Schema;
143   my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
144
145   # Query for all artists and put them in an array,
146   # or retrieve them as a result set object.
147   # $schema->resultset returns a DBIx::Class::ResultSet
148   my @all_artists = $schema->resultset('Artist')->all;
149   my $all_artists_rs = $schema->resultset('Artist');
150
151   # Output all artists names
152   # $artist here is a DBIx::Class::Row, which has accessors
153   # for all its columns. Rows are also subclasses of your Result class.
154   foreach $artist (@all_artists) {
155     print $artist->name, "\n";
156   }
157
158   # Create a result set to search for artists.
159   # This does not query the DB.
160   my $johns_rs = $schema->resultset('Artist')->search(
161     # Build your WHERE using an SQL::Abstract structure:
162     { name => { like => 'John%' } }
163   );
164
165   # Execute a joined query to get the cds.
166   my @all_john_cds = $johns_rs->search_related('cds')->all;
167
168   # Fetch the next available row.
169   my $first_john = $johns_rs->next;
170
171   # Specify ORDER BY on the query.
172   my $first_john_cds_by_title_rs = $first_john->cds(
173     undef,
174     { order_by => 'title' }
175   );
176
177   # Create a result set that will fetch the artist data
178   # at the same time as it fetches CDs, using only one query.
179   my $millennium_cds_rs = $schema->resultset('CD')->search(
180     { year => 2000 },
181     { prefetch => 'artist' }
182   );
183
184   my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
185   my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
186
187   # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
188   # create() is the same as new() then insert().
189   my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
190   $new_cd->artist($cd->artist);
191   $new_cd->insert; # Auto-increment primary key filled in after INSERT
192   $new_cd->title('Fork');
193
194   $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
195
196   # change the year of all the millennium CDs at once
197   $millennium_cds_rs->update({ year => 2002 });
198
199 =head1 DESCRIPTION
200
201 This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
202 (with a compatibility layer as a springboard for porting) and a resultset API
203 that allows abstract encapsulation of database operations. It aims to make
204 representing queries in your code as perl-ish as possible while still
205 providing access to as many of the capabilities of the database as possible,
206 including retrieving related records from multiple tables in a single query,
207 JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
208
209 DBIx::Class can handle multi-column primary and foreign keys, complex
210 queries and database-level paging, and does its best to only query the
211 database in order to return something you've directly asked for. If a
212 resultset is used as an iterator it only fetches rows off the statement
213 handle as requested in order to minimise memory usage. It has auto-increment
214 support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
215 known to be used in production on at least the first four, and is fork-
216 and thread-safe out of the box (although
217 L<your DBD may not be|DBI/Threads_and_Thread_Safety>).
218
219 This project is still under rapid development, so large new features may be
220 marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
221 Failing test cases are *always* welcome and point releases are put out rapidly
222 as bugs are found and fixed.
223
224 We do our best to maintain full backwards compatibility for published
225 APIs, since DBIx::Class is used in production in many organisations,
226 and even backwards incompatible changes to non-published APIs will be fixed
227 if they're reported and doing so doesn't cost the codebase anything.
228
229 The test suite is quite substantial, and several developer releases
230 are generally made to CPAN before the branch for the next release is
231 merged back to trunk for a major release.
232
233 =head1 WHERE TO GO NEXT
234
235 L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
236 the modules where you will find documentation.
237
238 =head1 AUTHOR
239
240 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
241
242 (I mostly consider myself "project founder" these days but the AUTHOR heading
243 is traditional :)
244
245 =head1 CONTRIBUTORS
246
247 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
248
249 aherzog: Adam Herzog <adam@herzogdesigns.com>
250
251 Alexander Keusch <cpan@keusch.at>
252
253 alnewkirk: Al Newkirk <we@ana.im>
254
255 amiri: Amiri Barksdale <amiri@metalabel.com>
256
257 amoore: Andrew Moore <amoore@cpan.org>
258
259 andyg: Andy Grundman <andy@hybridized.org>
260
261 ank: Andres Kievsky
262
263 arc: Aaron Crane <arc@cpan.org>
264
265 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
266
267 ash: Ash Berlin <ash@cpan.org>
268
269 bert: Norbert Csongradi <bert@cpan.org>
270
271 blblack: Brandon L. Black <blblack@gmail.com>
272
273 bluefeet: Aran Deltac <bluefeet@cpan.org>
274
275 bphillips: Brian Phillips <bphillips@cpan.org>
276
277 boghead: Bryan Beeley <cpan@beeley.org>
278
279 bricas: Brian Cassidy <bricas@cpan.org>
280
281 brunov: Bruno Vecchi <vecchi.b@gmail.com>
282
283 caelum: Rafael Kitover <rkitover@cpan.org>
284
285 caldrin: Maik Hentsche <maik.hentsche@amd.com>
286
287 castaway: Jess Robinson
288
289 claco: Christopher H. Laco
290
291 clkao: CL Kao
292
293 da5id: David Jack Olrik <djo@cpan.org>
294
295 debolaz: Anders Nor Berle <berle@cpan.org>
296
297 dew: Dan Thomas <dan@godders.org>
298
299 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
300
301 dnm: Justin Wheeler <jwheeler@datademons.com>
302
303 dpetrov: Dimitar Petrov <mitakaa@gmail.com>
304
305 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
306
307 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
308
309 freetime: Bill Moseley <moseley@hank.org>
310
311 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
312
313 goraxe: Gordon Irving <goraxe@cpan.org>
314
315 gphat: Cory G Watson <gphat@cpan.org>
316
317 Grant Street Group L<http://www.grantstreet.com/>
318
319 groditi: Guillermo Roditi <groditi@cpan.org>
320
321 Haarg: Graham Knop <haarg@haarg.org>
322
323 hobbs: Andrew Rodland <arodland@cpan.org>
324
325 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
326
327 initself: Mike Baas <mike@initselftech.com>
328
329 jawnsy: Jonathan Yu <jawnsy@cpan.org>
330
331 jasonmay: Jason May <jason.a.may@gmail.com>
332
333 jesper: Jesper Krogh
334
335 jgoulah: John Goulah <jgoulah@cpan.org>
336
337 jguenther: Justin Guenther <jguenther@cpan.org>
338
339 jhannah: Jay Hannah <jay@jays.net>
340
341 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
342
343 jon: Jon Schutz <jjschutz@cpan.org>
344
345 jshirley: J. Shirley <jshirley@gmail.com>
346
347 kaare: Kaare Rasmussen
348
349 konobi: Scott McWhirter
350
351 littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
352
353 lukes: Luke Saunders <luke.saunders@gmail.com>
354
355 marcus: Marcus Ramberg <mramberg@cpan.org>
356
357 mattlaw: Matt Lawrence
358
359 mattp: Matt Phillips <mattp@cpan.org>
360
361 michaelr: Michael Reddick <michael.reddick@gmail.com>
362
363 milki: Jonathan Chu <milki@rescomp.berkeley.edu>
364
365 ned: Neil de Carteret
366
367 nigel: Nigel Metheringham <nigelm@cpan.org>
368
369 ningu: David Kamholz <dkamholz@cpan.org>
370
371 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
372
373 norbi: Norbert Buchmuller <norbi@nix.hu>
374
375 nuba: Nuba Princigalli <nuba@cpan.org>
376
377 Numa: Dan Sully <daniel@cpan.org>
378
379 ovid: Curtis "Ovid" Poe <ovid@cpan.org>
380
381 oyse: Ã˜ystein Torget <oystein.torget@dnv.com>
382
383 paulm: Paul Makepeace
384
385 penguin: K J Cheetham
386
387 perigrin: Chris Prather <chris@prather.org>
388
389 peter: Peter Collingbourne <peter@pcc.me.uk>
390
391 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
392
393 plu: Johannes Plunien <plu@cpan.org>
394
395 Possum: Daniel LeWarne <possum@cpan.org>
396
397 quicksilver: Jules Bean
398
399 rafl: Florian Ragwitz <rafl@debian.org>
400
401 rainboxx: Matthias Dietrich <perl@rb.ly>
402
403 rbo: Robert Bohne <rbo@cpan.org>
404
405 rbuels: Robert Buels <rmb32@cornell.edu>
406
407 rdj: Ryan D Johnson <ryan@innerfence.com>
408
409 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
410
411 rjbs: Ricardo Signes <rjbs@cpan.org>
412
413 robkinyon: Rob Kinyon <rkinyon@cpan.org>
414
415 Roman: Roman Filippov <romanf@cpan.org>
416
417 Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
418
419 sc_: Just Another Perl Hacker
420
421 scotty: Scotty Allen <scotty@scottyallen.com>
422
423 semifor: Marc Mims <marc@questright.com>
424
425 solomon: Jared Johnson <jaredj@nmgi.com>
426
427 spb: Stephen Bennett <stephen@freenode.net>
428
429 Squeeks <squeek@cpan.org>
430
431 sszabo: Stephan Szabo <sszabo@bigpanda.com>
432
433 talexb: Alex Beamish <talexb@gmail.com>
434
435 tamias: Ronald J Kimball <rjk@tamias.net>
436
437 teejay : Aaron Trevena <teejay@cpan.org>
438
439 Todd Lipcon
440
441 Tom Hukins
442
443 tonvoon: Ton Voon <tonvoon@cpan.org>
444
445 triode: Pete Gamache <gamache@cpan.org>
446
447 typester: Daisuke Murase <typester@cpan.org>
448
449 victori: Victor Igumnov <victori@cpan.org>
450
451 wdh: Will Hawes
452
453 willert: Sebastian Willert <willert@cpan.org>
454
455 wreis: Wallace Reis <wreis@cpan.org>
456
457 yrlnry: Mark Jason Dominus <mjd@plover.com>
458
459 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
460
461 =head1 COPYRIGHT
462
463 Copyright (c) 2005 - 2010 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
464 as listed above.
465
466 =head1 LICENSE
467
468 This library is free software and may be distributed under the same terms
469 as perl itself.
470
471 =cut