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