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