Changes and dev notes in makefile
[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 the corresponding author_require 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 brunov: Bruno Vecchi <vecchi.b@gmail.com>
266
267 caelum: Rafael Kitover <rkitover@cpan.org>
268
269 castaway: Jess Robinson
270
271 claco: Christopher H. Laco
272
273 clkao: CL Kao
274
275 da5id: David Jack Olrik <djo@cpan.org>
276
277 debolaz: Anders Nor Berle <berle@cpan.org>
278
279 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
280
281 dnm: Justin Wheeler <jwheeler@datademons.com>
282
283 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
284
285 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
286
287 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
288
289 gphat: Cory G Watson <gphat@cpan.org>
290
291 groditi: Guillermo Roditi <groditi@cpan.org>
292
293 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
294
295 jasonmay: Jason May <jason.a.may@gmail.com>
296
297 jesper: Jesper Krogh
298
299 jgoulah: John Goulah <jgoulah@cpan.org>
300
301 jguenther: Justin Guenther <jguenther@cpan.org>
302
303 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
304
305 jon: Jon Schutz <jjschutz@cpan.org>
306
307 jshirley: J. Shirley <jshirley@gmail.com>
308
309 konobi: Scott McWhirter
310
311 lukes: Luke Saunders <luke.saunders@gmail.com>
312
313 marcus: Marcus Ramberg <mramberg@cpan.org>
314
315 mattlaw: Matt Lawrence
316
317 michaelr: Michael Reddick <michael.reddick@gmail.com>
318
319 ned: Neil de Carteret
320
321 nigel: Nigel Metheringham <nigelm@cpan.org>
322
323 ningu: David Kamholz <dkamholz@cpan.org>
324
325 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
326
327 norbi: Norbert Buchmuller <norbi@nix.hu>
328
329 Numa: Dan Sully <daniel@cpan.org>
330
331 oyse: Ã˜ystein Torget <oystein.torget@dnv.com>
332
333 paulm: Paul Makepeace
334
335 penguin: K J Cheetham
336
337 perigrin: Chris Prather <chris@prather.org>
338
339 peter: Peter Collingbourne <peter@pcc.me.uk>
340
341 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
342
343 plu: Johannes Plunien <plu@cpan.org>
344
345 quicksilver: Jules Bean
346
347 rafl: Florian Ragwitz <rafl@debian.org>
348
349 rbuels: Robert Buels <rmb32@cornell.edu>
350
351 rdj: Ryan D Johnson <ryan@innerfence.com>
352
353 ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
354
355 rjbs: Ricardo Signes <rjbs@cpan.org>
356
357 robkinyon: Rob Kinyon <rkinyon@cpan.org>
358
359 sc_: Just Another Perl Hacker
360
361 scotty: Scotty Allen <scotty@scottyallen.com>
362
363 semifor: Marc Mims <marc@questright.com>
364
365 solomon: Jared Johnson <jaredj@nmgi.com>
366
367 spb: Stephen Bennett <stephen@freenode.net>
368
369 sszabo: Stephan Szabo <sszabo@bigpanda.com>
370
371 teejay : Aaron Trevena <teejay@cpan.org>
372
373 Todd Lipcon
374
375 Tom Hukins
376
377 typester: Daisuke Murase <typester@cpan.org>
378
379 victori: Victor Igumnov <victori@cpan.org>
380
381 wdh: Will Hawes
382
383 willert: Sebastian Willert <willert@cpan.org>
384
385 wreis: Wallace Reis <wreis@cpan.org>
386
387 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
388
389 =head1 COPYRIGHT
390
391 Copyright (c) 2005 - 2009 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