9 use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
10 use DBIx::Class::StartupCheck;
13 shift->mk_classaccessor(@_);
16 sub mk_classaccessor {
18 $self->mk_group_accessors('inherited', $_[0]);
19 $self->set_inherited(@_) if @_ > 1;
22 sub component_base_class { 'DBIx::Class' }
24 # Always remember to do all digits for the version even if they're 0
25 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
26 # brain damage and presumably various other packaging systems too
30 $VERSION = eval $VERSION; # numify for warning-free dev releases
32 sub MODIFY_CODE_ATTRIBUTES {
33 my ($class,$code,@attrs) = @_;
34 $class->mk_classdata('__attr_cache' => {})
35 unless $class->can('__attr_cache');
36 $class->__attr_cache->{$code} = [@attrs];
42 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
43 my $rest = eval { $self->next::method };
44 return $@ ? $cache : { %$cache, %$rest };
51 DBIx::Class - Extensible and flexible object <-> relational mapper.
53 =head1 GETTING HELP/SUPPORT
55 The community can be found via:
57 Mailing list: http://lists.scsys.co.uk/mailman/listinfo/dbix-class/
59 SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
61 SVNWeb: http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/
63 IRC: irc.perl.org#dbix-class
67 Create a schema class called MyDB/Schema.pm:
70 use base qw/DBIx::Class::Schema/;
72 __PACKAGE__->load_namespaces();
76 Create a table class to represent artists, who have many CDs, in
77 MyDB/Schema/Result/Artist.pm:
79 package MyDB::Schema::Result::Artist;
80 use base qw/DBIx::Class/;
82 __PACKAGE__->load_components(qw/Core/);
83 __PACKAGE__->table('artist');
84 __PACKAGE__->add_columns(qw/ artistid name /);
85 __PACKAGE__->set_primary_key('artistid');
86 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
90 A table class to represent a CD, which belongs to an artist, in
91 MyDB/Schema/Result/CD.pm:
93 package MyDB::Schema::Result::CD;
94 use base qw/DBIx::Class/;
96 __PACKAGE__->load_components(qw/Core/);
97 __PACKAGE__->table('cd');
98 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
99 __PACKAGE__->set_primary_key('cdid');
100 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
104 Then you can use these classes in your application's code:
106 # Connect to your database.
108 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
110 # Query for all artists and put them in an array,
111 # or retrieve them as a result set object.
112 my @all_artists = $schema->resultset('Artist')->all;
113 my $all_artists_rs = $schema->resultset('Artist');
115 # Create a result set to search for artists.
116 # This does not query the DB.
117 my $johns_rs = $schema->resultset('Artist')->search(
118 # Build your WHERE using an SQL::Abstract structure:
119 { name => { like => 'John%' } }
122 # Execute a joined query to get the cds.
123 my @all_john_cds = $johns_rs->search_related('cds')->all;
125 # Fetch the next available row.
126 my $first_john = $johns_rs->next;
128 # Specify ORDER BY on the query.
129 my $first_john_cds_by_title_rs = $first_john->cds(
131 { order_by => 'title' }
134 # Create a result set that will fetch the artist data
135 # at the same time as it fetches CDs, using only one query.
136 my $millennium_cds_rs = $schema->resultset('CD')->search(
138 { prefetch => 'artist' }
141 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
142 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
144 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
145 # create() is the same as new() then insert().
146 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
147 $new_cd->artist($cd->artist);
148 $new_cd->insert; # Auto-increment primary key filled in after INSERT
149 $new_cd->title('Fork');
151 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
153 # change the year of all the millennium CDs at once
154 $millennium_cds_rs->update({ year => 2002 });
158 This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
159 (with a compatibility layer as a springboard for porting) and a resultset API
160 that allows abstract encapsulation of database operations. It aims to make
161 representing queries in your code as perl-ish as possible while still
162 providing access to as many of the capabilities of the database as possible,
163 including retrieving related records from multiple tables in a single query,
164 JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
166 DBIx::Class can handle multi-column primary and foreign keys, complex
167 queries and database-level paging, and does its best to only query the
168 database in order to return something you've directly asked for. If a
169 resultset is used as an iterator it only fetches rows off the statement
170 handle as requested in order to minimise memory usage. It has auto-increment
171 support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
172 known to be used in production on at least the first four, and is fork-
173 and thread-safe out of the box (although your DBD may not be).
175 This project is still under rapid development, so large new features may be
176 marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
177 Failing test cases are *always* welcome and point releases are put out rapidly
178 as bugs are found and fixed.
180 We do our best to maintain full backwards compatibility for published
181 APIs, since DBIx::Class is used in production in many organisations,
182 and even backwards incompatible changes to non-published APIs will be fixed
183 if they're reported and doing so doesn't cost the codebase anything.
185 The test suite is quite substantial, and several developer releases
186 are generally made to CPAN before the branch for the next release is
187 merged back to trunk for a major release.
189 =head1 WHERE TO GO NEXT
191 L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
192 the modules where you will find documentation.
196 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
198 (I mostly consider myself "project founder" these days but the AUTHOR heading
203 abraxxa: Alexander Hartmaier <alex_hartmaier@hotmail.com>
205 aherzog: Adam Herzog <adam@herzogdesigns.com>
207 andyg: Andy Grundman <andy@hybridized.org>
211 arcanez: Justin Hunter <justin.d.hunter@gmail.com>
213 ash: Ash Berlin <ash@cpan.org>
215 bert: Norbert Csongradi <bert@cpan.org>
217 blblack: Brandon L. Black <blblack@gmail.com>
219 bluefeet: Aran Deltac <bluefeet@cpan.org>
221 bricas: Brian Cassidy <bricas@cpan.org>
223 caelum: Rafael Kitover <rkitover@cpan.org>
225 castaway: Jess Robinson
227 claco: Christopher H. Laco
231 da5id: David Jack Olrik <djo@cpan.org>
233 debolaz: Anders Nor Berle <berle@cpan.org>
235 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
237 dnm: Justin Wheeler <jwheeler@datademons.com>
239 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
241 dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
243 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
245 gphat: Cory G Watson <gphat@cpan.org>
247 groditi: Guillermo Roditi <groditi@cpan.org>
249 ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
251 jasonmay: Jason May <jason.a.may@gmail.com>
255 jgoulah: John Goulah <jgoulah@cpan.org>
257 jguenther: Justin Guenther <jguenther@cpan.org>
259 jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
261 jon: Jon Schutz <jjschutz@cpan.org>
263 jshirley: J. Shirley <jshirley@gmail.com>
265 konobi: Scott McWhirter
267 lukes: Luke Saunders <luke.saunders@gmail.com>
269 marcus: Marcus Ramberg <mramberg@cpan.org>
271 mattlaw: Matt Lawrence
273 michaelr: Michael Reddick <michael.reddick@gmail.com>
275 ned: Neil de Carteret
277 nigel: Nigel Metheringham <nigelm@cpan.org>
279 ningu: David Kamholz <dkamholz@cpan.org>
281 Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
283 norbi: Norbert Buchmuller <norbi@nix.hu>
285 Numa: Dan Sully <daniel@cpan.org>
287 oyse: Øystein Torget <oystein.torget@dnv.com>
289 paulm: Paul Makepeace
291 penguin: K J Cheetham
293 perigrin: Chris Prather <chris@prather.org>
295 peter: Peter Collingbourne <peter@pcc.me.uk>
297 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
299 plu: Johannes Plunien <plu@cpan.org>
301 quicksilver: Jules Bean
303 rafl: Florian Ragwitz <rafl@debian.org>
305 rdj: Ryan D Johnson <ryan@innerfence.com>
307 ribasushi: Peter Rabbitson <rabbit+dbic@rabbit.us>
309 rjbs: Ricardo Signes <rjbs@cpan.org>
311 robkinyon: Rob Kinyon <rkinyon@cpan.org>
313 sc_: Just Another Perl Hacker
315 scotty: Scotty Allen <scotty@scottyallen.com>
317 semifor: Marc Mims <marc@questright.com>
319 solomon: Jared Johnson <jaredj@nmgi.com>
321 sszabo: Stephan Szabo <sszabo@bigpanda.com>
323 teejay : Aaron Trevena <teejay@cpan.org>
329 typester: Daisuke Murase <typester@cpan.org>
331 victori: Victor Igumnov <victori@cpan.org>
335 willert: Sebastian Willert <willert@cpan.org>
337 wreis: Wallace Reis <wreis@cpan.org>
339 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
343 You may distribute this code under the same terms as Perl itself.