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