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