Factor out dumper copy/paste
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
CommitLineData
ea2e61bf 1package DBIx::Class;
2
5d283305 3use strict;
4use warnings;
5
329d7385 6use MRO::Compat;
7
5d283305 8use vars qw($VERSION);
3e110410 9use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
11736b4c 10use DBIx::Class::StartupCheck;
3e110410 11
ade0fe3b 12sub mk_classdata {
77d518d1 13 shift->mk_classaccessor(@_);
14}
15
16sub mk_classaccessor {
17 my $self = shift;
ade0fe3b 18 $self->mk_group_accessors('inherited', $_[0]);
77d518d1 19 $self->set_inherited(@_) if @_ > 1;
3e110410 20}
3c0068c1 21
7411204b 22sub component_base_class { 'DBIx::Class' }
227d4dee 23
95da6f35 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
59f27fc3 28$VERSION = '0.08111';
748ab0dc 29
30$VERSION = eval $VERSION; # numify for warning-free dev releases
b8777a0d 31
7f6f5b69 32# what version of sqlt do we require if deploy() without a ddl_dir is invoked
33# when changing also adjust $sqlt_recommends in Makefile.PL
34my $minimum_sqlt_version = '0.11002';
35
f0750722 36sub MODIFY_CODE_ATTRIBUTES {
b5d2c57f 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 ();
f0750722 42}
43
da95b45f 44sub _attr_cache {
b5d2c57f 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 };
da95b45f 49}
50
7f6f5b69 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
b561bb6f 78# Pretty printer for debug messages
79sub _pretty_print {
80
81 require Data::Dumper;
82 local $Data::Dumper::Terse = 1;
83 local $Data::Dumper::Indent = 1;
84 local $Data::Dumper::Useqq = 1;
85 local $Data::Dumper::Quotekeys = 0;
86 local $Data::Dumper::Sortkeys = 1;
87
88 return Data::Dumper::Dumper ($_[1]);
89}
90
7f6f5b69 91
ea2e61bf 921;
34d52be2 93
75d07914 94=head1 NAME
34d52be2 95
7e4b2f59 96DBIx::Class - Extensible and flexible object <-> relational mapper.
34d52be2 97
3b1c2bbd 98=head1 GETTING HELP/SUPPORT
99
100The community can be found via:
101
102 Mailing list: http://lists.scsys.co.uk/mailman/listinfo/dbix-class/
103
104 SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
105
106 SVNWeb: http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/
107
108 IRC: irc.perl.org#dbix-class
109
34d52be2 110=head1 SYNOPSIS
111
bd077b47 112Create a schema class called MyDB/Schema.pm:
34d52be2 113
bd077b47 114 package MyDB::Schema;
a0638a7b 115 use base qw/DBIx::Class::Schema/;
34d52be2 116
f0bb26f3 117 __PACKAGE__->load_namespaces();
daec44b8 118
a0638a7b 119 1;
daec44b8 120
30e1753a 121Create a result class to represent artists, who have many CDs, in
f0bb26f3 122MyDB/Schema/Result/Artist.pm:
daec44b8 123
30e1753a 124See L<DBIx::Class::ResultSource> for docs on defining result classes.
125
f0bb26f3 126 package MyDB::Schema::Result::Artist;
a0638a7b 127 use base qw/DBIx::Class/;
daec44b8 128
bd077b47 129 __PACKAGE__->load_components(qw/Core/);
a0638a7b 130 __PACKAGE__->table('artist');
131 __PACKAGE__->add_columns(qw/ artistid name /);
132 __PACKAGE__->set_primary_key('artistid');
f0bb26f3 133 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
daec44b8 134
a0638a7b 135 1;
daec44b8 136
30e1753a 137A result class to represent a CD, which belongs to an artist, in
f0bb26f3 138MyDB/Schema/Result/CD.pm:
39fe0e65 139
f0bb26f3 140 package MyDB::Schema::Result::CD;
a0638a7b 141 use base qw/DBIx::Class/;
39fe0e65 142
bd077b47 143 __PACKAGE__->load_components(qw/Core/);
a0638a7b 144 __PACKAGE__->table('cd');
bd077b47 145 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
a0638a7b 146 __PACKAGE__->set_primary_key('cdid');
bd077b47 147 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
39fe0e65 148
a0638a7b 149 1;
39fe0e65 150
a0638a7b 151Then you can use these classes in your application's code:
39fe0e65 152
a0638a7b 153 # Connect to your database.
bd077b47 154 use MyDB::Schema;
155 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
a0638a7b 156
157 # Query for all artists and put them in an array,
158 # or retrieve them as a result set object.
30e1753a 159 # $schema->resultset returns a DBIx::Class::ResultSet
2053ab2a 160 my @all_artists = $schema->resultset('Artist')->all;
161 my $all_artists_rs = $schema->resultset('Artist');
126042ee 162
30e1753a 163 # Output all artists names
164 # $artist here is a DBIx::Class::Row, which has accessors
16ccb4fe 165 # for all its columns. Rows are also subclasses of your Result class.
30e1753a 166 foreach $artist (@artists) {
167 print $artist->name, "\n";
168 }
169
a0638a7b 170 # Create a result set to search for artists.
86beca1d 171 # This does not query the DB.
2053ab2a 172 my $johns_rs = $schema->resultset('Artist')->search(
6576ef54 173 # Build your WHERE using an SQL::Abstract structure:
2053ab2a 174 { name => { like => 'John%' } }
a0638a7b 175 );
39fe0e65 176
2053ab2a 177 # Execute a joined query to get the cds.
a0638a7b 178 my @all_john_cds = $johns_rs->search_related('cds')->all;
448c8424 179
f0bb26f3 180 # Fetch the next available row.
a0638a7b 181 my $first_john = $johns_rs->next;
448c8424 182
2053ab2a 183 # Specify ORDER BY on the query.
a0638a7b 184 my $first_john_cds_by_title_rs = $first_john->cds(
185 undef,
186 { order_by => 'title' }
187 );
448c8424 188
bd077b47 189 # Create a result set that will fetch the artist data
2053ab2a 190 # at the same time as it fetches CDs, using only one query.
884559b1 191 my $millennium_cds_rs = $schema->resultset('CD')->search(
a0638a7b 192 { year => 2000 },
193 { prefetch => 'artist' }
194 );
448c8424 195
880a1a0c 196 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
bd077b47 197 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
076652e8 198
264f1571 199 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
200 # create() is the same as new() then insert().
884559b1 201 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
f183eccd 202 $new_cd->artist($cd->artist);
f183eccd 203 $new_cd->insert; # Auto-increment primary key filled in after INSERT
f183eccd 204 $new_cd->title('Fork');
205
884559b1 206 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
f183eccd 207
bd077b47 208 # change the year of all the millennium CDs at once
209 $millennium_cds_rs->update({ year => 2002 });
f183eccd 210
211=head1 DESCRIPTION
212
213This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
bd077b47 214(with a compatibility layer as a springboard for porting) and a resultset API
f183eccd 215that allows abstract encapsulation of database operations. It aims to make
216representing queries in your code as perl-ish as possible while still
a0638a7b 217providing access to as many of the capabilities of the database as possible,
f183eccd 218including retrieving related records from multiple tables in a single query,
bd077b47 219JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
f183eccd 220
221DBIx::Class can handle multi-column primary and foreign keys, complex
222queries and database-level paging, and does its best to only query the
75d07914 223database in order to return something you've directly asked for. If a
224resultset is used as an iterator it only fetches rows off the statement
225handle as requested in order to minimise memory usage. It has auto-increment
2053ab2a 226support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
227known to be used in production on at least the first four, and is fork-
75d07914 228and thread-safe out of the box (although your DBD may not be).
f183eccd 229
dfccde48 230This project is still under rapid development, so large new features may be
231marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
232Failing test cases are *always* welcome and point releases are put out rapidly
233as bugs are found and fixed.
234
235We do our best to maintain full backwards compatibility for published
236APIs, since DBIx::Class is used in production in many organisations,
237and even backwards incompatible changes to non-published APIs will be fixed
238if they're reported and doing so doesn't cost the codebase anything.
239
264f1571 240The test suite is quite substantial, and several developer releases
241are generally made to CPAN before the branch for the next release is
242merged back to trunk for a major release.
f183eccd 243
f183eccd 244=head1 WHERE TO GO NEXT
245
2ca930b4 246L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
247the modules where you will find documentation.
076652e8 248
3942ab4d 249=head1 AUTHOR
34d52be2 250
266bdcc3 251mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 252
dfccde48 253(I mostly consider myself "project founder" these days but the AUTHOR heading
254is traditional :)
255
3942ab4d 256=head1 CONTRIBUTORS
257
266bdcc3 258abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
84e3c114 259
6d84db2c 260aherzog: Adam Herzog <adam@herzogdesigns.com>
261
266bdcc3 262andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 263
266bdcc3 264ank: Andres Kievsky
3942ab4d 265
624764ae 266arcanez: Justin Hunter <justin.d.hunter@gmail.com>
267
ce4c07df 268ash: Ash Berlin <ash@cpan.org>
269
3d5bd2af 270bert: Norbert Csongradi <bert@cpan.org>
271
967a4c40 272blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 273
62eb8fe8 274bluefeet: Aran Deltac <bluefeet@cpan.org>
275
bcb8f3ed 276bricas: Brian Cassidy <bricas@cpan.org>
277
3d7e3e05 278brunov: Bruno Vecchi <vecchi.b@gmail.com>
279
281719d2 280caelum: Rafael Kitover <rkitover@cpan.org>
281
d3b0e369 282castaway: Jess Robinson
3942ab4d 283
266bdcc3 284claco: Christopher H. Laco
ccb9c9b1 285
266bdcc3 286clkao: CL Kao
3942ab4d 287
e21dfd6a 288da5id: David Jack Olrik <djo@cpan.org>
18360aed 289
13de943d 290debolaz: Anders Nor Berle <berle@cpan.org>
291
266bdcc3 292dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 293
9382ad07 294dnm: Justin Wheeler <jwheeler@datademons.com>
295
266bdcc3 296dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 297
5cffe785 298dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 299
ade0fe3b 300frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
301
d3b0e369 302gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 303
e758ffe6 304groditi: Guillermo Roditi <groditi@cpan.org>
305
5d779578 306ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
307
bee21976 308jasonmay: Jason May <jason.a.may@gmail.com>
309
d3b0e369 310jesper: Jesper Krogh
5fb0c64c 311
4a743a00 312jgoulah: John Goulah <jgoulah@cpan.org>
313
102a2984 314jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 315
8b93a938 316jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
317
11736b4c 318jon: Jon Schutz <jjschutz@cpan.org>
319
1aec4bac 320jshirley: J. Shirley <jshirley@gmail.com>
321
d3b0e369 322konobi: Scott McWhirter
535fc2ee 323
4367679a 324lukes: Luke Saunders <luke.saunders@gmail.com>
325
709ea492 326marcus: Marcus Ramberg <mramberg@cpan.org>
327
114780ee 328mattlaw: Matt Lawrence
329
58755bba 330michaelr: Michael Reddick <michael.reddick@gmail.com>
331
77e7e47d 332ned: Neil de Carteret
333
266bdcc3 334nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 335
d3b0e369 336ningu: David Kamholz <dkamholz@cpan.org>
337
66cf3a84 338Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
339
20b4c148 340norbi: Norbert Buchmuller <norbi@nix.hu>
341
d3b0e369 342Numa: Dan Sully <daniel@cpan.org>
343
bf356c54 344oyse: Øystein Torget <oystein.torget@dnv.com>
345
266bdcc3 346paulm: Paul Makepeace
4763f4b7 347
d3b0e369 348penguin: K J Cheetham
349
8cfef6f5 350perigrin: Chris Prather <chris@prather.org>
351
14899528 352peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 353
266bdcc3 354phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 355
56fadd8f 356plu: Johannes Plunien <plu@cpan.org>
357
d3b0e369 358quicksilver: Jules Bean
022e0893 359
4ed01b34 360rafl: Florian Ragwitz <rafl@debian.org>
361
7ff0dace 362rbuels: Robert Buels <rmb32@cornell.edu>
363
0da8b7da 364rdj: Ryan D Johnson <ryan@innerfence.com>
365
28ad4c43 366ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
d76e282a 367
b487918c 368rjbs: Ricardo Signes <rjbs@cpan.org>
369
6ffb5be5 370robkinyon: Rob Kinyon <rkinyon@cpan.org>
371
d3b0e369 372sc_: Just Another Perl Hacker
ba606e58 373
266bdcc3 374scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 375
1c133e22 376semifor: Marc Mims <marc@questright.com>
377
20b4c148 378solomon: Jared Johnson <jaredj@nmgi.com>
379
88f937fb 380spb: Stephen Bennett <stephen@freenode.net>
381
637ca936 382sszabo: Stephan Szabo <sszabo@bigpanda.com>
383
386c2272 384teejay : Aaron Trevena <teejay@cpan.org>
385
84e3c114 386Todd Lipcon
e063fe2c 387
6eb6264e 388Tom Hukins
389
d3b0e369 390typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 391
4740bdb7 392victori: Victor Igumnov <victori@cpan.org>
393
d3b0e369 394wdh: Will Hawes
4c248161 395
00c03ced 396willert: Sebastian Willert <willert@cpan.org>
397
66d2a14e 398wreis: Wallace Reis <wreis@cpan.org>
399
d3b0e369 400zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 401
b38e10bd 402=head1 COPYRIGHT
403
404Copyright (c) 2005 - 2009 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
405as listed above.
406
96154ef7 407=head1 LICENSE
408
409This library is free software and may be distributed under the same terms
410as perl itself.
411
34d52be2 412=cut