276eb946ce6aede6890633868e6779970237df01
[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.08119_1';
31
32 $VERSION = eval $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 <alex_hartmaier@hotmail.com>
222
223 aherzog: Adam Herzog <adam@herzogdesigns.com>
224
225 andyg: Andy Grundman <andy@hybridized.org>
226
227 ank: Andres Kievsky
228
229 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
230
231 ash: Ash Berlin <ash@cpan.org>
232
233 bert: Norbert Csongradi <bert@cpan.org>
234
235 blblack: Brandon L. Black <blblack@gmail.com>
236
237 bluefeet: Aran Deltac <bluefeet@cpan.org>
238
239 boghead: Bryan Beeley <cpan@beeley.org>
240
241 bricas: Brian Cassidy <bricas@cpan.org>
242
243 brunov: Bruno Vecchi <vecchi.b@gmail.com>
244
245 caelum: Rafael Kitover <rkitover@cpan.org>
246
247 castaway: Jess Robinson
248
249 claco: Christopher H. Laco
250
251 clkao: CL Kao
252
253 da5id: David Jack Olrik <djo@cpan.org>
254
255 debolaz: Anders Nor Berle <berle@cpan.org>
256
257 dew: Dan Thomas <dan@godders.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 goraxe: Gordon Irving <goraxe@cpan.org>
270
271 gphat: Cory G Watson <gphat@cpan.org>
272
273 groditi: Guillermo Roditi <groditi@cpan.org>
274
275 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
276
277 jasonmay: Jason May <jason.a.may@gmail.com>
278
279 jesper: Jesper Krogh
280
281 jgoulah: John Goulah <jgoulah@cpan.org>
282
283 jguenther: Justin Guenther <jguenther@cpan.org>
284
285 jhannah: Jay Hannah <jay@jays.net>
286
287 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
288
289 jon: Jon Schutz <jjschutz@cpan.org>
290
291 jshirley: J. Shirley <jshirley@gmail.com>
292
293 konobi: Scott McWhirter
294
295 lukes: Luke Saunders <luke.saunders@gmail.com>
296
297 marcus: Marcus Ramberg <mramberg@cpan.org>
298
299 mattlaw: Matt Lawrence
300
301 michaelr: Michael Reddick <michael.reddick@gmail.com>
302
303 ned: Neil de Carteret
304
305 nigel: Nigel Metheringham <nigelm@cpan.org>
306
307 ningu: David Kamholz <dkamholz@cpan.org>
308
309 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
310
311 norbi: Norbert Buchmuller <norbi@nix.hu>
312
313 nuba: Nuba Princigalli <nuba@cpan.org>
314
315 Numa: Dan Sully <daniel@cpan.org>
316
317 ovid: Curtis "Ovid" Poe <ovid@cpan.org>
318
319 oyse: Ã˜ystein Torget <oystein.torget@dnv.com>
320
321 paulm: Paul Makepeace
322
323 penguin: K J Cheetham
324
325 perigrin: Chris Prather <chris@prather.org>
326
327 peter: Peter Collingbourne <peter@pcc.me.uk>
328
329 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
330
331 plu: Johannes Plunien <plu@cpan.org>
332
333 quicksilver: Jules Bean
334
335 rafl: Florian Ragwitz <rafl@debian.org>
336
337 rbuels: Robert Buels <rmb32@cornell.edu>
338
339 rdj: Ryan D Johnson <ryan@innerfence.com>
340
341 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
342
343 rjbs: Ricardo Signes <rjbs@cpan.org>
344
345 robkinyon: Rob Kinyon <rkinyon@cpan.org>
346
347 Roman: Roman Filippov <romanf@cpan.org>
348
349 sc_: Just Another Perl Hacker
350
351 scotty: Scotty Allen <scotty@scottyallen.com>
352
353 semifor: Marc Mims <marc@questright.com>
354
355 solomon: Jared Johnson <jaredj@nmgi.com>
356
357 spb: Stephen Bennett <stephen@freenode.net>
358
359 sszabo: Stephan Szabo <sszabo@bigpanda.com>
360
361 teejay : Aaron Trevena <teejay@cpan.org>
362
363 Todd Lipcon
364
365 Tom Hukins
366
367 triode: Pete Gamache <gamache@cpan.org>
368
369 typester: Daisuke Murase <typester@cpan.org>
370
371 victori: Victor Igumnov <victori@cpan.org>
372
373 wdh: Will Hawes
374
375 willert: Sebastian Willert <willert@cpan.org>
376
377 wreis: Wallace Reis <wreis@cpan.org>
378
379 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
380
381 =head1 COPYRIGHT
382
383 Copyright (c) 2005 - 2010 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
384 as listed above.
385
386 =head1 LICENSE
387
388 This library is free software and may be distributed under the same terms
389 as perl itself.
390
391 =cut