Release 0.08111
[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.08111';
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 AUTHOR
237
238 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
239
240 (I mostly consider myself "project founder" these days but the AUTHOR heading
241 is traditional :)
242
243 =head1 CONTRIBUTORS
244
245 abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
246
247 aherzog: Adam Herzog <adam@herzogdesigns.com>
248
249 andyg: Andy Grundman <andy@hybridized.org>
250
251 ank: Andres Kievsky
252
253 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
254
255 ash: Ash Berlin <ash@cpan.org>
256
257 bert: Norbert Csongradi <bert@cpan.org>
258
259 blblack: Brandon L. Black <blblack@gmail.com>
260
261 bluefeet: Aran Deltac <bluefeet@cpan.org>
262
263 bricas: Brian Cassidy <bricas@cpan.org>
264
265 caelum: Rafael Kitover <rkitover@cpan.org>
266
267 castaway: Jess Robinson
268
269 claco: Christopher H. Laco
270
271 clkao: CL Kao
272
273 da5id: David Jack Olrik <djo@cpan.org>
274
275 debolaz: Anders Nor Berle <berle@cpan.org>
276
277 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
278
279 dnm: Justin Wheeler <jwheeler@datademons.com>
280
281 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
282
283 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
284
285 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
286
287 gphat: Cory G Watson <gphat@cpan.org>
288
289 groditi: Guillermo Roditi <groditi@cpan.org>
290
291 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
292
293 jasonmay: Jason May <jason.a.may@gmail.com>
294
295 jesper: Jesper Krogh
296
297 jgoulah: John Goulah <jgoulah@cpan.org>
298
299 jguenther: Justin Guenther <jguenther@cpan.org>
300
301 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
302
303 jon: Jon Schutz <jjschutz@cpan.org>
304
305 jshirley: J. Shirley <jshirley@gmail.com>
306
307 konobi: Scott McWhirter
308
309 lukes: Luke Saunders <luke.saunders@gmail.com>
310
311 marcus: Marcus Ramberg <mramberg@cpan.org>
312
313 mattlaw: Matt Lawrence
314
315 michaelr: Michael Reddick <michael.reddick@gmail.com>
316
317 ned: Neil de Carteret
318
319 nigel: Nigel Metheringham <nigelm@cpan.org>
320
321 ningu: David Kamholz <dkamholz@cpan.org>
322
323 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
324
325 norbi: Norbert Buchmuller <norbi@nix.hu>
326
327 Numa: Dan Sully <daniel@cpan.org>
328
329 oyse: Ã˜ystein Torget <oystein.torget@dnv.com>
330
331 paulm: Paul Makepeace
332
333 penguin: K J Cheetham
334
335 perigrin: Chris Prather <chris@prather.org>
336
337 peter: Peter Collingbourne <peter@pcc.me.uk>
338
339 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
340
341 plu: Johannes Plunien <plu@cpan.org>
342
343 quicksilver: Jules Bean
344
345 rafl: Florian Ragwitz <rafl@debian.org>
346
347 rbuels: Robert Buels <rmb32@cornell.edu>
348
349 rdj: Ryan D Johnson <ryan@innerfence.com>
350
351 ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
352
353 rjbs: Ricardo Signes <rjbs@cpan.org>
354
355 robkinyon: Rob Kinyon <rkinyon@cpan.org>
356
357 sc_: Just Another Perl Hacker
358
359 scotty: Scotty Allen <scotty@scottyallen.com>
360
361 semifor: Marc Mims <marc@questright.com>
362
363 solomon: Jared Johnson <jaredj@nmgi.com>
364
365 spb: Stephen Bennett <stephen@freenode.net>
366
367 sszabo: Stephan Szabo <sszabo@bigpanda.com>
368
369 teejay : Aaron Trevena <teejay@cpan.org>
370
371 Todd Lipcon
372
373 Tom Hukins
374
375 typester: Daisuke Murase <typester@cpan.org>
376
377 victori: Victor Igumnov <victori@cpan.org>
378
379 wdh: Will Hawes
380
381 willert: Sebastian Willert <willert@cpan.org>
382
383 wreis: Wallace Reis <wreis@cpan.org>
384
385 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
386
387 =head1 COPYRIGHT
388
389 Copyright (c) 2005 - 2009 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
390 as listed above.
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