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