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