More try::tiny conversions
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class.pm
CommitLineData
ea2e61bf 1package DBIx::Class;
2
5d283305 3use strict;
4use warnings;
5
329d7385 6use MRO::Compat;
d38cd95c 7use mro 'c3';
329d7385 8
2527233b 9use DBIx::Class::Optional::Dependencies;
10
5d283305 11use vars qw($VERSION);
d38cd95c 12use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
11736b4c 13use DBIx::Class::StartupCheck;
20674fcd 14use Try::Tiny;
3e110410 15
ade0fe3b 16sub mk_classdata {
77d518d1 17 shift->mk_classaccessor(@_);
18}
19
20sub mk_classaccessor {
21 my $self = shift;
ade0fe3b 22 $self->mk_group_accessors('inherited', $_[0]);
77d518d1 23 $self->set_inherited(@_) if @_ > 1;
3e110410 24}
3c0068c1 25
7411204b 26sub component_base_class { 'DBIx::Class' }
227d4dee 27
95da6f35 28# Always remember to do all digits for the version even if they're 0
29# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
30# brain damage and presumably various other packaging systems too
a3356adb 31$VERSION = '0.08121_01';
748ab0dc 32
033955f9 33$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
b8777a0d 34
f0750722 35sub MODIFY_CODE_ATTRIBUTES {
b5d2c57f 36 my ($class,$code,@attrs) = @_;
37 $class->mk_classdata('__attr_cache' => {})
38 unless $class->can('__attr_cache');
39 $class->__attr_cache->{$code} = [@attrs];
40 return ();
f0750722 41}
42
da95b45f 43sub _attr_cache {
b5d2c57f 44 my $self = shift;
45 my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
9780718f 46
47 return {
48 %$cache,
49 %{ $self->maybe::next::method || {} },
20674fcd 50 };
da95b45f 51}
52
ea2e61bf 531;
34d52be2 54
75d07914 55=head1 NAME
34d52be2 56
7e4b2f59 57DBIx::Class - Extensible and flexible object <-> relational mapper.
34d52be2 58
3b1c2bbd 59=head1 GETTING HELP/SUPPORT
60
61The community can be found via:
62
a06e1181 63=over
3b1c2bbd 64
a06e1181 65=item * IRC: L<irc.perl.org#dbix-class (click for instant chatroom login)
66|http://mibbit.com/chat/#dbix-class@irc.perl.org>
3b1c2bbd 67
a06e1181 68=item * Mailing list: L<http://lists.scsys.co.uk/mailman/listinfo/dbix-class>
3b1c2bbd 69
a06e1181 70=item * RT Bug Tracker: L<https://rt.cpan.org/Dist/Display.html?Queue=DBIx-Class>
71
72=item * SVNWeb: L<http://dev.catalyst.perl.org/svnweb/bast/browse/DBIx-Class/0.08>
73
74=item * SVN: L<http://dev.catalyst.perl.org/repos/bast/DBIx-Class/0.08>
75
76=back
3b1c2bbd 77
34d52be2 78=head1 SYNOPSIS
79
bd077b47 80Create a schema class called MyDB/Schema.pm:
34d52be2 81
bd077b47 82 package MyDB::Schema;
a0638a7b 83 use base qw/DBIx::Class::Schema/;
34d52be2 84
f0bb26f3 85 __PACKAGE__->load_namespaces();
daec44b8 86
a0638a7b 87 1;
daec44b8 88
30e1753a 89Create a result class to represent artists, who have many CDs, in
f0bb26f3 90MyDB/Schema/Result/Artist.pm:
daec44b8 91
30e1753a 92See L<DBIx::Class::ResultSource> for docs on defining result classes.
93
f0bb26f3 94 package MyDB::Schema::Result::Artist;
d88ecca6 95 use base qw/DBIx::Class::Core/;
daec44b8 96
a0638a7b 97 __PACKAGE__->table('artist');
98 __PACKAGE__->add_columns(qw/ artistid name /);
99 __PACKAGE__->set_primary_key('artistid');
f0bb26f3 100 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
daec44b8 101
a0638a7b 102 1;
daec44b8 103
30e1753a 104A result class to represent a CD, which belongs to an artist, in
f0bb26f3 105MyDB/Schema/Result/CD.pm:
39fe0e65 106
f0bb26f3 107 package MyDB::Schema::Result::CD;
d88ecca6 108 use base qw/DBIx::Class::Core/;
39fe0e65 109
d88ecca6 110 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
a0638a7b 111 __PACKAGE__->table('cd');
bd077b47 112 __PACKAGE__->add_columns(qw/ cdid artistid title year /);
a0638a7b 113 __PACKAGE__->set_primary_key('cdid');
bd077b47 114 __PACKAGE__->belongs_to(artist => 'MyDB::Schema::Artist', 'artistid');
39fe0e65 115
a0638a7b 116 1;
39fe0e65 117
a0638a7b 118Then you can use these classes in your application's code:
39fe0e65 119
a0638a7b 120 # Connect to your database.
bd077b47 121 use MyDB::Schema;
122 my $schema = MyDB::Schema->connect($dbi_dsn, $user, $pass, \%dbi_params);
a0638a7b 123
124 # Query for all artists and put them in an array,
125 # or retrieve them as a result set object.
30e1753a 126 # $schema->resultset returns a DBIx::Class::ResultSet
2053ab2a 127 my @all_artists = $schema->resultset('Artist')->all;
128 my $all_artists_rs = $schema->resultset('Artist');
126042ee 129
30e1753a 130 # Output all artists names
4e8ffded 131 # $artist here is a DBIx::Class::Row, which has accessors
16ccb4fe 132 # for all its columns. Rows are also subclasses of your Result class.
85067746 133 foreach $artist (@all_artists) {
30e1753a 134 print $artist->name, "\n";
135 }
136
a0638a7b 137 # Create a result set to search for artists.
86beca1d 138 # This does not query the DB.
2053ab2a 139 my $johns_rs = $schema->resultset('Artist')->search(
6576ef54 140 # Build your WHERE using an SQL::Abstract structure:
2053ab2a 141 { name => { like => 'John%' } }
a0638a7b 142 );
39fe0e65 143
2053ab2a 144 # Execute a joined query to get the cds.
a0638a7b 145 my @all_john_cds = $johns_rs->search_related('cds')->all;
448c8424 146
f0bb26f3 147 # Fetch the next available row.
a0638a7b 148 my $first_john = $johns_rs->next;
448c8424 149
2053ab2a 150 # Specify ORDER BY on the query.
a0638a7b 151 my $first_john_cds_by_title_rs = $first_john->cds(
152 undef,
153 { order_by => 'title' }
154 );
448c8424 155
bd077b47 156 # Create a result set that will fetch the artist data
2053ab2a 157 # at the same time as it fetches CDs, using only one query.
884559b1 158 my $millennium_cds_rs = $schema->resultset('CD')->search(
a0638a7b 159 { year => 2000 },
160 { prefetch => 'artist' }
161 );
448c8424 162
880a1a0c 163 my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
bd077b47 164 my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
076652e8 165
264f1571 166 # new() makes a DBIx::Class::Row object but doesnt insert it into the DB.
167 # create() is the same as new() then insert().
884559b1 168 my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
f183eccd 169 $new_cd->artist($cd->artist);
f183eccd 170 $new_cd->insert; # Auto-increment primary key filled in after INSERT
f183eccd 171 $new_cd->title('Fork');
172
884559b1 173 $schema->txn_do(sub { $new_cd->update }); # Runs the update in a transaction
f183eccd 174
bd077b47 175 # change the year of all the millennium CDs at once
176 $millennium_cds_rs->update({ year => 2002 });
f183eccd 177
178=head1 DESCRIPTION
179
180This is an SQL to OO mapper with an object API inspired by L<Class::DBI>
bd077b47 181(with a compatibility layer as a springboard for porting) and a resultset API
f183eccd 182that allows abstract encapsulation of database operations. It aims to make
183representing queries in your code as perl-ish as possible while still
a0638a7b 184providing access to as many of the capabilities of the database as possible,
f183eccd 185including retrieving related records from multiple tables in a single query,
bd077b47 186JOIN, LEFT JOIN, COUNT, DISTINCT, GROUP BY, ORDER BY and HAVING support.
f183eccd 187
188DBIx::Class can handle multi-column primary and foreign keys, complex
189queries and database-level paging, and does its best to only query the
75d07914 190database in order to return something you've directly asked for. If a
191resultset is used as an iterator it only fetches rows off the statement
192handle as requested in order to minimise memory usage. It has auto-increment
2053ab2a 193support for SQLite, MySQL, PostgreSQL, Oracle, SQL Server and DB2 and is
194known to be used in production on at least the first four, and is fork-
75d07914 195and thread-safe out of the box (although your DBD may not be).
f183eccd 196
dfccde48 197This project is still under rapid development, so large new features may be
198marked EXPERIMENTAL - such APIs are still usable but may have edge bugs.
199Failing test cases are *always* welcome and point releases are put out rapidly
200as bugs are found and fixed.
201
202We do our best to maintain full backwards compatibility for published
203APIs, since DBIx::Class is used in production in many organisations,
204and even backwards incompatible changes to non-published APIs will be fixed
205if they're reported and doing so doesn't cost the codebase anything.
206
264f1571 207The test suite is quite substantial, and several developer releases
208are generally made to CPAN before the branch for the next release is
209merged back to trunk for a major release.
f183eccd 210
f183eccd 211=head1 WHERE TO GO NEXT
212
2ca930b4 213L<DBIx::Class::Manual::DocMap> lists each task you might want help on, and
214the modules where you will find documentation.
076652e8 215
3942ab4d 216=head1 AUTHOR
34d52be2 217
266bdcc3 218mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 219
dfccde48 220(I mostly consider myself "project founder" these days but the AUTHOR heading
221is traditional :)
222
3942ab4d 223=head1 CONTRIBUTORS
224
907ed671 225abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
84e3c114 226
6d84db2c 227aherzog: Adam Herzog <adam@herzogdesigns.com>
228
b703fec7 229amoore: Andrew Moore <amoore@cpan.org>
230
266bdcc3 231andyg: Andy Grundman <andy@hybridized.org>
3942ab4d 232
266bdcc3 233ank: Andres Kievsky
3942ab4d 234
624764ae 235arcanez: Justin Hunter <justin.d.hunter@gmail.com>
236
ce4c07df 237ash: Ash Berlin <ash@cpan.org>
238
3d5bd2af 239bert: Norbert Csongradi <bert@cpan.org>
240
967a4c40 241blblack: Brandon L. Black <blblack@gmail.com>
3942ab4d 242
62eb8fe8 243bluefeet: Aran Deltac <bluefeet@cpan.org>
244
f856fe01 245boghead: Bryan Beeley <cpan@beeley.org>
246
bcb8f3ed 247bricas: Brian Cassidy <bricas@cpan.org>
248
3d7e3e05 249brunov: Bruno Vecchi <vecchi.b@gmail.com>
250
281719d2 251caelum: Rafael Kitover <rkitover@cpan.org>
252
d3b0e369 253castaway: Jess Robinson
3942ab4d 254
266bdcc3 255claco: Christopher H. Laco
ccb9c9b1 256
266bdcc3 257clkao: CL Kao
3942ab4d 258
e21dfd6a 259da5id: David Jack Olrik <djo@cpan.org>
18360aed 260
13de943d 261debolaz: Anders Nor Berle <berle@cpan.org>
262
d1f542db 263dew: Dan Thomas <dan@godders.org>
264
266bdcc3 265dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
ccb9c9b1 266
9382ad07 267dnm: Justin Wheeler <jwheeler@datademons.com>
268
0818c9a7 269dpetrov: Dimitar Petrov <mitakaa@gmail.com>
270
266bdcc3 271dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
4685e006 272
5cffe785 273dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
8fe164b9 274
ade0fe3b 275frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
276
b4987ed0 277goraxe: Gordon Irving <goraxe@cpan.org>
278
d3b0e369 279gphat: Cory G Watson <gphat@cpan.org>
ad3d2d7c 280
e758ffe6 281groditi: Guillermo Roditi <groditi@cpan.org>
282
157ce0cf 283hobbs: Andrew Rodland <arodland@cpan.org>
284
5d779578 285ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
286
bee21976 287jasonmay: Jason May <jason.a.may@gmail.com>
288
d3b0e369 289jesper: Jesper Krogh
5fb0c64c 290
4a743a00 291jgoulah: John Goulah <jgoulah@cpan.org>
292
102a2984 293jguenther: Justin Guenther <jguenther@cpan.org>
d7c4c15c 294
a14a46e2 295jhannah: Jay Hannah <jay@jays.net>
296
8b93a938 297jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
298
11736b4c 299jon: Jon Schutz <jjschutz@cpan.org>
300
1aec4bac 301jshirley: J. Shirley <jshirley@gmail.com>
302
d3b0e369 303konobi: Scott McWhirter
535fc2ee 304
4367679a 305lukes: Luke Saunders <luke.saunders@gmail.com>
306
709ea492 307marcus: Marcus Ramberg <mramberg@cpan.org>
308
114780ee 309mattlaw: Matt Lawrence
310
58755bba 311michaelr: Michael Reddick <michael.reddick@gmail.com>
312
77e7e47d 313ned: Neil de Carteret
314
266bdcc3 315nigel: Nigel Metheringham <nigelm@cpan.org>
6565b410 316
d3b0e369 317ningu: David Kamholz <dkamholz@cpan.org>
318
66cf3a84 319Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
320
20b4c148 321norbi: Norbert Buchmuller <norbi@nix.hu>
322
48580715 323nuba: Nuba Princigalli <nuba@cpan.org>
324
d3b0e369 325Numa: Dan Sully <daniel@cpan.org>
326
dc571b76 327ovid: Curtis "Ovid" Poe <ovid@cpan.org>
328
bf356c54 329oyse: Øystein Torget <oystein.torget@dnv.com>
330
266bdcc3 331paulm: Paul Makepeace
4763f4b7 332
d3b0e369 333penguin: K J Cheetham
334
8cfef6f5 335perigrin: Chris Prather <chris@prather.org>
336
14899528 337peter: Peter Collingbourne <peter@pcc.me.uk>
caac1708 338
266bdcc3 339phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
a53b95f1 340
56fadd8f 341plu: Johannes Plunien <plu@cpan.org>
342
d3b0e369 343quicksilver: Jules Bean
022e0893 344
4ed01b34 345rafl: Florian Ragwitz <rafl@debian.org>
346
7ff0dace 347rbuels: Robert Buels <rmb32@cornell.edu>
348
0da8b7da 349rdj: Ryan D Johnson <ryan@innerfence.com>
350
66b1e361 351ribasushi: Peter Rabbitson <ribasushi@cpan.org>
d76e282a 352
b487918c 353rjbs: Ricardo Signes <rjbs@cpan.org>
354
6ffb5be5 355robkinyon: Rob Kinyon <rkinyon@cpan.org>
356
e4c9f3f0 357Roman: Roman Filippov <romanf@cpan.org>
358
d3b0e369 359sc_: Just Another Perl Hacker
ba606e58 360
266bdcc3 361scotty: Scotty Allen <scotty@scottyallen.com>
181a28f4 362
1c133e22 363semifor: Marc Mims <marc@questright.com>
364
20b4c148 365solomon: Jared Johnson <jaredj@nmgi.com>
366
88f937fb 367spb: Stephen Bennett <stephen@freenode.net>
368
637ca936 369sszabo: Stephan Szabo <sszabo@bigpanda.com>
370
386c2272 371teejay : Aaron Trevena <teejay@cpan.org>
372
84e3c114 373Todd Lipcon
e063fe2c 374
6eb6264e 375Tom Hukins
376
2e4b6d78 377tonvoon: Ton Voon <tonvoon@cpan.org>
378
d15e3fc5 379triode: Pete Gamache <gamache@cpan.org>
380
d3b0e369 381typester: Daisuke Murase <typester@cpan.org>
c0e7b4e5 382
4740bdb7 383victori: Victor Igumnov <victori@cpan.org>
384
d3b0e369 385wdh: Will Hawes
4c248161 386
00c03ced 387willert: Sebastian Willert <willert@cpan.org>
388
66d2a14e 389wreis: Wallace Reis <wreis@cpan.org>
390
d3b0e369 391zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
78060df8 392
c1807ed5 393Possum: Daniel LeWarne <possum@cpan.org>
394
b38e10bd 395=head1 COPYRIGHT
396
48580715 397Copyright (c) 2005 - 2010 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
b38e10bd 398as listed above.
399
96154ef7 400=head1 LICENSE
401
402This library is free software and may be distributed under the same terms
403as perl itself.
404
34d52be2 405=cut