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