Fix regression where SQL files with comments were not handled properly by ::Schema...
[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.08120_1';
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 <alex_hartmaier@hotmail.com>
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 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
280
281 jasonmay: Jason May <jason.a.may@gmail.com>
282
283 jesper: Jesper Krogh
284
285 jgoulah: John Goulah <jgoulah@cpan.org>
286
287 jguenther: Justin Guenther <jguenther@cpan.org>
288
289 jhannah: Jay Hannah <jay@jays.net>
290
291 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
292
293 jon: Jon Schutz <jjschutz@cpan.org>
294
295 jshirley: J. Shirley <jshirley@gmail.com>
296
297 konobi: Scott McWhirter
298
299 lukes: Luke Saunders <luke.saunders@gmail.com>
300
301 marcus: Marcus Ramberg <mramberg@cpan.org>
302
303 mattlaw: Matt Lawrence
304
305 michaelr: Michael Reddick <michael.reddick@gmail.com>
306
307 ned: Neil de Carteret
308
309 nigel: Nigel Metheringham <nigelm@cpan.org>
310
311 ningu: David Kamholz <dkamholz@cpan.org>
312
313 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
314
315 norbi: Norbert Buchmuller <norbi@nix.hu>
316
317 nuba: Nuba Princigalli <nuba@cpan.org>
318
319 Numa: Dan Sully <daniel@cpan.org>
320
321 ovid: Curtis "Ovid" Poe <ovid@cpan.org>
322
323 oyse: Ã˜ystein Torget <oystein.torget@dnv.com>
324
325 paulm: Paul Makepeace
326
327 penguin: K J Cheetham
328
329 perigrin: Chris Prather <chris@prather.org>
330
331 peter: Peter Collingbourne <peter@pcc.me.uk>
332
333 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
334
335 plu: Johannes Plunien <plu@cpan.org>
336
337 quicksilver: Jules Bean
338
339 rafl: Florian Ragwitz <rafl@debian.org>
340
341 rbuels: Robert Buels <rmb32@cornell.edu>
342
343 rdj: Ryan D Johnson <ryan@innerfence.com>
344
345 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
346
347 rjbs: Ricardo Signes <rjbs@cpan.org>
348
349 robkinyon: Rob Kinyon <rkinyon@cpan.org>
350
351 Roman: Roman Filippov <romanf@cpan.org>
352
353 sc_: Just Another Perl Hacker
354
355 scotty: Scotty Allen <scotty@scottyallen.com>
356
357 semifor: Marc Mims <marc@questright.com>
358
359 solomon: Jared Johnson <jaredj@nmgi.com>
360
361 spb: Stephen Bennett <stephen@freenode.net>
362
363 sszabo: Stephan Szabo <sszabo@bigpanda.com>
364
365 teejay : Aaron Trevena <teejay@cpan.org>
366
367 Todd Lipcon
368
369 Tom Hukins
370
371 triode: Pete Gamache <gamache@cpan.org>
372
373 typester: Daisuke Murase <typester@cpan.org>
374
375 victori: Victor Igumnov <victori@cpan.org>
376
377 wdh: Will Hawes
378
379 willert: Sebastian Willert <willert@cpan.org>
380
381 wreis: Wallace Reis <wreis@cpan.org>
382
383 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
384
385 =head1 COPYRIGHT
386
387 Copyright (c) 2005 - 2010 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
388 as listed above.
389
390 =head1 LICENSE
391
392 This library is free software and may be distributed under the same terms
393 as perl itself.
394
395 =cut