restore mk_classaccessor
[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
6fa7228e 26$VERSION = '0.08002';
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
154This project is still under rapid development, so features added in the
2053ab2a 155latest major release may not work 100% yet -- check the Changes if you run
f183eccd 156into trouble, and beware of anything explicitly marked EXPERIMENTAL. Failing
157test cases are *always* welcome and point releases are put out rapidly as
158bugs are found and fixed.
159
86beca1d 160Even so, we do our best to maintain full backwards compatibility for published
2053ab2a 161APIs, since DBIx::Class is used in production in a number of organisations.
162The test suite is quite substantial, and several developer releases are
86beca1d 163generally made to CPAN before the -current branch is merged back to trunk for
164a major release.
f183eccd 165
2053ab2a 166The community can be found via:
f183eccd 167
168 Mailing list: http://lists.rawmode.org/mailman/listinfo/dbix-class/
169
170 SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
171
172 Wiki: http://dbix-class.shadowcatsystems.co.uk/
173
174 IRC: irc.perl.org#dbix-class
175
176=head1 WHERE TO GO NEXT
177
2ca930b4 178L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
179the modules where you will find documentation.
076652e8 180
3942ab4d 181=head1 AUTHOR
34d52be2 182
266bdcc3 183mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 184
3942ab4d 185=head1 CONTRIBUTORS
186
266bdcc3 187abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
84e3c114 188
266bdcc3 189andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 190
266bdcc3 191ank: Andres Kievsky
3942ab4d 192
ce4c07df 193ash: Ash Berlin <ash@cpan.org>
194
967a4c40 195blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 196
62eb8fe8 197bluefeet: Aran Deltac <bluefeet@cpan.org>
198
d3b0e369 199captainL: Luke Saunders <luke.saunders@gmail.com>
200
201castaway: Jess Robinson
3942ab4d 202
266bdcc3 203claco: Christopher H. Laco
ccb9c9b1 204
266bdcc3 205clkao: CL Kao
3942ab4d 206
e21dfd6a 207da5id: David Jack Olrik <djo@cpan.org>
18360aed 208
266bdcc3 209dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 210
9382ad07 211dnm: Justin Wheeler <jwheeler@datademons.com>
212
d3b0e369 213draven: Marcus Ramberg <mramberg@cpan.org>
4685e006 214
266bdcc3 215dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 216
5cffe785 217dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 218
d3b0e369 219gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 220
d3b0e369 221jesper: Jesper Krogh
5fb0c64c 222
102a2984 223jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 224
1aec4bac 225jshirley: J. Shirley <jshirley@gmail.com>
226
d3b0e369 227konobi: Scott McWhirter
535fc2ee 228
d3b0e369 229LTJake: Brian Cassidy <bricas@cpan.org>
103e3e03 230
77e7e47d 231ned: Neil de Carteret
232
266bdcc3 233nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 234
d3b0e369 235ningu: David Kamholz <dkamholz@cpan.org>
236
237Numa: Dan Sully <daniel@cpan.org>
238
266bdcc3 239paulm: Paul Makepeace
4763f4b7 240
d3b0e369 241penguin: K J Cheetham
242
266bdcc3 243phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 244
d3b0e369 245quicksilver: Jules Bean
022e0893 246
d3b0e369 247sc_: Just Another Perl Hacker
ba606e58 248
266bdcc3 249scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 250
637ca936 251sszabo: Stephan Szabo <sszabo@bigpanda.com>
252
84e3c114 253Todd Lipcon
e063fe2c 254
d3b0e369 255typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 256
4740bdb7 257victori: Victor Igumnov <victori@cpan.org>
258
d3b0e369 259wdh: Will Hawes
4c248161 260
00c03ced 261willert: Sebastian Willert <willert@cpan.org>
262
d3b0e369 263zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 264
34d52be2 265=head1 LICENSE
266
267You may distribute this code under the same terms as Perl itself.
268
269=cut