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