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