Fixed incorect class name in sqlt examples
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / Cookbook.pod
CommitLineData
3b44ccc6 1=head1 NAME
9c82c181 2
40dbc108 3DBIx::Class::Manual::Cookbook - Miscellaneous recipes
ee38fa40 4
40dbc108 5=head1 RECIPES
2913b2d3 6
bade79c4 7=head2 Searching
faf62551 8
bade79c4 9=head3 Paged results
faf62551 10
bade79c4 11When you expect a large number of results, you can ask L<DBIx::Class> for a
12paged resultset, which will fetch only a small number of records at a time:
faf62551 13
bade79c4 14 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 15 undef,
bade79c4 16 {
17 page => 1, # page to return (defaults to 1)
18 rows => 10, # number of results per page
19 },
20 );
faf62551 21
bade79c4 22 return $rs->all(); # all records for page 1
faf62551 23
bade79c4 24The C<page> attribute does not have to be specified in your search:
25
26 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 27 undef,
bade79c4 28 {
29 rows => 10,
30 }
31 );
faf62551 32
bade79c4 33 return $rs->page(1); # DBIx::Class::ResultSet containing first 10 records
faf62551 34
35In either of the above cases, you can return a L<Data::Page> object for the
bade79c4 36resultset (suitable for use in e.g. a template) using the C<pager> method:
faf62551 37
bade79c4 38 return $rs->pager();
faf62551 39
bade79c4 40=head3 Complex WHERE clauses
2913b2d3 41
40dbc108 42Sometimes you need to formulate a query using specific operators:
43
ea6309e2 44 my @albums = $schema->resultset('Album')->search({
35d4fe78 45 artist => { 'like', '%Lamb%' },
46 title => { 'like', '%Fear of Fours%' },
47 });
40dbc108 48
49This results in something like the following C<WHERE> clause:
50
35d4fe78 51 WHERE artist LIKE '%Lamb%' AND title LIKE '%Fear of Fours%'
40dbc108 52
53Other queries might require slightly more complex logic:
54
ea6309e2 55 my @albums = $schema->resultset('Album')->search({
35d4fe78 56 -or => [
57 -and => [
58 artist => { 'like', '%Smashing Pumpkins%' },
59 title => 'Siamese Dream',
60 ],
61 artist => 'Starchildren',
62 ],
63 });
40dbc108 64
65This results in the following C<WHERE> clause:
66
35d4fe78 67 WHERE ( artist LIKE '%Smashing Pumpkins%' AND title = 'Siamese Dream' )
68 OR artist = 'Starchildren'
40dbc108 69
70For more information on generating complex queries, see
71L<SQL::Abstract/WHERE CLAUSES>.
ee38fa40 72
bade79c4 73=head3 Using specific columns
faf62551 74
bade79c4 75When you only want selected columns from a table, you can use C<cols> to
76specify which ones you need:
faf62551 77
bade79c4 78 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 79 undef,
bade79c4 80 {
5e8b1b2a 81 columns => [qw/ name /]
bade79c4 82 }
83 );
faf62551 84
bade79c4 85 # Equivalent SQL:
86 # SELECT artist.name FROM artist
faf62551 87
bade79c4 88=head3 Using database functions or stored procedures
faf62551 89
bade79c4 90The combination of C<select> and C<as> can be used to return the result of a
91database function or stored procedure as a column value. You use C<select> to
92specify the source for your column value (e.g. a column name, function, or
93stored procedure name). You then use C<as> to set the column name you will use
94to access the returned value:
faf62551 95
bade79c4 96 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 97 undef,
bade79c4 98 {
99 select => [ 'name', { LENGTH => 'name' } ],
100 as => [qw/ name name_length /],
101 }
102 );
faf62551 103
bade79c4 104 # Equivalent SQL:
105 # SELECT name name, LENGTH( name ) name_length
106 # FROM artist
faf62551 107
108If your alias exists as a column in your base class (i.e. it was added with
bade79c4 109C<add_columns>), you just access it as normal. Our C<Artist> class has a C<name>
110column, so we just use the C<name> accessor:
faf62551 111
bade79c4 112 my $artist = $rs->first();
113 my $name = $artist->name();
faf62551 114
115If on the other hand the alias does not correspond to an existing column, you
bade79c4 116can get the value using the C<get_column> accessor:
faf62551 117
bade79c4 118 my $name_length = $artist->get_column('name_length');
faf62551 119
bade79c4 120If you don't like using C<get_column>, you can always create an accessor for
faf62551 121any of your aliases using either of these:
122
bade79c4 123 # Define accessor manually:
124 sub name_length { shift->get_column('name_length'); }
faf62551 125
bade79c4 126 # Or use DBIx::Class::AccessorGroup:
127 __PACKAGE__->mk_group_accessors('column' => 'name_length');
faf62551 128
bade79c4 129=head3 SELECT DISTINCT with multiple columns
faf62551 130
bade79c4 131 my $rs = $schema->resultset('Foo')->search(
5e8b1b2a 132 undef,
bade79c4 133 {
134 select => [
135 { distinct => [ $source->columns ] }
136 ],
137 as => [ $source->columns ]
138 }
139 );
faf62551 140
286f32b3 141 my $count = $rs->next->get_column('count');
142
bade79c4 143=head3 SELECT COUNT(DISTINCT colname)
6607ee1b 144
bade79c4 145 my $rs = $schema->resultset('Foo')->search(
5e8b1b2a 146 undef,
bade79c4 147 {
148 select => [
149 { count => { distinct => 'colname' } }
150 ],
151 as => [ 'count' ]
152 }
153 );
6607ee1b 154
bade79c4 155=head3 Grouping results
156
157L<DBIx::Class> supports C<GROUP BY> as follows:
158
159 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 160 undef,
bade79c4 161 {
162 join => [qw/ cds /],
163 select => [ 'name', { count => 'cds.cdid' } ],
164 as => [qw/ name cd_count /],
165 group_by => [qw/ name /]
166 }
167 );
6607ee1b 168
bade79c4 169 # Equivalent SQL:
170 # SELECT name, COUNT( cds.cdid ) FROM artist me
171 # LEFT JOIN cd cds ON ( cds.artist = me.artistid )
172 # GROUP BY name
6607ee1b 173
74dc2edc 174=head3 Predefined searches
175
176You can write your own DBIx::Class::ResultSet class by inheriting from it
177and define often used searches as methods:
178
179 package My::DBIC::ResultSet::CD;
180 use strict;
181 use warnings;
182 use base 'DBIx::Class::ResultSet';
183
184 sub search_cds_ordered {
185 my ($self) = @_;
186
187 return $self->search(
188 {},
189 { order_by => 'name DESC' },
190 );
191 }
192
193 1;
194
195To use your resultset, first tell DBIx::Class to create an instance of it
196for you, in your My::DBIC::Schema::CD class:
197
198 __PACKAGE__->resultset_class('My::DBIC::ResultSet::CD');
199
200Then call your new method in your code:
201
202 my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
203
204
d6ed6a67 205=head3 Predefined searches without writing a ResultSet class
206
207Alternatively you can automatically generate a DBIx::Class::ResultSet
208class by using the ResultSetManager component and tagging your method
209as ResultSet:
210
211 __PACKAGE__->load_components(qw/ ResultSetManager Core /);
212
213 sub search_cds_ordered : ResultSet {
214 my ($self) = @_;
215 return $self->search(
216 {},
217 { order_by => 'name DESC' },
218 );
219 }
220
221Then call your method in the same way from your code:
222
223 my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
224
87980de7 225=head2 Using joins and prefetch
226
bade79c4 227You can use the C<join> attribute to allow searching on, or sorting your
228results by, one or more columns in a related table. To return all CDs matching
229a particular artist name:
ea6309e2 230
bade79c4 231 my $rs = $schema->resultset('CD')->search(
232 {
233 'artist.name' => 'Bob Marley'
234 },
235 {
236 join => [qw/artist/], # join the artist table
237 }
238 );
239
240 # Equivalent SQL:
241 # SELECT cd.* FROM cd
242 # JOIN artist ON cd.artist = artist.id
243 # WHERE artist.name = 'Bob Marley'
244
245If required, you can now sort on any column in the related tables by including
246it in your C<order_by> attribute:
247
248 my $rs = $schema->resultset('CD')->search(
249 {
250 'artist.name' => 'Bob Marley'
251 },
252 {
253 join => [qw/ artist /],
254 order_by => [qw/ artist.name /]
255 }
256 };
ea6309e2 257
bade79c4 258 # Equivalent SQL:
259 # SELECT cd.* FROM cd
260 # JOIN artist ON cd.artist = artist.id
261 # WHERE artist.name = 'Bob Marley'
262 # ORDER BY artist.name
ea6309e2 263
bade79c4 264Note that the C<join> attribute should only be used when you need to search or
265sort using columns in a related table. Joining related tables when you only
266need columns from the main table will make performance worse!
ea6309e2 267
bade79c4 268Now let's say you want to display a list of CDs, each with the name of the
269artist. The following will work fine:
ea6309e2 270
bade79c4 271 while (my $cd = $rs->next) {
272 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
273 }
ea6309e2 274
bade79c4 275There is a problem however. We have searched both the C<cd> and C<artist> tables
276in our main query, but we have only returned data from the C<cd> table. To get
277the artist name for any of the CD objects returned, L<DBIx::Class> will go back
278to the database:
ea6309e2 279
bade79c4 280 SELECT artist.* FROM artist WHERE artist.id = ?
ea6309e2 281
282A statement like the one above will run for each and every CD returned by our
283main query. Five CDs, five extra queries. A hundred CDs, one hundred extra
284queries!
285
bade79c4 286Thankfully, L<DBIx::Class> has a C<prefetch> attribute to solve this problem.
897342e4 287This allows you to fetch results from related tables in advance:
ea6309e2 288
bade79c4 289 my $rs = $schema->resultset('CD')->search(
290 {
291 'artist.name' => 'Bob Marley'
292 },
293 {
294 join => [qw/ artist /],
295 order_by => [qw/ artist.name /],
296 prefetch => [qw/ artist /] # return artist data too!
297 }
298 );
ea6309e2 299
bade79c4 300 # Equivalent SQL (note SELECT from both "cd" and "artist"):
301 # SELECT cd.*, artist.* FROM cd
302 # JOIN artist ON cd.artist = artist.id
303 # WHERE artist.name = 'Bob Marley'
304 # ORDER BY artist.name
ea6309e2 305
306The code to print the CD list remains the same:
307
bade79c4 308 while (my $cd = $rs->next) {
309 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
310 }
ea6309e2 311
bade79c4 312L<DBIx::Class> has now prefetched all matching data from the C<artist> table,
ea6309e2 313so no additional SQL statements are executed. You now have a much more
314efficient query.
315
77d6b403 316Note that as of L<DBIx::Class> 0.05999_01, C<prefetch> I<can> be used with
317C<has_many> relationships.
ea6309e2 318
bade79c4 319Also note that C<prefetch> should only be used when you know you will
ea6309e2 320definitely use data from a related table. Pre-fetching related tables when you
321only need columns from the main table will make performance worse!
322
bade79c4 323=head3 Multi-step joins
ea6309e2 324
325Sometimes you want to join more than one relationship deep. In this example,
bade79c4 326we want to find all C<Artist> objects who have C<CD>s whose C<LinerNotes>
327contain a specific string:
328
329 # Relationships defined elsewhere:
330 # Artist->has_many('cds' => 'CD', 'artist');
331 # CD->has_one('liner_notes' => 'LinerNotes', 'cd');
332
333 my $rs = $schema->resultset('Artist')->search(
334 {
335 'liner_notes.notes' => { 'like', '%some text%' },
336 },
337 {
338 join => {
339 'cds' => 'liner_notes'
340 }
341 }
342 );
ea6309e2 343
bade79c4 344 # Equivalent SQL:
345 # SELECT artist.* FROM artist
346 # JOIN ( cd ON artist.id = cd.artist )
347 # JOIN ( liner_notes ON cd.id = liner_notes.cd )
348 # WHERE liner_notes.notes LIKE '%some text%'
ea6309e2 349
350Joins can be nested to an arbitrary level. So if we decide later that we
351want to reduce the number of Artists returned based on who wrote the liner
352notes:
353
bade79c4 354 # Relationship defined elsewhere:
355 # LinerNotes->belongs_to('author' => 'Person');
356
357 my $rs = $schema->resultset('Artist')->search(
358 {
359 'liner_notes.notes' => { 'like', '%some text%' },
360 'author.name' => 'A. Writer'
361 },
362 {
363 join => {
364 'cds' => {
365 'liner_notes' => 'author'
ea6309e2 366 }
bade79c4 367 }
368 }
369 );
ea6309e2 370
bade79c4 371 # Equivalent SQL:
372 # SELECT artist.* FROM artist
373 # JOIN ( cd ON artist.id = cd.artist )
374 # JOIN ( liner_notes ON cd.id = liner_notes.cd )
375 # JOIN ( author ON author.id = liner_notes.author )
376 # WHERE liner_notes.notes LIKE '%some text%'
377 # AND author.name = 'A. Writer'
87980de7 378
897342e4 379=head2 Multi-step prefetch
380
381From 0.04999_05 onwards, C<prefetch> can be nested more than one relationship
382deep using the same syntax as a multi-step join:
383
384 my $rs = $schema->resultset('Tag')->search(
5e8b1b2a 385 undef,
897342e4 386 {
387 prefetch => {
388 cd => 'artist'
389 }
390 }
391 );
392
393 # Equivalent SQL:
394 # SELECT tag.*, cd.*, artist.* FROM tag
395 # JOIN cd ON tag.cd = cd.cdid
396 # JOIN artist ON cd.artist = artist.artistid
397
398Now accessing our C<cd> and C<artist> relationships does not need additional
399SQL statements:
400
401 my $tag = $rs->first;
402 print $tag->cd->artist->name;
403
acee4e4d 404=head2 Using relationships
405
406=head3 Create a new row in a related table
407
408 my $book->create_related('author', { name => 'Fred'});
409
410=head3 Search in a related table
411
412Only searches for books named 'Titanic' by the author in $author.
413
414 my $author->search_related('books', { name => 'Titanic' });
415
416=head3 Delete data in a related table
417
418Deletes only the book named Titanic by the author in $author.
419
420 my $author->delete_related('books', { name => 'Titanic' });
421
f8bad769 422=head3 Ordering a relationship result set
423
424If you always want a relation to be ordered, you can specify this when you
425create the relationship.
426
427To order C<< $book->pages >> by descending page_number.
428
429 Book->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} );
430
431
432
87980de7 433=head2 Transactions
434
435As of version 0.04001, there is improved transaction support in
181a28f4 436L<DBIx::Class::Storage::DBI> and L<DBIx::Class::Schema>. Here is an
437example of the recommended way to use it:
87980de7 438
181a28f4 439 my $genus = $schema->resultset('Genus')->find(12);
440
70634260 441 my $coderef2 = sub {
442 $genus->extinct(1);
443 $genus->update;
444 };
445
181a28f4 446 my $coderef1 = sub {
35d4fe78 447 $genus->add_to_species({ name => 'troglodyte' });
448 $genus->wings(2);
449 $genus->update;
70634260 450 $schema->txn_do($coderef2); # Can have a nested transaction
181a28f4 451 return $genus->species;
452 };
453
181a28f4 454 my $rs;
455 eval {
70634260 456 $rs = $schema->txn_do($coderef1);
181a28f4 457 };
458
459 if ($@) { # Transaction failed
460 die "the sky is falling!" #
461 if ($@ =~ /Rollback failed/); # Rollback failed
462
463 deal_with_failed_transaction();
35d4fe78 464 }
87980de7 465
181a28f4 466Nested transactions will work as expected. That is, only the outermost
467transaction will actually issue a commit to the $dbh, and a rollback
468at any level of any transaction will cause the entire nested
469transaction to fail. Support for savepoints and for true nested
40dbc108 470transactions (for databases that support them) will hopefully be added
471in the future.
ee38fa40 472
130c6439 473=head2 Many-to-many relationships
ee38fa40 474
ea6309e2 475This is straightforward using L<DBIx::Class::Relationship::ManyToMany>:
476
bade79c4 477 package My::DB;
478 # ... set up connection ...
479
480 package My::User;
481 use base 'My::DB';
482 __PACKAGE__->table('user');
483 __PACKAGE__->add_columns(qw/id name/);
484 __PACKAGE__->set_primary_key('id');
485 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'user');
486 __PACKAGE__->many_to_many('addresses' => 'user_address', 'address');
487
488 package My::UserAddress;
489 use base 'My::DB';
490 __PACKAGE__->table('user_address');
491 __PACKAGE__->add_columns(qw/user address/);
492 __PACKAGE__->set_primary_key(qw/user address/);
493 __PACKAGE__->belongs_to('user' => 'My::User');
494 __PACKAGE__->belongs_to('address' => 'My::Address');
495
496 package My::Address;
497 use base 'My::DB';
498 __PACKAGE__->table('address');
499 __PACKAGE__->add_columns(qw/id street town area_code country/);
500 __PACKAGE__->set_primary_key('id');
501 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'address');
502 __PACKAGE__->many_to_many('users' => 'user_address', 'user');
503
504 $rs = $user->addresses(); # get all addresses for a user
505 $rs = $address->users(); # get all users for an address
506
507=head2 Setting default values for a row
a00e1684 508
35d4fe78 509It's as simple as overriding the C<new> method. Note the use of
40dbc108 510C<next::method>.
a00e1684 511
35d4fe78 512 sub new {
513 my ( $class, $attrs ) = @_;
40dbc108 514
35d4fe78 515 $attrs->{foo} = 'bar' unless defined $attrs->{foo};
40dbc108 516
35d4fe78 517 $class->next::method($attrs);
518 }
a00e1684 519
4a3c6354 520For more information about C<next::method>, look in the L<Class::C3>
521documentation. See also L<DBIx::Class::Manual::Component> for more
522ways to write your own base classes to do this.
523
524People looking for ways to do "triggers" with DBIx::Class are probably
525just looking for this.
526
25af00d7 527=head2 Stringification
528
40dbc108 529Employ the standard stringification technique by using the C<overload>
462bb847 530module.
531
532To make an object stringify itself as a single column, use something
533like this (replace C<foo> with the column/method of your choice):
25af00d7 534
35d4fe78 535 use overload '""' => 'foo', fallback => 1;
25af00d7 536
462bb847 537For more complex stringification, you can use an anonymous subroutine:
538
539 use overload '""' => sub { $_[0]->name . ", " .
540 $_[0]->address }, fallback => 1;
541
542=head3 Stringifcation Example
543
544Suppose we have two tables: C<Product> and C<Category>. The table
545specifications are:
546
547 Product(id, Description, category)
548 Category(id, Description)
549
550C<category> is a foreign key into the Category table.
551
552If you have a Product object C<$obj> and write something like
553
554 print $obj->category
555
556things will not work as expected.
557
558To obtain, for example, the category description, you should add this
559method to the class defining the Category table:
560
561 use overload "" => sub {
562 my $self = shift;
563
564 return $self->Description;
77713550 565 }, fallback => 1;
462bb847 566
bade79c4 567=head2 Disconnecting cleanly
568
569If you find yourself quitting an app with Control-C a lot during
570development, you might like to put the following signal handler in
571your main database class to make sure it disconnects cleanly:
572
573 $SIG{INT} = sub {
6d1bf0a9 574 __PACKAGE__->storage->disconnect;
bade79c4 575 };
576
362500af 577=head2 Schema import/export
578
579This functionality requires you to have L<SQL::Translator> (also known as
580"SQL Fairy") installed.
581
582To create a DBIx::Class schema from an existing database:
583
584 sqlt --from DBI
585 --to DBIx::Class::File
586 --prefix "MySchema" > MySchema.pm
587
588To create a MySQL database from an existing L<DBIx::Class> schema, convert the
589schema to MySQL's dialect of SQL:
590
54c30987 591 sqlt --from SQL::Translator::Parser::DBIx::Class
592 --to MySQL
593 --DBIx::Class "MySchema.pm" > Schema1.sql
362500af 594
595And import using the mysql client:
596
597 mysql -h "host" -D "database" -u "user" -p < Schema1.sql
598
b0a20454 599=head2 Easy migration from class-based to schema-based setup
600
601You want to start using the schema-based approach to L<DBIx::Class>
602(see L<SchemaIntro.pod>), but have an established class-based setup with lots
603of existing classes that you don't want to move by hand. Try this nifty script
604instead:
605
606 use MyDB;
607 use SQL::Translator;
608
609 my $schema = MyDB->schema_instance;
610
611 my $translator = SQL::Translator->new(
612 debug => $debug || 0,
613 trace => $trace || 0,
614 no_comments => $no_comments || 0,
615 show_warnings => $show_warnings || 0,
616 add_drop_table => $add_drop_table || 0,
617 validate => $validate || 0,
618 parser_args => {
619 'DBIx::Schema' => $schema,
c5f36986 620 },
b0a20454 621 producer_args => {
622 'prefix' => 'My::Schema',
c5f36986 623 },
b0a20454 624 );
625
d240abac 626 $translator->parser('SQL::Translator::Parser::DBIx::Class');
627 $translator->producer('SQL::Translator::Producer::DBIx::Class::File');
b0a20454 628
629 my $output = $translator->translate(@args) or die
630 "Error: " . $translator->error;
631
632 print $output;
633
634You could use L<Module::Find> to search for all subclasses in the MyDB::*
880a1a0c 635namespace, which is currently left as an exercise for the reader.
b0a20454 636
362500af 637=head2 Schema versioning
638
639The following example shows simplistically how you might use DBIx::Class to
640deploy versioned schemas to your customers. The basic process is as follows:
641
da4779ad 642=over 4
643
644=item 1.
645
646Create a DBIx::Class schema
647
648=item 2.
649
650Save the schema
651
652=item 3.
653
654Deploy to customers
655
656=item 4.
657
658Modify schema to change functionality
659
660=item 5.
661
662Deploy update to customers
663
664=back
362500af 665
666=head3 Create a DBIx::Class schema
667
668This can either be done manually, or generated from an existing database as
669described under C<Schema import/export>.
670
671=head3 Save the schema
672
673Use C<sqlt> to transform your schema into an SQL script suitable for your
674customer's database. E.g. for MySQL:
675
54c30987 676 sqlt --from SQL::Translator::Parser::DBIx::Class
362500af 677 --to MySQL
678 --DBIx::Class "MySchema.pm" > Schema1.mysql.sql
679
680If you need to target databases from multiple vendors, just generate an SQL
681script suitable for each. To support PostgreSQL too:
682
54c30987 683 sqlt --from SQL::Translator::DBIx::Class
362500af 684 --to PostgreSQL
685 --DBIx::Class "MySchema.pm" > Schema1.pgsql.sql
686
687=head3 Deploy to customers
688
689There are several ways you could deploy your schema. These are probably
690beyond the scope of this recipe, but might include:
691
da4779ad 692=over 4
693
694=item 1.
695
696Require customer to apply manually using their RDBMS.
697
698=item 2.
699
700Package along with your app, making database dump/schema update/tests
362500af 701all part of your install.
702
da4779ad 703=back
704
362500af 705=head3 Modify the schema to change functionality
706
707As your application evolves, it may be necessary to modify your schema to
708change functionality. Once the changes are made to your schema in DBIx::Class,
709export the modified schema as before, taking care not to overwrite the original:
710
54c30987 711 sqlt --from SQL::Translator::DBIx::Class
362500af 712 --to MySQL
713 --DBIx::Class "Anything.pm" > Schema2.mysql.sql
714
715Next, use sqlt-diff to create an SQL script that will update the customer's
716database schema:
717
718 sqlt-diff --to MySQL Schema1=MySQL Schema2=MySQL > SchemaUpdate.mysql.sql
719
720=head3 Deploy update to customers
721
722The schema update can be deployed to customers using the same method as before.
723
7be93b07 724=head2 Setting limit dialect for SQL::Abstract::Limit
725
726In some cases, SQL::Abstract::Limit cannot determine the dialect of the remote
727SQL-server by looking at the database-handle. This is a common problem when
728using the DBD::JDBC, since the DBD-driver only know that in has a Java-driver
729available, not which JDBC-driver the Java component has loaded.
730This specifically sets the limit_dialect to Microsoft SQL-server (Se more names
731in SQL::Abstract::Limit -documentation.
732
733 __PACKAGE__->storage->sql_maker->limit_dialect('mssql');
734
735The JDBC-bridge is one way of getting access to a MSSQL-server from a platform
736that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
737
2437a1e3 738=head2 Setting quotes for the generated SQL.
739
740If the database contains columnames with spaces and/or reserved words, the
741SQL-query needs to be quoted. This is done using:
742
743 __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
744 __PACKAGE__->storage->sql_maker->name_sep('.');
745
746The first sets the quotesymbols. If the quote i "symmetric" as " or '
747
748 __PACKAGE__->storage->sql_maker->quote_char('"');
749
880a1a0c 750is enough. If the left quote differs form the right quote, the first
2437a1e3 751notation should be used. name_sep needs to be set to allow the
752SQL generator to put the quotes the correct place.
753
086b93a2 754=head2 Overloading methods
755
756L<DBIx::Class> uses the L<Class::C3> package, which provides for redispatch of
757method calls. You have to use calls to C<next::method> to overload methods.
758More information on using L<Class::C3> with L<DBIx::Class> can be found in
759L<DBIx::Class::Manual::Component>.
760
761=head3 Changing one field whenever another changes
762
763For example, say that you have three columns, C<id>, C<number>, and
764C<squared>. You would like to make changes to C<number> and have
765C<squared> be automagically set to the value of C<number> squared.
766You can accomplish this by overriding C<store_column>:
767
768 sub store_column {
769 my ( $self, $name, $value ) = @_;
770 if ($name eq 'number') {
771 $self->squared($value * $value);
772 }
773 $self->next::method($name, $value);
774 }
775
776Note that the hard work is done by the call to C<next::method>, which
777redispatches your call to store_column to the superclass(es).
778
779=head3 Automatically creating related objects
780
781You might have a class C<Artist> which has many C<CD>s. Further, you
782want to create a C<CD> object every time you insert an C<Artist> object.
ccbebdbc 783You can accomplish this by overriding C<insert> on your objects:
086b93a2 784
785 sub insert {
ccbebdbc 786 my ( $self, @args ) = @_;
787 $self->next::method(@args);
086b93a2 788 $self->cds->new({})->fill_from_artist($self)->insert;
789 return $self;
790 }
791
792where C<fill_from_artist> is a method you specify in C<CD> which sets
793values in C<CD> based on the data in the C<Artist> object you pass in.
794
1def3451 795=head2 Debugging DBIx::Class objects with Data::Dumper
796
797L<Data::Dumper> can be a very useful tool for debugging, but sometimes it can
798be hard to find the pertinent data in all the data it can generate.
799Specifically, if one naively tries to use it like so,
800
801 use Data::Dumper;
802
803 my $cd = $schema->resultset('CD')->find(1);
804 print Dumper($cd);
805
806several pages worth of data from the CD object's schema and result source will
807be dumped to the screen. Since usually one is only interested in a few column
808values of the object, this is not very helpful.
809
810Luckily, it is possible to modify the data before L<Data::Dumper> outputs
811it. Simply define a hook that L<Data::Dumper> will call on the object before
812dumping it. For example,
813
814 package My::DB::CD;
815
816 sub _dumper_hook {
99fb1058 817 $_[0] = bless {
818 %{ $_[0] },
1def3451 819 result_source => undef,
99fb1058 820 }, ref($_[0]);
1def3451 821 }
822
823 [...]
824
825 use Data::Dumper;
826
22139027 827 local $Data::Dumper::Freezer = '_dumper_hook';
1def3451 828
829 my $cd = $schema->resultset('CD')->find(1);
830 print Dumper($cd);
831 # dumps $cd without its ResultSource
832
833If the structure of your schema is such that there is a common base class for
834all your table classes, simply put a method similar to C<_dumper_hook> in the
835base class and set C<$Data::Dumper::Freezer> to its name and L<Data::Dumper>
836will automagically clean up your data before printing it. See
837L<Data::Dumper/EXAMPLES> for more information.
838
1def3451 839=head2 Retrieving a row object's Schema
840
841It is possible to get a Schema object from a row object like so,
842
843 my $schema = $cd->result_source->schema;
844 my $artist_rs = $schema->resultset('Artist');
845 # for example
846
847This can be useful when you don't want to pass around a Schema object to every
848method.
849
4c248161 850=head2 Profiling
851
852When you enable L<DBIx::Class::Storage::DBI>'s debugging it prints the SQL
853executed as well as notifications of query completion and transaction
854begin/commit. If you'd like to profile the SQL you can subclass the
855L<DBIx::Class::Storage::Statistics> class and write your own profiling
856mechanism:
857
858 package My::Profiler;
859 use strict;
860
861 use base 'DBIx::Class::Storage::Statistics';
862
863 use Time::HiRes qw(time);
864
865 my $start;
866
867 sub query_start {
868 my $self = shift();
869 my $sql = shift();
870 my $params = @_;
871
872 print "Executing $sql: ".join(', ', @params)."\n";
873 $start = time();
874 }
875
876 sub query_end {
877 my $self = shift();
878 my $sql = shift();
879 my @params = @_;
880
881 printf("Execution took %0.4f seconds.\n", time() - $start);
882 $start = undef;
883 }
884
885 1;
886
887You can then install that class as the debugging object:
888
889 __PACKAGE__->storage()->debugobj(new My::Profiler());
890 __PACKAGE__->storage()->debug(1);
891
892A more complicated example might involve storing each execution of SQL in an
893array:
894
895 sub query_end {
896 my $self = shift();
897 my $sql = shift();
898 my @params = @_;
899
900 my $elapsed = time() - $start;
901 push(@{ $calls{$sql} }, {
902 params => \@params,
903 elapsed => $elapsed
904 });
905 }
906
907You could then create average, high and low execution times for an SQL
908statement and dig down to see if certain parameters cause aberrant behavior.
909
e8e9e5c7 910=head2 Getting the value of the primary key for the last database insert
911
74413b83 912AKA getting last_insert_id
913
e8e9e5c7 914If you are using PK::Auto, this is straightforward:
915
74413b83 916 my $foo = $rs->create(\%blah);
e8e9e5c7 917 # do more stuff
918 my $id = $foo->id; # foo->my_primary_key_field will also work.
919
920If you are not using autoincrementing primary keys, this will probably
921not work, but then you already know the value of the last primary key anyway.
922
824f4422 923=head2 Dynamic Sub-classing DBIx::Class proxy classes
924(AKA multi-class object inflation from one table)
925
926L<DBIx::Class> classes are proxy classes, therefore some different techniques
927need to be employed for more than basic subclassing. In this example we have
928a single user table that carries a boolean bit for admin. We would like
929like to give the admin users objects(L<DBIx::Class::Row>) the same methods as
930a regular user but also special admin only methods. It doesn't make sense to
931create two seperate proxy-class files for this. We would be copying all the
932user methods into the Admin class. There is a cleaner way to accomplish this.
933
934Overriding the C<inflate_results()> method within the User proxy-class gives
935us the effect we want. This method is called by L<DBIx::Class::ResultSet> when
936inflating a result from storage. So we grab the object being returned, inspect
937the values we are looking for, bless it if it's an admin object, and then
938return it. Running the test file below will confirm this works.
939
940B<Schema Definition>
941
942 package DB::Schema;
943
944 use base qw/DBIx::Class::Schema/;
945
946 __PACKAGE__->load_classes(qw/User/);
947
948
949B<Proxy-Class definitions>
950
951 package DB::Schema::User;
952
953 use strict;
954 use warnings;
955 use base qw/DBIx::Class/;
956
957 ### Defined what our admin class is for ensure_class_loaded
958 my $admin_class = __PACKAGE__ . '::Admin';
959
960 __PACKAGE__->load_components(qw/PK::Auto Core/);
961
962 __PACKAGE__->table('users');
963
964 __PACKAGE__->add_columns(qw/user_id email password
965 firstname lastname active
966 admin/);
967
968 __PACKAGE__->set_primary_key('user_id');
969
970 sub inflate_result {
971 my $self = shift;
972 my $ret = $self->next::method(@_);
973 if( $ret->admin ) {### If this is an admin rebless for extra functions
974 $self->ensure_class_loaded( $admin_class );
975 bless $ret, $admin_class;
976 }
977 return $ret;
978 }
979
980 sub hello {
981 print "I am a regular user.\n";
982 return ;
983 }
984
985
986 package DB::Schema::User::Admin;
987
988 use strict;
989 use warnings;
990 use base qw/DB::Schema::User/;
991
992 sub hello
993 {
994 print "I am an admin.\n";
995 return;
996 }
997
998 sub do_admin_stuff
999 {
1000 print "I am doing admin stuff\n";
1001 return ;
1002 }
1003
1004B<Test File> test.pl
1005
1006 use warnings;
1007 use strict;
1008 use DB::Schema;
1009
1010 my $user_data = { email => 'someguy@place.com',
1011 password => 'pass1',
1012 admin => 0 };
1013
1014 my $admin_data = { email => 'someadmin@adminplace.com',
1015 password => 'pass2',
1016 admin => 1 };
1017
1018 my $schema = DB::Schema->connection('dbi:Pg:dbname=test');
1019
1020 $schema->resultset('User')->create( $user_data );
1021 $schema->resultset('User')->create( $admin_data );
1022
1023 ### Now we search for them
1024 my $user = $schema->resultset('User')->single( $user_data );
1025 my $admin = $schema->resultset('User')->single( $admin_data );
1026
1027 print ref $user, "\n";
1028 print ref $admin, "\n";
1029
1030 print $user->password , "\n"; # pass1
1031 print $admin->password , "\n";# pass2; inherited from User
1032 print $user->hello , "\n";# I am a regular user.
1033 print $admin->hello, "\n";# I am an admin.
1034
1035 ### The statement below will NOT print
1036 print "I can do admin stuff\n" if $user->can('do_admin_stuff');
1037 ### The statement below will print
1038 print "I can do admin stuff\n" if $admin->can('do_admin_stuff');
1039
40dbc108 1040=cut