testing dhoss's permissions
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
CommitLineData
ea2e61bf 1package DBIx::Class;
2
5d283305 3use strict;
4use warnings;
5
5d283305 6use vars qw($VERSION);
3e110410 7use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
11736b4c 8use DBIx::Class::StartupCheck;
3e110410 9
77d518d1 10
3e110410 11sub mk_classdata {
77d518d1 12 shift->mk_classaccessor(@_);
13}
14
15sub mk_classaccessor {
16 my $self = shift;
17 $self->mk_group_accessors('inherited', $_[0]);
18 $self->set_inherited(@_) if @_ > 1;
3e110410 19}
3c0068c1 20
7411204b 21sub component_base_class { 'DBIx::Class' }
227d4dee 22
95da6f35 23# Always remember to do all digits for the version even if they're 0
24# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
25# brain damage and presumably various other packaging systems too
26
eaab653f 27$VERSION = '0.08099_06';
748ab0dc 28
29$VERSION = eval $VERSION; # numify for warning-free dev releases
b8777a0d 30
f0750722 31sub MODIFY_CODE_ATTRIBUTES {
b5d2c57f 32 my ($class,$code,@attrs) = @_;
33 $class->mk_classdata('__attr_cache' => {})
34 unless $class->can('__attr_cache');
35 $class->__attr_cache->{$code} = [@attrs];
36 return ();
f0750722 37}
38
da95b45f 39sub _attr_cache {
b5d2c57f 40 my $self = shift;
41 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
42 my $rest = eval { $self->next::method };
43 return $@ ? $cache : { %$cache, %$rest };
da95b45f 44}
45
ea2e61bf 461;
34d52be2 47
a21014a7 48my $dhoss_has_commit_bit = 1;
49
75d07914 50=head1 NAME
34d52be2 51
7e4b2f59 52DBIx::Class - Extensible and flexible object <-> relational mapper.
34d52be2 53
3b1c2bbd 54=head1 GETTING HELP/SUPPORT
55
56The community can be found via:
57
58 Mailing list: http://lists.scsys.co.uk/mailman/listinfo/dbix-class/
59
60 SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
61
62 SVNWeb: http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/
63
64 IRC: irc.perl.org#dbix-class
65
34d52be2 66=head1 SYNOPSIS
67
bd077b47 68Create a schema class called MyDB/Schema.pm:
34d52be2 69
bd077b47 70 package MyDB::Schema;
a0638a7b 71 use base qw/DBIx::Class::Schema/;
34d52be2 72
f0bb26f3 73 __PACKAGE__->load_namespaces();
daec44b8 74
a0638a7b 75 1;
daec44b8 76
bd077b47 77Create a table class to represent artists, who have many CDs, in
f0bb26f3 78MyDB/Schema/Result/Artist.pm:
daec44b8 79
f0bb26f3 80 package MyDB::Schema::Result::Artist;
a0638a7b 81 use base qw/DBIx::Class/;
daec44b8 82
bd077b47 83 __PACKAGE__->load_components(qw/Core/);
a0638a7b 84 __PACKAGE__->table('artist');
85 __PACKAGE__->add_columns(qw/ artistid name /);
86 __PACKAGE__->set_primary_key('artistid');
f0bb26f3 87 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
daec44b8 88
a0638a7b 89 1;
daec44b8 90
bd077b47 91A table class to represent a CD, which belongs to an artist, in
f0bb26f3 92MyDB/Schema/Result/CD.pm:
39fe0e65 93
f0bb26f3 94 package MyDB::Schema::Result::CD;
a0638a7b 95 use base qw/DBIx::Class/;
39fe0e65 96
bd077b47 97 __PACKAGE__->load_components(qw/Core/);
a0638a7b 98 __PACKAGE__->table('cd');
bd077b47 99 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
a0638a7b 100 __PACKAGE__->set_primary_key('cdid');
bd077b47 101 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
39fe0e65 102
a0638a7b 103 1;
39fe0e65 104
a0638a7b 105Then you can use these classes in your application's code:
39fe0e65 106
a0638a7b 107 # Connect to your database.
bd077b47 108 use MyDB::Schema;
109 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
a0638a7b 110
111 # Query for all artists and put them in an array,
112 # or retrieve them as a result set object.
2053ab2a 113 my @all_artists = $schema->resultset('Artist')->all;
114 my $all_artists_rs = $schema->resultset('Artist');
126042ee 115
a0638a7b 116 # Create a result set to search for artists.
86beca1d 117 # This does not query the DB.
2053ab2a 118 my $johns_rs = $schema->resultset('Artist')->search(
6576ef54 119 # Build your WHERE using an SQL::Abstract structure:
2053ab2a 120 { name => { like => 'John%' } }
a0638a7b 121 );
39fe0e65 122
2053ab2a 123 # Execute a joined query to get the cds.
a0638a7b 124 my @all_john_cds = $johns_rs->search_related('cds')->all;
448c8424 125
f0bb26f3 126 # Fetch the next available row.
a0638a7b 127 my $first_john = $johns_rs->next;
448c8424 128
2053ab2a 129 # Specify ORDER BY on the query.
a0638a7b 130 my $first_john_cds_by_title_rs = $first_john->cds(
131 undef,
132 { order_by => 'title' }
133 );
448c8424 134
bd077b47 135 # Create a result set that will fetch the artist data
2053ab2a 136 # at the same time as it fetches CDs, using only one query.
884559b1 137 my $millennium_cds_rs = $schema->resultset('CD')->search(
a0638a7b 138 { year => 2000 },
139 { prefetch => 'artist' }
140 );
448c8424 141
880a1a0c 142 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
bd077b47 143 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
076652e8 144
264f1571 145 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
146 # create() is the same as new() then insert().
884559b1 147 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
f183eccd 148 $new_cd->artist($cd->artist);
f183eccd 149 $new_cd->insert; # Auto-increment primary key filled in after INSERT
f183eccd 150 $new_cd->title('Fork');
151
884559b1 152 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
f183eccd 153
bd077b47 154 # change the year of all the millennium CDs at once
155 $millennium_cds_rs->update({ year => 2002 });
f183eccd 156
157=head1 DESCRIPTION
158
159This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
bd077b47 160(with a compatibility layer as a springboard for porting) and a resultset API
f183eccd 161that allows abstract encapsulation of database operations. It aims to make
162representing queries in your code as perl-ish as possible while still
a0638a7b 163providing access to as many of the capabilities of the database as possible,
f183eccd 164including retrieving related records from multiple tables in a single query,
bd077b47 165JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
f183eccd 166
167DBIx::Class can handle multi-column primary and foreign keys, complex
168queries and database-level paging, and does its best to only query the
75d07914 169database in order to return something you've directly asked for. If a
170resultset is used as an iterator it only fetches rows off the statement
171handle as requested in order to minimise memory usage. It has auto-increment
2053ab2a 172support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
173known to be used in production on at least the first four, and is fork-
75d07914 174and thread-safe out of the box (although your DBD may not be).
f183eccd 175
dfccde48 176This project is still under rapid development, so large new features may be
177marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
178Failing test cases are *always* welcome and point releases are put out rapidly
179as bugs are found and fixed.
180
181We do our best to maintain full backwards compatibility for published
182APIs, since DBIx::Class is used in production in many organisations,
183and even backwards incompatible changes to non-published APIs will be fixed
184if they're reported and doing so doesn't cost the codebase anything.
185
264f1571 186The test suite is quite substantial, and several developer releases
187are generally made to CPAN before the branch for the next release is
188merged back to trunk for a major release.
f183eccd 189
f183eccd 190=head1 WHERE TO GO NEXT
191
2ca930b4 192L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
193the modules where you will find documentation.
076652e8 194
3942ab4d 195=head1 AUTHOR
34d52be2 196
266bdcc3 197mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 198
dfccde48 199(I mostly consider myself "project founder" these days but the AUTHOR heading
200is traditional :)
201
3942ab4d 202=head1 CONTRIBUTORS
203
266bdcc3 204abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
84e3c114 205
6d84db2c 206aherzog: Adam Herzog <adam@herzogdesigns.com>
207
266bdcc3 208andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 209
266bdcc3 210ank: Andres Kievsky
3942ab4d 211
ce4c07df 212ash: Ash Berlin <ash@cpan.org>
213
3d5bd2af 214bert: Norbert Csongradi <bert@cpan.org>
215
967a4c40 216blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 217
62eb8fe8 218bluefeet: Aran Deltac <bluefeet@cpan.org>
219
bcb8f3ed 220bricas: Brian Cassidy <bricas@cpan.org>
221
281719d2 222caelum: Rafael Kitover <rkitover@cpan.org>
223
d3b0e369 224captainL: Luke Saunders <luke.saunders@gmail.com>
225
226castaway: Jess Robinson
3942ab4d 227
266bdcc3 228claco: Christopher H. Laco
ccb9c9b1 229
266bdcc3 230clkao: CL Kao
3942ab4d 231
e21dfd6a 232da5id: David Jack Olrik <djo@cpan.org>
18360aed 233
13de943d 234debolaz: Anders Nor Berle <berle@cpan.org>
235
266bdcc3 236dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 237
9382ad07 238dnm: Justin Wheeler <jwheeler@datademons.com>
239
266bdcc3 240dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 241
5cffe785 242dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 243
d3b0e369 244gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 245
e758ffe6 246groditi: Guillermo Roditi <groditi@cpan.org>
247
d3b0e369 248jesper: Jesper Krogh
5fb0c64c 249
4a743a00 250jgoulah: John Goulah <jgoulah@cpan.org>
251
102a2984 252jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 253
8b93a938 254jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
255
11736b4c 256jon: Jon Schutz <jjschutz@cpan.org>
257
1aec4bac 258jshirley: J. Shirley <jshirley@gmail.com>
259
d3b0e369 260konobi: Scott McWhirter
535fc2ee 261
709ea492 262marcus: Marcus Ramberg <mramberg@cpan.org>
263
114780ee 264mattlaw: Matt Lawrence
265
77e7e47d 266ned: Neil de Carteret
267
266bdcc3 268nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 269
d3b0e369 270ningu: David Kamholz <dkamholz@cpan.org>
271
272Numa: Dan Sully <daniel@cpan.org>
273
bf356c54 274oyse: Øystein Torget <oystein.torget@dnv.com>
275
266bdcc3 276paulm: Paul Makepeace
4763f4b7 277
d3b0e369 278penguin: K J Cheetham
279
8cfef6f5 280perigrin: Chris Prather <chris@prather.org>
281
266bdcc3 282phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 283
56fadd8f 284plu: Johannes Plunien <plu@cpan.org>
285
d3b0e369 286quicksilver: Jules Bean
022e0893 287
4ed01b34 288rafl: Florian Ragwitz <rafl@debian.org>
289
0da8b7da 290rdj: Ryan D Johnson <ryan@innerfence.com>
291
28ad4c43 292ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
d76e282a 293
b487918c 294rjbs: Ricardo Signes <rjbs@cpan.org>
295
d3b0e369 296sc_: Just Another Perl Hacker
ba606e58 297
266bdcc3 298scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 299
1c133e22 300semifor: Marc Mims <marc@questright.com>
301
637ca936 302sszabo: Stephan Szabo <sszabo@bigpanda.com>
303
386c2272 304teejay : Aaron Trevena <teejay@cpan.org>
305
84e3c114 306Todd Lipcon
e063fe2c 307
6eb6264e 308Tom Hukins
309
d3b0e369 310typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 311
4740bdb7 312victori: Victor Igumnov <victori@cpan.org>
313
d3b0e369 314wdh: Will Hawes
4c248161 315
00c03ced 316willert: Sebastian Willert <willert@cpan.org>
317
d3b0e369 318zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 319
35210f02 320norbi: Norbert Buchmuller <norbi@nix.hu>
321
34d52be2 322=head1 LICENSE
323
324You may distribute this code under the same terms as Perl itself.
325
326=cut