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