couple of comment/documentation tweaks to pg storage driver
[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
dc5460a7 28$VERSION = '0.08109';
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
96154ef7 236=head1 COPYRIGHT
fc6d3d81 237
238Copyright (c) 2005 - 2009 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
239as listed below.
240
3942ab4d 241=head1 AUTHOR
34d52be2 242
266bdcc3 243mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 244
dfccde48 245(I mostly consider myself "project founder" these days but the AUTHOR heading
246is traditional :)
247
3942ab4d 248=head1 CONTRIBUTORS
249
266bdcc3 250abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
84e3c114 251
6d84db2c 252aherzog: Adam Herzog <adam@herzogdesigns.com>
253
266bdcc3 254andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 255
266bdcc3 256ank: Andres Kievsky
3942ab4d 257
624764ae 258arcanez: Justin Hunter <justin.d.hunter@gmail.com>
259
ce4c07df 260ash: Ash Berlin <ash@cpan.org>
261
3d5bd2af 262bert: Norbert Csongradi <bert@cpan.org>
263
967a4c40 264blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 265
62eb8fe8 266bluefeet: Aran Deltac <bluefeet@cpan.org>
267
bcb8f3ed 268bricas: Brian Cassidy <bricas@cpan.org>
269
281719d2 270caelum: Rafael Kitover <rkitover@cpan.org>
271
d3b0e369 272castaway: Jess Robinson
3942ab4d 273
266bdcc3 274claco: Christopher H. Laco
ccb9c9b1 275
266bdcc3 276clkao: CL Kao
3942ab4d 277
e21dfd6a 278da5id: David Jack Olrik <djo@cpan.org>
18360aed 279
13de943d 280debolaz: Anders Nor Berle <berle@cpan.org>
281
266bdcc3 282dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 283
9382ad07 284dnm: Justin Wheeler <jwheeler@datademons.com>
285
266bdcc3 286dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 287
5cffe785 288dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 289
ade0fe3b 290frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
291
d3b0e369 292gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 293
e758ffe6 294groditi: Guillermo Roditi <groditi@cpan.org>
295
5d779578 296ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
297
bee21976 298jasonmay: Jason May <jason.a.may@gmail.com>
299
d3b0e369 300jesper: Jesper Krogh
5fb0c64c 301
4a743a00 302jgoulah: John Goulah <jgoulah@cpan.org>
303
102a2984 304jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 305
8b93a938 306jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
307
11736b4c 308jon: Jon Schutz <jjschutz@cpan.org>
309
1aec4bac 310jshirley: J. Shirley <jshirley@gmail.com>
311
d3b0e369 312konobi: Scott McWhirter
535fc2ee 313
4367679a 314lukes: Luke Saunders <luke.saunders@gmail.com>
315
709ea492 316marcus: Marcus Ramberg <mramberg@cpan.org>
317
114780ee 318mattlaw: Matt Lawrence
319
58755bba 320michaelr: Michael Reddick <michael.reddick@gmail.com>
321
77e7e47d 322ned: Neil de Carteret
323
266bdcc3 324nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 325
d3b0e369 326ningu: David Kamholz <dkamholz@cpan.org>
327
66cf3a84 328Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
329
20b4c148 330norbi: Norbert Buchmuller <norbi@nix.hu>
331
d3b0e369 332Numa: Dan Sully <daniel@cpan.org>
333
bf356c54 334oyse: Øystein Torget <oystein.torget@dnv.com>
335
266bdcc3 336paulm: Paul Makepeace
4763f4b7 337
d3b0e369 338penguin: K J Cheetham
339
8cfef6f5 340perigrin: Chris Prather <chris@prather.org>
341
14899528 342peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 343
266bdcc3 344phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 345
56fadd8f 346plu: Johannes Plunien <plu@cpan.org>
347
d3b0e369 348quicksilver: Jules Bean
022e0893 349
4ed01b34 350rafl: Florian Ragwitz <rafl@debian.org>
351
7ff0dace 352rbuels: Robert Buels <rmb32@cornell.edu>
353
0da8b7da 354rdj: Ryan D Johnson <ryan@innerfence.com>
355
28ad4c43 356ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
d76e282a 357
b487918c 358rjbs: Ricardo Signes <rjbs@cpan.org>
359
6ffb5be5 360robkinyon: Rob Kinyon <rkinyon@cpan.org>
361
d3b0e369 362sc_: Just Another Perl Hacker
ba606e58 363
266bdcc3 364scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 365
1c133e22 366semifor: Marc Mims <marc@questright.com>
367
20b4c148 368solomon: Jared Johnson <jaredj@nmgi.com>
369
88f937fb 370spb: Stephen Bennett <stephen@freenode.net>
371
637ca936 372sszabo: Stephan Szabo <sszabo@bigpanda.com>
373
386c2272 374teejay : Aaron Trevena <teejay@cpan.org>
375
84e3c114 376Todd Lipcon
e063fe2c 377
6eb6264e 378Tom Hukins
379
d3b0e369 380typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 381
4740bdb7 382victori: Victor Igumnov <victori@cpan.org>
383
d3b0e369 384wdh: Will Hawes
4c248161 385
00c03ced 386willert: Sebastian Willert <willert@cpan.org>
387
66d2a14e 388wreis: Wallace Reis <wreis@cpan.org>
389
d3b0e369 390zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 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