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