Cookbook entry for -as and syntax tests
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / Cookbook.pod
CommitLineData
0132e136 1=head1 NAME
9c82c181 2
40dbc108 3DBIx::Class::Manual::Cookbook - Miscellaneous recipes
ee38fa40 4
d2f3e87b 5=head1 SEARCHING
2913b2d3 6
d2f3e87b 7=head2 Paged results
faf62551 8
bade79c4 9When you expect a large number of results, you can ask L<DBIx::Class> for a
264f1571 10paged resultset, which will fetch only a defined number of records at a time:
faf62551 11
bade79c4 12 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 13 undef,
bade79c4 14 {
15 page => 1, # page to return (defaults to 1)
16 rows => 10, # number of results per page
17 },
18 );
faf62551 19
bade79c4 20 return $rs->all(); # all records for page 1
faf62551 21
b4664250 22 return $rs->page(2); # records for page 2
23
ec30560d 24You can get a L<Data::Page> object for the resultset (suitable for use
25in e.g. a template) using the C<pager> method:
faf62551 26
bade79c4 27 return $rs->pager();
faf62551 28
d2f3e87b 29=head2 Complex WHERE clauses
2913b2d3 30
40dbc108 31Sometimes you need to formulate a query using specific operators:
32
ea6309e2 33 my @albums = $schema->resultset('Album')->search({
35d4fe78 34 artist => { 'like', '%Lamb%' },
35 title => { 'like', '%Fear of Fours%' },
36 });
40dbc108 37
38This results in something like the following C<WHERE> clause:
39
35d4fe78 40 WHERE artist LIKE '%Lamb%' AND title LIKE '%Fear of Fours%'
40dbc108 41
42Other queries might require slightly more complex logic:
43
ea6309e2 44 my @albums = $schema->resultset('Album')->search({
35d4fe78 45 -or => [
46 -and => [
47 artist => { 'like', '%Smashing Pumpkins%' },
48 title => 'Siamese Dream',
49 ],
50 artist => 'Starchildren',
51 ],
52 });
40dbc108 53
54This results in the following C<WHERE> clause:
55
35d4fe78 56 WHERE ( artist LIKE '%Smashing Pumpkins%' AND title = 'Siamese Dream' )
57 OR artist = 'Starchildren'
40dbc108 58
59For more information on generating complex queries, see
60L<SQL::Abstract/WHERE CLAUSES>.
ee38fa40 61
b9823354 62=head2 Retrieve one and only one row from a resultset
63
b4664250 64Sometimes you need only the first "top" row of a resultset. While this
65can be easily done with L<< $rs->first|DBIx::Class::ResultSet/first
66>>, it is suboptimal, as a full blown cursor for the resultset will be
67created and then immediately destroyed after fetching the first row
68object. L<< $rs->single|DBIx::Class::ResultSet/single >> is designed
69specifically for this case - it will grab the first returned result
0132e136 70without even instantiating a cursor.
b9823354 71
0132e136 72Before replacing all your calls to C<first()> with C<single()> please observe the
b9823354 73following CAVEATS:
74
75=over
76
77=item *
b4664250 78
b9823354 79While single() takes a search condition just like search() does, it does
80_not_ accept search attributes. However one can always chain a single() to
81a search():
82
b4664250 83 my $top_cd = $cd_rs->search({}, { order_by => 'rating' })->single;
b9823354 84
85
86=item *
b4664250 87
b9823354 88Since single() is the engine behind find(), it is designed to fetch a
89single row per database query. Thus a warning will be issued when the
90underlying SELECT returns more than one row. Sometimes however this usage
91is valid: i.e. we have an arbitrary number of cd's but only one of them is
92at the top of the charts at any given time. If you know what you are doing,
93you can silence the warning by explicitly limiting the resultset size:
94
b4664250 95 my $top_cd = $cd_rs->search ({}, { order_by => 'rating', rows => 1 })->single;
b9823354 96
97=back
98
d2f3e87b 99=head2 Arbitrary SQL through a custom ResultSource
321d9634 100
101Sometimes you have to run arbitrary SQL because your query is too complex
102(e.g. it contains Unions, Sub-Selects, Stored Procedures, etc.) or has to
0132e136 103be optimized for your database in a special way, but you still want to
104get the results as a L<DBIx::Class::ResultSet>.
321d9634 105
7adc2091 106This is accomplished by defining a
107L<ResultSource::View|DBIx::Class::ResultSource::View> for your query,
108almost like you would define a regular ResultSource.
0132e136 109
b4664250 110 package My::Schema::Result::UserFriendsComplex;
111 use strict;
112 use warnings;
321d9634 113 use base qw/DBIx::Class/;
0132e136 114
b4664250 115 __PACKAGE__->load_components('Core');
116 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
117
118 # ->table, ->add_columns, etc.
119
7adc2091 120 # do not attempt to deploy() this view
b4664250 121 __PACKAGE__->result_source_instance->is_virtual(1);
7adc2091 122
b4664250 123 __PACKAGE__->result_source_instance->view_definition(q[
124 SELECT u.* FROM user u
125 INNER JOIN user_friends f ON u.id = f.user_id
126 WHERE f.friend_user_id = ?
127 UNION
128 SELECT u.* FROM user u
129 INNER JOIN user_friends f ON u.id = f.friend_user_id
130 WHERE f.user_id = ?
131 ]);
321d9634 132
133Next, you can execute your complex query using bind parameters like this:
134
b4664250 135 my $friends = $schema->resultset( 'UserFriendsComplex' )->search( {},
321d9634 136 {
137 bind => [ 12345, 12345 ]
138 }
b4664250 139 );
0132e136 140
d00a5c68 141... and you'll get back a perfect L<DBIx::Class::ResultSet> (except, of course,
142that you cannot modify the rows it contains, ie. cannot call L</update>,
143L</delete>, ... on it).
144
b4664250 145Note that you cannot have bind parameters unless is_virtual is set to true.
321d9634 146
7adc2091 147=over
148
149=item * NOTE
150
151If you're using the old deprecated C<< $rsrc_instance->name(\'( SELECT ...') >>
152method for custom SQL execution, you are highly encouraged to update your code
153to use a virtual view as above. If you do not want to change your code, and just
154want to suppress the deprecation warning when you call
155L<DBIx::Class::Schema/deploy>, add this line to your source definition, so that
156C<deploy> will exclude this "table":
a8fcfb9f 157
158 sub sqlt_deploy_hook { $_[1]->schema->drop_table ($_[1]) }
159
7adc2091 160=back
161
d2f3e87b 162=head2 Using specific columns
faf62551 163
324572ca 164When you only want specific columns from a table, you can use
165C<columns> to specify which ones you need. This is useful to avoid
166loading columns with large amounts of data that you aren't about to
167use anyway:
faf62551 168
bade79c4 169 my $rs = $schema->resultset('Artist')->search(
5e8b1b2a 170 undef,
bade79c4 171 {
5e8b1b2a 172 columns => [qw/ name /]
bade79c4 173 }
174 );
faf62551 175
bade79c4 176 # Equivalent SQL:
177 # SELECT artist.name FROM artist
faf62551 178
324572ca 179This is a shortcut for C<select> and C<as>, see below. C<columns>
180cannot be used together with C<select> and C<as>.
181
d2f3e87b 182=head2 Using database functions or stored procedures
faf62551 183
bade79c4 184The combination of C<select> and C<as> can be used to return the result of a
185database function or stored procedure as a column value. You use C<select> to
186specify the source for your column value (e.g. a column name, function, or
187stored procedure name). You then use C<as> to set the column name you will use
188to access the returned value:
faf62551 189
bade79c4 190 my $rs = $schema->resultset('Artist')->search(
324572ca 191 {},
bade79c4 192 {
193 select => [ 'name', { LENGTH => 'name' } ],
194 as => [qw/ name name_length /],
195 }
196 );
faf62551 197
bade79c4 198 # Equivalent SQL:
98b65433 199 # SELECT name name, LENGTH( name )
bade79c4 200 # FROM artist
faf62551 201
324bc214 202Note that the C<as> attribute B<has absolutely nothing to do> with the sql
203syntax C< SELECT foo AS bar > (see the documentation in
204L<DBIx::Class::ResultSet/ATTRIBUTES>). You can control the C<AS> part of the
205generated SQL via the C<-as> field attribute as follows:
206
207 my $rs = $schema->resultset('Artist')->search(
208 {},
209 {
210 join => 'cds',
211 distinct => 1,
212 +select => [ { count => 'cds.cdid', -as => 'amount_of_cds' } ],
213 +as => [qw/num_cds/],
214 order_by => { -desc => 'amount_of_cds' },
215 }
216 );
217
218 # Equivalent SQL
219 # SELECT me.artistid, me.name, me.rank, me.charfield, COUNT( cds.cdid ) AS amount_of_cds
220 # FROM artist me LEFT JOIN cd cds ON cds.artist = me.artistid
221 # GROUP BY me.artistid, me.name, me.rank, me.charfield
222 # ORDER BY amount_of_cds DESC
223
224
225If your alias exists as a column in your base class (i.e. it was added with
226L<add_columns|DBIx::Class::ResultSource/add_columns>), you just access it as
227normal. Our C<Artist> class has a C<name> column, so we just use the C<name>
228accessor:
faf62551 229
bade79c4 230 my $artist = $rs->first();
231 my $name = $artist->name();
faf62551 232
233If on the other hand the alias does not correspond to an existing column, you
324572ca 234have to fetch the value using the C<get_column> accessor:
faf62551 235
bade79c4 236 my $name_length = $artist->get_column('name_length');
faf62551 237
bade79c4 238If you don't like using C<get_column>, you can always create an accessor for
faf62551 239any of your aliases using either of these:
240
bade79c4 241 # Define accessor manually:
242 sub name_length { shift->get_column('name_length'); }
0132e136 243
bade79c4 244 # Or use DBIx::Class::AccessorGroup:
245 __PACKAGE__->mk_group_accessors('column' => 'name_length');
faf62551 246
d2f3e87b 247=head2 SELECT DISTINCT with multiple columns
faf62551 248
58a20107 249 my $rs = $schema->resultset('Artist')->search(
324572ca 250 {},
bade79c4 251 {
cd87b928 252 columns => [ qw/artist_id name rank/ ],
58a20107 253 distinct => 1
0132e136 254 }
58a20107 255 );
256
257 my $rs = $schema->resultset('Artist')->search(
258 {},
259 {
cd87b928 260 columns => [ qw/artist_id name rank/ ],
261 group_by => [ qw/artist_id name rank/ ],
bade79c4 262 }
263 );
faf62551 264
58a20107 265 # Equivalent SQL:
cd87b928 266 # SELECT me.artist_id, me.name, me.rank
58a20107 267 # FROM artist me
cd87b928 268 # GROUP BY artist_id, name, rank
58a20107 269
d2f3e87b 270=head2 SELECT COUNT(DISTINCT colname)
6607ee1b 271
58a20107 272 my $rs = $schema->resultset('Artist')->search(
324572ca 273 {},
bade79c4 274 {
58a20107 275 columns => [ qw/name/ ],
276 distinct => 1
bade79c4 277 }
278 );
6607ee1b 279
58a20107 280 my $rs = $schema->resultset('Artist')->search(
281 {},
282 {
283 columns => [ qw/name/ ],
284 group_by => [ qw/name/ ],
285 }
286 );
287
288 my $count = $rs->count;
289
290 # Equivalent SQL:
0132e136 291 # SELECT COUNT( * ) FROM (SELECT me.name FROM artist me GROUP BY me.name) count_subq:
3d565896 292
d2f3e87b 293=head2 Grouping results
bade79c4 294
295L<DBIx::Class> supports C<GROUP BY> as follows:
296
297 my $rs = $schema->resultset('Artist')->search(
324572ca 298 {},
bade79c4 299 {
300 join => [qw/ cds /],
51458a6a 301 select => [ 'name', { count => 'cds.id' } ],
bade79c4 302 as => [qw/ name cd_count /],
303 group_by => [qw/ name /]
304 }
305 );
6607ee1b 306
bade79c4 307 # Equivalent SQL:
51458a6a 308 # SELECT name, COUNT( cd.id ) FROM artist
309 # LEFT JOIN cd ON artist.id = cd.artist
bade79c4 310 # GROUP BY name
6607ee1b 311
d676881f 312Please see L<DBIx::Class::ResultSet/ATTRIBUTES> documentation if you
313are in any way unsure about the use of the attributes above (C< join
314>, C< select >, C< as > and C< group_by >).
315
70bb942d 316=head2 Subqueries (EXPERIMENTAL)
03834f77 317
318You can write subqueries relatively easily in DBIC.
319
320 my $inside_rs = $schema->resultset('Artist')->search({
321 name => [ 'Billy Joel', 'Brittany Spears' ],
322 });
323
68a797c1 324 my $rs = $schema->resultset('CD')->search({
03834f77 325 artist_id => { 'IN' => $inside_rs->get_column('id')->as_query },
326 });
327
328The usual operators ( =, !=, IN, NOT IN, etc) are supported.
329
330B<NOTE>: You have to explicitly use '=' when doing an equality comparison.
331The following will B<not> work:
332
68a797c1 333 my $rs = $schema->resultset('CD')->search({
03834f77 334 artist_id => $inside_rs->get_column('id')->as_query,
335 });
336
0a62f675 337=head3 Support
338
339Subqueries are supported in the where clause (first hashref), and in the
340from, select, and +select attributes.
341
68a797c1 342=head3 Correlated subqueries
343
344 my $cdrs = $schema->resultset('CD');
345 my $rs = $cdrs->search({
346 year => {
347 '=' => $cdrs->search(
cd87b928 348 { artist_id => { '=' => \'me.artist_id' } },
68a797c1 349 { alias => 'inner' }
350 )->get_column('year')->max_rs->as_query,
351 },
352 });
353
354That creates the following SQL:
355
356 SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
357 FROM cd me
358 WHERE year = (
359 SELECT MAX(inner.year)
360 FROM cd inner
cd87b928 361 WHERE artist_id = me.artist_id
68a797c1 362 )
363
6a9530d1 364=head3 EXPERIMENTAL
365
366Please note that subqueries are considered an experimental feature.
367
d2f3e87b 368=head2 Predefined searches
74dc2edc 369
324572ca 370You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
0132e136 371and defining often used searches as methods:
74dc2edc 372
373 package My::DBIC::ResultSet::CD;
374 use strict;
375 use warnings;
376 use base 'DBIx::Class::ResultSet';
377
378 sub search_cds_ordered {
379 my ($self) = @_;
380
381 return $self->search(
382 {},
383 { order_by => 'name DESC' },
384 );
385 }
386
387 1;
388
389To use your resultset, first tell DBIx::Class to create an instance of it
390for you, in your My::DBIC::Schema::CD class:
391
9dc1bfce 392 # class definition as normal
393 __PACKAGE__->load_components(qw/ Core /);
394 __PACKAGE__->table('cd');
395
396 # tell DBIC to use the custom ResultSet class
74dc2edc 397 __PACKAGE__->resultset_class('My::DBIC::ResultSet::CD');
398
9dc1bfce 399Note that C<resultset_class> must be called after C<load_components> and C<table>, or you will get errors about missing methods.
400
74dc2edc 401Then call your new method in your code:
402
403 my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
404
d2f3e87b 405=head2 Using SQL functions on the left hand side of a comparison
1c133e22 406
407Using SQL functions on the left hand side of a comparison is generally
408not a good idea since it requires a scan of the entire table. However,
409it can be accomplished with C<DBIx::Class> when necessary.
410
411If you do not have quoting on, simply include the function in your search
412specification as you would any column:
413
414 $rs->search({ 'YEAR(date_of_birth)' => 1979 });
415
416With quoting on, or for a more portable solution, use the C<where>
417attribute:
418
419 $rs->search({}, { where => \'YEAR(date_of_birth) = 1979' });
420
421=begin hidden
422
423(When the bind args ordering bug is fixed, this technique will be better
424and can replace the one above.)
425
426With quoting on, or for a more portable solution, use the C<where> and
427C<bind> attributes:
428
429 $rs->search({}, {
430 where => \'YEAR(date_of_birth) = ?',
431 bind => [ 1979 ]
432 });
433
434=end hidden
435
d2f3e87b 436=head1 JOINS AND PREFETCHING
437
87980de7 438=head2 Using joins and prefetch
439
bade79c4 440You can use the C<join> attribute to allow searching on, or sorting your
cd87b928 441results by, one or more columns in a related table.
442
443This requires that you have defined the L<DBIx::Class::Relationship>. For example :
444
445 My::Schema::CD->has_many( artists => 'My::Schema::Artist', 'artist_id');
446
447To return all CDs matching a particular artist name, you specify the name of the relationship ('artists'):
ea6309e2 448
bade79c4 449 my $rs = $schema->resultset('CD')->search(
450 {
0132e136 451 'artists.name' => 'Bob Marley'
bade79c4 452 },
453 {
cd87b928 454 join => 'artists', # join the artist table
bade79c4 455 }
456 );
457
458 # Equivalent SQL:
459 # SELECT cd.* FROM cd
460 # JOIN artist ON cd.artist = artist.id
461 # WHERE artist.name = 'Bob Marley'
462
cd87b928 463In that example both the join, and the condition use the relationship name rather than the table name
0132e136 464(see L<DBIx::Class::Manual::Joining> for more details on aliasing ).
cd87b928 465
bade79c4 466If required, you can now sort on any column in the related tables by including
cd87b928 467it in your C<order_by> attribute, (again using the aliased relation name rather than table name) :
bade79c4 468
469 my $rs = $schema->resultset('CD')->search(
470 {
cd87b928 471 'artists.name' => 'Bob Marley'
bade79c4 472 },
473 {
cd87b928 474 join => 'artists',
475 order_by => [qw/ artists.name /]
bade79c4 476 }
2f81ed0f 477 );
ea6309e2 478
bade79c4 479 # Equivalent SQL:
480 # SELECT cd.* FROM cd
481 # JOIN artist ON cd.artist = artist.id
482 # WHERE artist.name = 'Bob Marley'
483 # ORDER BY artist.name
ea6309e2 484
bade79c4 485Note that the C<join> attribute should only be used when you need to search or
486sort using columns in a related table. Joining related tables when you only
487need columns from the main table will make performance worse!
ea6309e2 488
bade79c4 489Now let's say you want to display a list of CDs, each with the name of the
490artist. The following will work fine:
ea6309e2 491
bade79c4 492 while (my $cd = $rs->next) {
493 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
494 }
ea6309e2 495
bade79c4 496There is a problem however. We have searched both the C<cd> and C<artist> tables
497in our main query, but we have only returned data from the C<cd> table. To get
498the artist name for any of the CD objects returned, L<DBIx::Class> will go back
499to the database:
ea6309e2 500
bade79c4 501 SELECT artist.* FROM artist WHERE artist.id = ?
ea6309e2 502
503A statement like the one above will run for each and every CD returned by our
504main query. Five CDs, five extra queries. A hundred CDs, one hundred extra
505queries!
506
bade79c4 507Thankfully, L<DBIx::Class> has a C<prefetch> attribute to solve this problem.
897342e4 508This allows you to fetch results from related tables in advance:
ea6309e2 509
bade79c4 510 my $rs = $schema->resultset('CD')->search(
511 {
cd87b928 512 'artists.name' => 'Bob Marley'
bade79c4 513 },
514 {
cd87b928 515 join => 'artists',
516 order_by => [qw/ artists.name /],
517 prefetch => 'artists' # return artist data too!
bade79c4 518 }
519 );
ea6309e2 520
bade79c4 521 # Equivalent SQL (note SELECT from both "cd" and "artist"):
522 # SELECT cd.*, artist.* FROM cd
523 # JOIN artist ON cd.artist = artist.id
524 # WHERE artist.name = 'Bob Marley'
525 # ORDER BY artist.name
ea6309e2 526
527The code to print the CD list remains the same:
528
bade79c4 529 while (my $cd = $rs->next) {
530 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
531 }
ea6309e2 532
bade79c4 533L<DBIx::Class> has now prefetched all matching data from the C<artist> table,
ea6309e2 534so no additional SQL statements are executed. You now have a much more
535efficient query.
536
bade79c4 537Also note that C<prefetch> should only be used when you know you will
ea6309e2 538definitely use data from a related table. Pre-fetching related tables when you
539only need columns from the main table will make performance worse!
540
51458a6a 541=head2 Multiple joins
542
543In the examples above, the C<join> attribute was a scalar. If you
544pass an array reference instead, you can join to multiple tables. In
545this example, we want to limit the search further, using
546C<LinerNotes>:
547
548 # Relationships defined elsewhere:
549 # CD->belongs_to('artist' => 'Artist');
550 # CD->has_one('liner_notes' => 'LinerNotes', 'cd');
551 my $rs = $schema->resultset('CD')->search(
552 {
553 'artist.name' => 'Bob Marley'
554 'liner_notes.notes' => { 'like', '%some text%' },
555 },
556 {
557 join => [qw/ artist liner_notes /],
558 order_by => [qw/ artist.name /],
559 }
560 );
561
562 # Equivalent SQL:
563 # SELECT cd.*, artist.*, liner_notes.* FROM cd
564 # JOIN artist ON cd.artist = artist.id
565 # JOIN liner_notes ON cd.id = liner_notes.cd
566 # WHERE artist.name = 'Bob Marley'
567 # ORDER BY artist.name
568
d2f3e87b 569=head2 Multi-step joins
ea6309e2 570
571Sometimes you want to join more than one relationship deep. In this example,
bade79c4 572we want to find all C<Artist> objects who have C<CD>s whose C<LinerNotes>
573contain a specific string:
574
575 # Relationships defined elsewhere:
576 # Artist->has_many('cds' => 'CD', 'artist');
577 # CD->has_one('liner_notes' => 'LinerNotes', 'cd');
578
579 my $rs = $schema->resultset('Artist')->search(
580 {
581 'liner_notes.notes' => { 'like', '%some text%' },
582 },
583 {
584 join => {
585 'cds' => 'liner_notes'
586 }
587 }
588 );
ea6309e2 589
bade79c4 590 # Equivalent SQL:
591 # SELECT artist.* FROM artist
51458a6a 592 # LEFT JOIN cd ON artist.id = cd.artist
593 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
bade79c4 594 # WHERE liner_notes.notes LIKE '%some text%'
ea6309e2 595
596Joins can be nested to an arbitrary level. So if we decide later that we
597want to reduce the number of Artists returned based on who wrote the liner
598notes:
599
bade79c4 600 # Relationship defined elsewhere:
601 # LinerNotes->belongs_to('author' => 'Person');
602
603 my $rs = $schema->resultset('Artist')->search(
604 {
605 'liner_notes.notes' => { 'like', '%some text%' },
606 'author.name' => 'A. Writer'
607 },
608 {
609 join => {
610 'cds' => {
611 'liner_notes' => 'author'
ea6309e2 612 }
bade79c4 613 }
614 }
615 );
ea6309e2 616
bade79c4 617 # Equivalent SQL:
618 # SELECT artist.* FROM artist
51458a6a 619 # LEFT JOIN cd ON artist.id = cd.artist
620 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
621 # LEFT JOIN author ON author.id = liner_notes.author
bade79c4 622 # WHERE liner_notes.notes LIKE '%some text%'
623 # AND author.name = 'A. Writer'
87980de7 624
51458a6a 625=head2 Multi-step and multiple joins
626
627With various combinations of array and hash references, you can join
628tables in any combination you desire. For example, to join Artist to
629CD and Concert, and join CD to LinerNotes:
630
631 # Relationships defined elsewhere:
632 # Artist->has_many('concerts' => 'Concert', 'artist');
633
634 my $rs = $schema->resultset('Artist')->search(
635 { },
636 {
637 join => [
638 {
639 cds => 'liner_notes'
640 },
641 'concerts'
642 ],
643 }
644 );
645
646 # Equivalent SQL:
647 # SELECT artist.* FROM artist
648 # LEFT JOIN cd ON artist.id = cd.artist
649 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
650 # LEFT JOIN concert ON artist.id = concert.artist
651
897342e4 652=head2 Multi-step prefetch
653
d76788de 654C<prefetch> can be nested more than one relationship
897342e4 655deep using the same syntax as a multi-step join:
656
657 my $rs = $schema->resultset('Tag')->search(
ac2803ef 658 {},
897342e4 659 {
660 prefetch => {
661 cd => 'artist'
662 }
663 }
664 );
665
666 # Equivalent SQL:
667 # SELECT tag.*, cd.*, artist.* FROM tag
51458a6a 668 # JOIN cd ON tag.cd = cd.id
669 # JOIN artist ON cd.artist = artist.id
897342e4 670
671Now accessing our C<cd> and C<artist> relationships does not need additional
672SQL statements:
673
674 my $tag = $rs->first;
675 print $tag->cd->artist->name;
676
d2f3e87b 677=head1 ROW-LEVEL OPERATIONS
678
679=head2 Retrieving a row object's Schema
680
681It is possible to get a Schema object from a row object like so:
682
683 my $schema = $cd->result_source->schema;
684 # use the schema as normal:
0132e136 685 my $artist_rs = $schema->resultset('Artist');
d2f3e87b 686
687This can be useful when you don't want to pass around a Schema object to every
688method.
689
690=head2 Getting the value of the primary key for the last database insert
691
692AKA getting last_insert_id
693
d76788de 694Thanks to the core component PK::Auto, this is straightforward:
d2f3e87b 695
696 my $foo = $rs->create(\%blah);
697 # do more stuff
698 my $id = $foo->id; # foo->my_primary_key_field will also work.
699
700If you are not using autoincrementing primary keys, this will probably
701not work, but then you already know the value of the last primary key anyway.
702
703=head2 Stringification
704
0132e136 705Employ the standard stringification technique by using the L<overload>
d2f3e87b 706module.
707
708To make an object stringify itself as a single column, use something
b24d86a1 709like this (replace C<name> with the column/method of your choice):
d2f3e87b 710
711 use overload '""' => sub { shift->name}, fallback => 1;
712
713For more complex stringification, you can use an anonymous subroutine:
714
715 use overload '""' => sub { $_[0]->name . ", " .
716 $_[0]->address }, fallback => 1;
717
718=head3 Stringification Example
719
720Suppose we have two tables: C<Product> and C<Category>. The table
721specifications are:
722
723 Product(id, Description, category)
724 Category(id, Description)
725
726C<category> is a foreign key into the Category table.
727
728If you have a Product object C<$obj> and write something like
729
730 print $obj->category
731
732things will not work as expected.
733
734To obtain, for example, the category description, you should add this
735method to the class defining the Category table:
736
737 use overload "" => sub {
738 my $self = shift;
739
740 return $self->Description;
741 }, fallback => 1;
742
743=head2 Want to know if find_or_create found or created a row?
744
745Just use C<find_or_new> instead, then check C<in_storage>:
746
747 my $obj = $rs->find_or_new({ blah => 'blarg' });
748 unless ($obj->in_storage) {
749 $obj->insert;
750 # do whatever else you wanted if it was a new row
751 }
752
0132e136 753=head2 Static sub-classing DBIx::Class result classes
6fc80947 754
755AKA adding additional relationships/methods/etc. to a model for a
756specific usage of the (shared) model.
757
0132e136 758B<Schema definition>
759
760 package My::App::Schema;
761
762 use base DBIx::Class::Schema;
6fc80947 763
764 # load subclassed classes from My::App::Schema::Result/ResultSet
765 __PACKAGE__->load_namespaces;
766
767 # load classes from shared model
768 load_classes({
769 'My::Shared::Model::Result' => [qw/
770 Foo
771 Bar
772 /]});
773
774 1;
0132e136 775
776B<Result-Subclass definition>
777
6fc80947 778 package My::App::Schema::Result::Baz;
0132e136 779
780 use strict;
781 use warnings;
782 use base My::Shared::Model::Result::Baz;
783
6fc80947 784 # WARNING: Make sure you call table() again in your subclass,
785 # otherwise DBIx::Class::ResultSourceProxy::Table will not be called
786 # and the class name is not correctly registered as a source
0132e136 787 __PACKAGE__->table('baz');
788
789 sub additional_method {
790 return "I'm an additional method only needed by this app";
6fc80947 791 }
792
793 1;
0132e136 794
795=head2 Dynamic Sub-classing DBIx::Class proxy classes
d2f3e87b 796
797AKA multi-class object inflation from one table
0132e136 798
d2f3e87b 799L<DBIx::Class> classes are proxy classes, therefore some different
800techniques need to be employed for more than basic subclassing. In
801this example we have a single user table that carries a boolean bit
802for admin. We would like like to give the admin users
0132e136 803objects (L<DBIx::Class::Row>) the same methods as a regular user but
d2f3e87b 804also special admin only methods. It doesn't make sense to create two
805seperate proxy-class files for this. We would be copying all the user
806methods into the Admin class. There is a cleaner way to accomplish
807this.
808
809Overriding the C<inflate_result> method within the User proxy-class
810gives us the effect we want. This method is called by
811L<DBIx::Class::ResultSet> when inflating a result from storage. So we
812grab the object being returned, inspect the values we are looking for,
813bless it if it's an admin object, and then return it. See the example
814below:
0132e136 815
816B<Schema Definition>
817
818 package My::Schema;
819
820 use base qw/DBIx::Class::Schema/;
821
6fc80947 822 __PACKAGE__->load_namespaces;
823
824 1;
0132e136 825
826
827B<Proxy-Class definitions>
828
829 package My::Schema::Result::User;
830
831 use strict;
832 use warnings;
833 use base qw/DBIx::Class/;
834
835 ### Define what our admin class is, for ensure_class_loaded()
836 my $admin_class = __PACKAGE__ . '::Admin';
837
838 __PACKAGE__->load_components(qw/Core/);
839
840 __PACKAGE__->table('users');
841
842 __PACKAGE__->add_columns(qw/user_id email password
843 firstname lastname active
844 admin/);
845
846 __PACKAGE__->set_primary_key('user_id');
847
848 sub inflate_result {
849 my $self = shift;
850 my $ret = $self->next::method(@_);
851 if( $ret->admin ) {### If this is an admin, rebless for extra functions
852 $self->ensure_class_loaded( $admin_class );
853 bless $ret, $admin_class;
854 }
855 return $ret;
856 }
857
858 sub hello {
859 print "I am a regular user.\n";
860 return ;
861 }
862
6fc80947 863 1;
864
0132e136 865
866 package My::Schema::Result::User::Admin;
867
868 use strict;
869 use warnings;
870 use base qw/My::Schema::Result::User/;
04d29efe 871
872 # This line is important
873 __PACKAGE__->table('users');
0132e136 874
875 sub hello
876 {
877 print "I am an admin.\n";
878 return;
879 }
880
881 sub do_admin_stuff
882 {
883 print "I am doing admin stuff\n";
884 return ;
6fc80947 885 }
886
887 1;
0132e136 888
889B<Test File> test.pl
890
891 use warnings;
892 use strict;
893 use My::Schema;
894
895 my $user_data = { email => 'someguy@place.com',
896 password => 'pass1',
897 admin => 0 };
898
899 my $admin_data = { email => 'someadmin@adminplace.com',
900 password => 'pass2',
901 admin => 1 };
902
903 my $schema = My::Schema->connection('dbi:Pg:dbname=test');
904
905 $schema->resultset('User')->create( $user_data );
906 $schema->resultset('User')->create( $admin_data );
907
908 ### Now we search for them
909 my $user = $schema->resultset('User')->single( $user_data );
910 my $admin = $schema->resultset('User')->single( $admin_data );
911
912 print ref $user, "\n";
913 print ref $admin, "\n";
914
915 print $user->password , "\n"; # pass1
916 print $admin->password , "\n";# pass2; inherited from User
917 print $user->hello , "\n";# I am a regular user.
918 print $admin->hello, "\n";# I am an admin.
919
920 ### The statement below will NOT print
921 print "I can do admin stuff\n" if $user->can('do_admin_stuff');
922 ### The statement below will print
923 print "I can do admin stuff\n" if $admin->can('do_admin_stuff');
d2f3e87b 924
a5b29361 925=head2 Skip row object creation for faster results
d2f3e87b 926
927DBIx::Class is not built for speed, it's built for convenience and
928ease of use, but sometimes you just need to get the data, and skip the
929fancy objects.
0132e136 930
d2f3e87b 931To do this simply use L<DBIx::Class::ResultClass::HashRefInflator>.
0132e136 932
d2f3e87b 933 my $rs = $schema->resultset('CD');
0132e136 934
d2f3e87b 935 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
0132e136 936
d2f3e87b 937 my $hash_ref = $rs->find(1);
a5b29361 938
d2f3e87b 939Wasn't that easy?
bc96f260 940
db2b2eb6 941Beware, changing the Result class using
942L<DBIx::Class::ResultSet/result_class> will replace any existing class
943completely including any special components loaded using
944load_components, eg L<DBIx::Class::InflateColumn::DateTime>.
945
d2f3e87b 946=head2 Get raw data for blindingly fast results
947
948If the L<HashRefInflator|DBIx::Class::ResultClass::HashRefInflator> solution
949above is not fast enough for you, you can use a DBIx::Class to return values
db2b2eb6 950exactly as they come out of the database with none of the convenience methods
d2f3e87b 951wrapped round them.
952
2d7d8459 953This is used like so:
d2f3e87b 954
955 my $cursor = $rs->cursor
956 while (my @vals = $cursor->next) {
957 # use $val[0..n] here
958 }
959
960You will need to map the array offsets to particular columns (you can
db2b2eb6 961use the L<DBIx::Class::ResultSet/select> attribute of L<DBIx::Class::ResultSet/search> to force ordering).
d2f3e87b 962
963=head1 RESULTSET OPERATIONS
964
965=head2 Getting Schema from a ResultSet
966
db2b2eb6 967To get the L<DBIx::Class::Schema> object from a ResultSet, do the following:
d2f3e87b 968
969 $rs->result_source->schema
970
971=head2 Getting Columns Of Data
972
973AKA Aggregating Data
ac2803ef 974
975If you want to find the sum of a particular column there are several
976ways, the obvious one is to use search:
977
978 my $rs = $schema->resultset('Items')->search(
979 {},
0132e136 980 {
ac2803ef 981 select => [ { sum => 'Cost' } ],
d676881f 982 as => [ 'total_cost' ], # remember this 'as' is for DBIx::Class::ResultSet not SQL
ac2803ef 983 }
984 );
985 my $tc = $rs->first->get_column('total_cost');
986
987Or, you can use the L<DBIx::Class::ResultSetColumn>, which gets
988returned when you ask the C<ResultSet> for a column using
989C<get_column>:
990
991 my $cost = $schema->resultset('Items')->get_column('Cost');
992 my $tc = $cost->sum;
993
994With this you can also do:
995
996 my $minvalue = $cost->min;
997 my $maxvalue = $cost->max;
998
999Or just iterate through the values of this column only:
1000
1001 while ( my $c = $cost->next ) {
1002 print $c;
1003 }
1004
1005 foreach my $c ($cost->all) {
1006 print $c;
1007 }
1008
0132e136 1009C<ResultSetColumn> only has a limited number of built-in functions. If
709353af 1010you need one that it doesn't have, then you can use the C<func> method
1011instead:
1012
1013 my $avg = $cost->func('AVERAGE');
1014
1015This will cause the following SQL statement to be run:
1016
1017 SELECT AVERAGE(Cost) FROM Items me
1018
1019Which will of course only work if your database supports this function.
ac2803ef 1020See L<DBIx::Class::ResultSetColumn> for more documentation.
1021
204e5c03 1022=head2 Creating a result set from a set of rows
1023
0132e136 1024Sometimes you have a (set of) row objects that you want to put into a
204e5c03 1025resultset without the need to hit the DB again. You can do that by using the
1026L<set_cache|DBIx::Class::Resultset/set_cache> method:
1027
2d7a4e46 1028 my @uploadable_groups;
204e5c03 1029 while (my $group = $groups->next) {
1030 if ($group->can_upload($self)) {
1031 push @uploadable_groups, $group;
1032 }
1033 }
1034 my $new_rs = $self->result_source->resultset;
1035 $new_rs->set_cache(\@uploadable_groups);
1036 return $new_rs;
1037
1038
d2f3e87b 1039=head1 USING RELATIONSHIPS
acee4e4d 1040
d2f3e87b 1041=head2 Create a new row in a related table
acee4e4d 1042
6f1434fd 1043 my $author = $book->create_related('author', { name => 'Fred'});
acee4e4d 1044
d2f3e87b 1045=head2 Search in a related table
acee4e4d 1046
1047Only searches for books named 'Titanic' by the author in $author.
1048
6f1434fd 1049 my $books_rs = $author->search_related('books', { name => 'Titanic' });
acee4e4d 1050
d2f3e87b 1051=head2 Delete data in a related table
acee4e4d 1052
1053Deletes only the book named Titanic by the author in $author.
1054
6f1434fd 1055 $author->delete_related('books', { name => 'Titanic' });
acee4e4d 1056
d2f3e87b 1057=head2 Ordering a relationship result set
f8bad769 1058
0132e136 1059If you always want a relation to be ordered, you can specify this when you
f8bad769 1060create the relationship.
1061
6f1434fd 1062To order C<< $book->pages >> by descending page_number, create the relation
1063as follows:
f8bad769 1064
6f1434fd 1065 __PACKAGE__->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} );
f8bad769 1066
7c0825ab 1067=head2 Filtering a relationship result set
1068
1069If you want to get a filtered result set, you can just add add to $attr as follows:
1070
1071 __PACKAGE__->has_many('pages' => 'Page', 'book', { where => { scrap => 0 } } );
1072
d2f3e87b 1073=head2 Many-to-many relationships
f8bad769 1074
d2f3e87b 1075This is straightforward using L<ManyToMany|DBIx::Class::Relationship/many_to_many>:
f8bad769 1076
d2f3e87b 1077 package My::User;
6f1434fd 1078 use base 'DBIx::Class';
1079 __PACKAGE__->load_components('Core');
d2f3e87b 1080 __PACKAGE__->table('user');
1081 __PACKAGE__->add_columns(qw/id name/);
1082 __PACKAGE__->set_primary_key('id');
1083 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'user');
1084 __PACKAGE__->many_to_many('addresses' => 'user_address', 'address');
87980de7 1085
d2f3e87b 1086 package My::UserAddress;
6f1434fd 1087 use base 'DBIx::Class';
1088 __PACKAGE__->load_components('Core');
d2f3e87b 1089 __PACKAGE__->table('user_address');
1090 __PACKAGE__->add_columns(qw/user address/);
1091 __PACKAGE__->set_primary_key(qw/user address/);
1092 __PACKAGE__->belongs_to('user' => 'My::User');
1093 __PACKAGE__->belongs_to('address' => 'My::Address');
181a28f4 1094
d2f3e87b 1095 package My::Address;
6f1434fd 1096 use base 'DBIx::Class';
1097 __PACKAGE__->load_components('Core');
d2f3e87b 1098 __PACKAGE__->table('address');
1099 __PACKAGE__->add_columns(qw/id street town area_code country/);
1100 __PACKAGE__->set_primary_key('id');
1101 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'address');
1102 __PACKAGE__->many_to_many('users' => 'user_address', 'user');
1103
1104 $rs = $user->addresses(); # get all addresses for a user
1105 $rs = $address->users(); # get all users for an address
1106
db2b2eb6 1107=head2 Relationships across DB schemas
1108
1109Mapping relationships across L<DB schemas|DBIx::Class::Manual::Glossary/DB schema>
1110is easy as long as the schemas themselves are all accessible via the same DBI
1111connection. In most cases, this means that they are on the same database host
1112as each other and your connecting database user has the proper permissions to them.
1113
1114To accomplish this one only needs to specify the DB schema name in the table
1115declaration, like so...
1116
1117 package MyDatabase::Main::Artist;
1118 use base qw/DBIx::Class/;
1119 __PACKAGE__->load_components(qw/PK::Auto Core/);
0132e136 1120
db2b2eb6 1121 __PACKAGE__->table('database1.artist'); # will use "database1.artist" in FROM clause
0132e136 1122
cd87b928 1123 __PACKAGE__->add_columns(qw/ artist_id name /);
1124 __PACKAGE__->set_primary_key('artist_id');
db2b2eb6 1125 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
1126
1127 1;
1128
1129Whatever string you specify there will be used to build the "FROM" clause in SQL
1130queries.
1131
1132The big drawback to this is you now have DB schema names hardcoded in your
1133class files. This becomes especially troublesome if you have multiple instances
1134of your application to support a change lifecycle (e.g. DEV, TEST, PROD) and
1135the DB schemas are named based on the environment (e.g. database1_dev).
1136
1137However, one can dynamically "map" to the proper DB schema by overriding the
1138L<connection|DBIx::Class::Schama/connection> method in your Schema class and
1139building a renaming facility, like so:
1140
1141 package MyDatabase::Schema;
1142 use Moose;
0132e136 1143
db2b2eb6 1144 extends 'DBIx::Class::Schema';
0132e136 1145
db2b2eb6 1146 around connection => sub {
1147 my ( $inner, $self, $dsn, $username, $pass, $attr ) = ( shift, @_ );
0132e136 1148
db2b2eb6 1149 my $postfix = delete $attr->{schema_name_postfix};
0132e136 1150
db2b2eb6 1151 $inner->(@_);
0132e136 1152
db2b2eb6 1153 if ( $postfix ) {
1154 $self->append_db_name($postfix);
1155 }
1156 };
1157
1158 sub append_db_name {
1159 my ( $self, $postfix ) = @_;
0132e136 1160
1161 my @sources_with_db
1162 = grep
1163 { $_->name =~ /^\w+\./mx }
1164 map
1165 { $self->source($_) }
db2b2eb6 1166 $self->sources;
0132e136 1167
db2b2eb6 1168 foreach my $source (@sources_with_db) {
1169 my $name = $source->name;
1170 $name =~ s{^(\w+)\.}{${1}${postfix}\.}mx;
0132e136 1171
db2b2eb6 1172 $source->name($name);
1173 }
1174 }
1175
1176 1;
1177
1178By overridding the L<connection|DBIx::Class::Schama/connection>
1179method and extracting a custom option from the provided \%attr hashref one can
1180then simply iterate over all the Schema's ResultSources, renaming them as
1181needed.
1182
0132e136 1183To use this facility, simply add or modify the \%attr hashref that is passed to
db2b2eb6 1184L<connection|DBIx::Class::Schama/connect>, as follows:
1185
0132e136 1186 my $schema
db2b2eb6 1187 = MyDatabase::Schema->connect(
0132e136 1188 $dsn,
1189 $user,
db2b2eb6 1190 $pass,
1191 {
1192 schema_name_postfix => '_dev'
0132e136 1193 # ... Other options as desired ...
db2b2eb6 1194 })
1195
1196Obviously, one could accomplish even more advanced mapping via a hash map or a
1197callback routine.
1198
d2f3e87b 1199=head1 TRANSACTIONS
1200
1201As of version 0.04001, there is improved transaction support in
1202L<DBIx::Class::Storage> and L<DBIx::Class::Schema>. Here is an
1203example of the recommended way to use it:
1204
1205 my $genus = $schema->resultset('Genus')->find(12);
1206
1207 my $coderef2 = sub {
1208 $genus->extinct(1);
1209 $genus->update;
1210 };
70634260 1211
181a28f4 1212 my $coderef1 = sub {
35d4fe78 1213 $genus->add_to_species({ name => 'troglodyte' });
1214 $genus->wings(2);
1215 $genus->update;
6f1434fd 1216 $schema->txn_do($coderef2); # Can have a nested transaction. Only the outer will actualy commit
181a28f4 1217 return $genus->species;
1218 };
1219
181a28f4 1220 my $rs;
1221 eval {
70634260 1222 $rs = $schema->txn_do($coderef1);
181a28f4 1223 };
1224
1225 if ($@) { # Transaction failed
1226 die "the sky is falling!" #
1227 if ($@ =~ /Rollback failed/); # Rollback failed
1228
1229 deal_with_failed_transaction();
35d4fe78 1230 }
87980de7 1231
181a28f4 1232Nested transactions will work as expected. That is, only the outermost
1233transaction will actually issue a commit to the $dbh, and a rollback
1234at any level of any transaction will cause the entire nested
1235transaction to fail. Support for savepoints and for true nested
40dbc108 1236transactions (for databases that support them) will hopefully be added
1237in the future.
ee38fa40 1238
0132e136 1239=head1 SQL
ee38fa40 1240
d2f3e87b 1241=head2 Creating Schemas From An Existing Database
ea6309e2 1242
0132e136 1243L<DBIx::Class::Schema::Loader> will connect to a database and create a
d2f3e87b 1244L<DBIx::Class::Schema> and associated sources by examining the database.
bade79c4 1245
0132e136 1246The recommend way of achieving this is to use the
d2f3e87b 1247L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> method:
bade79c4 1248
6f1434fd 1249 perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib \
1250 -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
362500af 1251
d2f3e87b 1252This will create a tree of files rooted at C<./lib/My/Schema/> containing
1253source definitions for all the tables found in the C<foo> database.
362500af 1254
d2f3e87b 1255=head2 Creating DDL SQL
362500af 1256
264f1571 1257The following functionality requires you to have L<SQL::Translator>
1258(also known as "SQL Fairy") installed.
362500af 1259
264f1571 1260To create a set of database-specific .sql files for the above schema:
362500af 1261
264f1571 1262 my $schema = My::Schema->connect($dsn);
1263 $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
1264 '0.1',
d2f3e87b 1265 './dbscriptdir/'
264f1571 1266 );
1267
1268By default this will create schema files in the current directory, for
1269MySQL, SQLite and PostgreSQL, using the $VERSION from your Schema.pm.
1270
1271To create a new database using the schema:
1272
1273 my $schema = My::Schema->connect($dsn);
1274 $schema->deploy({ add_drop_tables => 1});
1275
1276To import created .sql files using the mysql client:
1277
1278 mysql -h "host" -D "database" -u "user" -p < My_Schema_1.0_MySQL.sql
1279
1280To create C<ALTER TABLE> conversion scripts to update a database to a
1281newer version of your schema at a later point, first set a new
d2f3e87b 1282C<$VERSION> in your Schema file, then:
264f1571 1283
1284 my $schema = My::Schema->connect($dsn);
1285 $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
1286 '0.2',
1287 '/dbscriptdir/',
1288 '0.1'
1289 );
1290
1291This will produce new database-specific .sql files for the new version
1292of the schema, plus scripts to convert from version 0.1 to 0.2. This
1293requires that the files for 0.1 as created above are available in the
1294given directory to diff against.
362500af 1295
6f1434fd 1296=head2 Select from dual
16cd5b28 1297
1298Dummy tables are needed by some databases to allow calling functions
1299or expressions that aren't based on table content, for examples of how
1300this applies to various database types, see:
1301L<http://troels.arvin.dk/db/rdbms/#other-dummy_table>.
1302
1303Note: If you're using Oracles dual table don't B<ever> do anything
1304other than a select, if you CRUD on your dual table you *will* break
1305your database.
1306
1307Make a table class as you would for any other table
0132e136 1308
16cd5b28 1309 package MyAppDB::Dual;
1310 use strict;
1311 use warnings;
1312 use base 'DBIx::Class';
1313 __PACKAGE__->load_components("Core");
1314 __PACKAGE__->table("Dual");
1315 __PACKAGE__->add_columns(
1316 "dummy",
1317 { data_type => "VARCHAR2", is_nullable => 0, size => 1 },
1318 );
0132e136 1319
16cd5b28 1320Once you've loaded your table class select from it using C<select>
1321and C<as> instead of C<columns>
0132e136 1322
16cd5b28 1323 my $rs = $schema->resultset('Dual')->search(undef,
1324 { select => [ 'sydate' ],
1325 as => [ 'now' ]
1326 },
1327 );
0132e136 1328
16cd5b28 1329All you have to do now is be careful how you access your resultset, the below
1330will not work because there is no column called 'now' in the Dual table class
0132e136 1331
16cd5b28 1332 while (my $dual = $rs->next) {
1333 print $dual->now."\n";
1334 }
6f1434fd 1335 # Can't locate object method "now" via package "MyAppDB::Dual" at headshot.pl line 23.
0132e136 1336
16cd5b28 1337You could of course use 'dummy' in C<as> instead of 'now', or C<add_columns> to
1338your Dual class for whatever you wanted to select from dual, but that's just
1339silly, instead use C<get_column>
0132e136 1340
16cd5b28 1341 while (my $dual = $rs->next) {
1342 print $dual->get_column('now')."\n";
1343 }
0132e136 1344
16cd5b28 1345Or use C<cursor>
0132e136 1346
16cd5b28 1347 my $cursor = $rs->cursor;
1348 while (my @vals = $cursor->next) {
1349 print $vals[0]."\n";
1350 }
336256bc 1351
1352In case you're going to use this "trick" together with L<DBIx::Class::Schema/deploy> or
1353L<DBIx::Class::Schema/create_ddl_dir> a table called "dual" will be created in your
1354current schema. This would overlap "sys.dual" and you could not fetch "sysdate" or
1355"sequence.nextval" anymore from dual. To avoid this problem, just tell
1356L<SQL::Translator> to not create table dual:
1357
1358 my $sqlt_args = {
1359 add_drop_table => 1,
1360 parser_args => { sources => [ grep $_ ne 'Dual', schema->sources ] },
1361 };
1362 $schema->create_ddl_dir( [qw/Oracle/], undef, './sql', undef, $sqlt_args );
0132e136 1363
16cd5b28 1364Or use L<DBIx::Class::ResultClass::HashRefInflator>
0132e136 1365
16cd5b28 1366 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
1367 while ( my $dual = $rs->next ) {
1368 print $dual->{now}."\n";
1369 }
0132e136 1370
16cd5b28 1371Here are some example C<select> conditions to illustrate the different syntax
0132e136 1372you could use for doing stuff like
16cd5b28 1373C<oracles.heavily(nested(functions_can('take', 'lots'), OF), 'args')>
0132e136 1374
16cd5b28 1375 # get a sequence value
1376 select => [ 'A_SEQ.nextval' ],
0132e136 1377
16cd5b28 1378 # get create table sql
1379 select => [ { 'dbms_metadata.get_ddl' => [ "'TABLE'", "'ARTIST'" ]} ],
0132e136 1380
16cd5b28 1381 # get a random num between 0 and 100
1382 select => [ { "trunc" => [ { "dbms_random.value" => [0,100] } ]} ],
0132e136 1383
16cd5b28 1384 # what year is it?
1385 select => [ { 'extract' => [ \'year from sysdate' ] } ],
0132e136 1386
16cd5b28 1387 # do some math
1388 select => [ {'round' => [{'cos' => [ \'180 * 3.14159265359/180' ]}]}],
0132e136 1389
16cd5b28 1390 # which day of the week were you born on?
6f1434fd 1391 select => [{'to_char' => [{'to_date' => [ "'25-DEC-1980'", "'dd-mon-yyyy'" ]}, "'day'"]}],
0132e136 1392
16cd5b28 1393 # select 16 rows from dual
1394 select => [ "'hello'" ],
1395 as => [ 'world' ],
1396 group_by => [ 'cube( 1, 2, 3, 4 )' ],
0132e136 1397
1398
16cd5b28 1399
d2f3e87b 1400=head2 Adding Indexes And Functions To Your SQL
362500af 1401
d2f3e87b 1402Often you will want indexes on columns on your table to speed up searching. To
0132e136 1403do this, create a method called C<sqlt_deploy_hook> in the relevant source
1404class (refer to the advanced
2d7d8459 1405L<callback system|DBIx::Class::ResultSource/sqlt_deploy_callback> if you wish
1406to share a hook between multiple sources):
b0a20454 1407
23471103 1408 package My::Schema::Result::Artist;
b0a20454 1409
d2f3e87b 1410 __PACKAGE__->table('artist');
1411 __PACKAGE__->add_columns(id => { ... }, name => { ... })
b0a20454 1412
d2f3e87b 1413 sub sqlt_deploy_hook {
1414 my ($self, $sqlt_table) = @_;
1415
1416 $sqlt_table->add_index(name => 'idx_name', fields => ['name']);
1417 }
1418
1419 1;
1420
0132e136 1421Sometimes you might want to change the index depending on the type of the
d2f3e87b 1422database for which SQL is being generated:
1423
1424 my ($db_type = $sqlt_table->schema->translator->producer_type)
1425 =~ s/^SQL::Translator::Producer:://;
1426
0132e136 1427You can also add hooks to the schema level to stop certain tables being
d2f3e87b 1428created:
1429
1430 package My::Schema;
1431
1432 ...
1433
1434 sub sqlt_deploy_hook {
1435 my ($self, $sqlt_schema) = @_;
1436
1437 $sqlt_schema->drop_table('table_name');
1438 }
1439
2d7d8459 1440You could also add views, procedures or triggers to the output using
1441L<SQL::Translator::Schema/add_view>,
1442L<SQL::Translator::Schema/add_procedure> or
1443L<SQL::Translator::Schema/add_trigger>.
1444
b0a20454 1445
362500af 1446=head2 Schema versioning
1447
1448The following example shows simplistically how you might use DBIx::Class to
1449deploy versioned schemas to your customers. The basic process is as follows:
1450
da4779ad 1451=over 4
1452
1453=item 1.
1454
1455Create a DBIx::Class schema
1456
1457=item 2.
1458
1459Save the schema
1460
1461=item 3.
1462
1463Deploy to customers
1464
1465=item 4.
1466
1467Modify schema to change functionality
1468
1469=item 5.
1470
1471Deploy update to customers
1472
1473=back
362500af 1474
d2f3e87b 1475B<Create a DBIx::Class schema>
362500af 1476
1477This can either be done manually, or generated from an existing database as
d2f3e87b 1478described under L</Creating Schemas From An Existing Database>
362500af 1479
d2f3e87b 1480B<Save the schema>
362500af 1481
d2f3e87b 1482Call L<DBIx::Class::Schema/create_ddl_dir> as above under L</Creating DDL SQL>.
362500af 1483
d2f3e87b 1484B<Deploy to customers>
362500af 1485
1486There are several ways you could deploy your schema. These are probably
1487beyond the scope of this recipe, but might include:
1488
da4779ad 1489=over 4
1490
1491=item 1.
1492
1493Require customer to apply manually using their RDBMS.
1494
1495=item 2.
1496
1497Package along with your app, making database dump/schema update/tests
362500af 1498all part of your install.
1499
da4779ad 1500=back
1501
d2f3e87b 1502B<Modify the schema to change functionality>
362500af 1503
264f1571 1504As your application evolves, it may be necessary to modify your schema
1505to change functionality. Once the changes are made to your schema in
1506DBIx::Class, export the modified schema and the conversion scripts as
d2f3e87b 1507in L</Creating DDL SQL>.
362500af 1508
d2f3e87b 1509B<Deploy update to customers>
362500af 1510
264f1571 1511Add the L<DBIx::Class::Schema::Versioned> schema component to your
1512Schema class. This will add a new table to your database called
ecea7937 1513C<dbix_class_schema_vesion> which will keep track of which version is installed
264f1571 1514and warn if the user trys to run a newer schema version than the
1515database thinks it has.
1516
1517Alternatively, you can send the conversion sql scripts to your
1518customers as above.
362500af 1519
0132e136 1520=head2 Setting quoting for the generated SQL.
d2f3e87b 1521
1522If the database contains column names with spaces and/or reserved words, they
1523need to be quoted in the SQL queries. This is done using:
1524
1525 __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
1526 __PACKAGE__->storage->sql_maker->name_sep('.');
1527
1528The first sets the quote characters. Either a pair of matching
1529brackets, or a C<"> or C<'>:
0132e136 1530
d2f3e87b 1531 __PACKAGE__->storage->sql_maker->quote_char('"');
1532
1533Check the documentation of your database for the correct quote
1534characters to use. C<name_sep> needs to be set to allow the SQL
1535generator to put the quotes the correct place.
1536
0132e136 1537In most cases you should set these as part of the arguments passed to
d68b0c69 1538L<DBIx::Class::Schema/connect>:
d2f3e87b 1539
1540 my $schema = My::Schema->connect(
1541 'dbi:mysql:my_db',
1542 'db_user',
1543 'db_password',
1544 {
1545 quote_char => '"',
1546 name_sep => '.'
1547 }
1548 )
1549
7be93b07 1550=head2 Setting limit dialect for SQL::Abstract::Limit
1551
324572ca 1552In some cases, SQL::Abstract::Limit cannot determine the dialect of
1553the remote SQL server by looking at the database handle. This is a
1554common problem when using the DBD::JDBC, since the DBD-driver only
1555know that in has a Java-driver available, not which JDBC driver the
1556Java component has loaded. This specifically sets the limit_dialect
1557to Microsoft SQL-server (See more names in SQL::Abstract::Limit
1558-documentation.
7be93b07 1559
1560 __PACKAGE__->storage->sql_maker->limit_dialect('mssql');
1561
324572ca 1562The JDBC bridge is one way of getting access to a MSSQL server from a platform
7be93b07 1563that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
1564
0132e136 1565The limit dialect can also be set at connect time by specifying a
d2f3e87b 1566C<limit_dialect> key in the final hash as shown above.
2437a1e3 1567
05697a49 1568=head2 Working with PostgreSQL array types
1569
20ea616f 1570You can also assign values to PostgreSQL array columns by passing array
1571references in the C<\%columns> (C<\%vals>) hashref of the
1572L<DBIx::Class::ResultSet/create> and L<DBIx::Class::Row/update> family of
1573methods:
05697a49 1574
1575 $resultset->create({
1576 numbers => [1, 2, 3]
1577 });
1578
1579 $row->update(
1580 {
1581 numbers => [1, 2, 3]
1582 },
1583 {
1584 day => '2008-11-24'
1585 }
1586 );
1587
1588In conditions (eg. C<\%cond> in the L<DBIx::Class::ResultSet/search> family of
1589methods) you cannot directly use array references (since this is interpreted as
1590a list of values to be C<OR>ed), but you can use the following syntax to force
1591passing them as bind values:
1592
1593 $resultset->search(
1594 {
31eb3263 1595 numbers => \[ '= ?', [numbers => [1, 2, 3]] ]
05697a49 1596 }
1597 );
1598
1599See L<SQL::Abstract/array_datatypes> and L<SQL::Abstract/Literal SQL with
31eb3263 1600placeholders and bind values (subqueries)> for more explanation. Note that
1601L<DBIx::Class> sets L<SQL::Abstract/bindtype> to C<columns>, so you must pass
1602the bind values (the C<[1, 2, 3]> arrayref in the above example) wrapped in
1603arrayrefs together with the column name, like this: C<< [column_name => value]
1604>>.
05697a49 1605
0132e136 1606=head1 BOOTSTRAPPING/MIGRATING
2437a1e3 1607
d2f3e87b 1608=head2 Easy migration from class-based to schema-based setup
2437a1e3 1609
d2f3e87b 1610You want to start using the schema-based approach to L<DBIx::Class>
1611(see L<SchemaIntro.pod>), but have an established class-based setup with lots
1612of existing classes that you don't want to move by hand. Try this nifty script
1613instead:
1614
1615 use MyDB;
1616 use SQL::Translator;
0132e136 1617
d2f3e87b 1618 my $schema = MyDB->schema_instance;
0132e136 1619
1620 my $translator = SQL::Translator->new(
d2f3e87b 1621 debug => $debug || 0,
1622 trace => $trace || 0,
1623 no_comments => $no_comments || 0,
1624 show_warnings => $show_warnings || 0,
1625 add_drop_table => $add_drop_table || 0,
1626 validate => $validate || 0,
1627 parser_args => {
1628 'DBIx::Schema' => $schema,
1629 },
1630 producer_args => {
1631 'prefix' => 'My::Schema',
1632 },
1633 );
0132e136 1634
d2f3e87b 1635 $translator->parser('SQL::Translator::Parser::DBIx::Class');
1636 $translator->producer('SQL::Translator::Producer::DBIx::Class::File');
0132e136 1637
d2f3e87b 1638 my $output = $translator->translate(@args) or die
1639 "Error: " . $translator->error;
0132e136 1640
d2f3e87b 1641 print $output;
2437a1e3 1642
d2f3e87b 1643You could use L<Module::Find> to search for all subclasses in the MyDB::*
1644namespace, which is currently left as an exercise for the reader.
2437a1e3 1645
d2f3e87b 1646=head1 OVERLOADING METHODS
086b93a2 1647
ab872312 1648L<DBIx::Class> uses the L<Class::C3> package, which provides for redispatch of
1649method calls, useful for things like default values and triggers. You have to
1650use calls to C<next::method> to overload methods. More information on using
1651L<Class::C3> with L<DBIx::Class> can be found in
086b93a2 1652L<DBIx::Class::Manual::Component>.
1653
d2f3e87b 1654=head2 Setting default values for a row
1655
1656It's as simple as overriding the C<new> method. Note the use of
1657C<next::method>.
1658
1659 sub new {
1660 my ( $class, $attrs ) = @_;
1661
1662 $attrs->{foo} = 'bar' unless defined $attrs->{foo};
1663
1664 my $new = $class->next::method($attrs);
1665
1666 return $new;
1667 }
1668
0132e136 1669For more information about C<next::method>, look in the L<Class::C3>
d2f3e87b 1670documentation. See also L<DBIx::Class::Manual::Component> for more
1671ways to write your own base classes to do this.
1672
1673People looking for ways to do "triggers" with DBIx::Class are probably
0132e136 1674just looking for this.
d2f3e87b 1675
1676=head2 Changing one field whenever another changes
086b93a2 1677
0132e136 1678For example, say that you have three columns, C<id>, C<number>, and
086b93a2 1679C<squared>. You would like to make changes to C<number> and have
1680C<squared> be automagically set to the value of C<number> squared.
1681You can accomplish this by overriding C<store_column>:
1682
1683 sub store_column {
1684 my ( $self, $name, $value ) = @_;
1685 if ($name eq 'number') {
1686 $self->squared($value * $value);
1687 }
1688 $self->next::method($name, $value);
1689 }
1690
1691Note that the hard work is done by the call to C<next::method>, which
324572ca 1692redispatches your call to store_column in the superclass(es).
086b93a2 1693
d2f3e87b 1694=head2 Automatically creating related objects
086b93a2 1695
0132e136 1696You might have a class C<Artist> which has many C<CD>s. Further, you
086b93a2 1697want to create a C<CD> object every time you insert an C<Artist> object.
ccbebdbc 1698You can accomplish this by overriding C<insert> on your objects:
086b93a2 1699
1700 sub insert {
ccbebdbc 1701 my ( $self, @args ) = @_;
1702 $self->next::method(@args);
086b93a2 1703 $self->cds->new({})->fill_from_artist($self)->insert;
1704 return $self;
1705 }
1706
1707where C<fill_from_artist> is a method you specify in C<CD> which sets
1708values in C<CD> based on the data in the C<Artist> object you pass in.
1709
d2f3e87b 1710=head2 Wrapping/overloading a column accessor
1711
1712B<Problem:>
1713
1714Say you have a table "Camera" and want to associate a description
1715with each camera. For most cameras, you'll be able to generate the description from
1716the other columns. However, in a few special cases you may want to associate a
1717custom description with a camera.
1718
1719B<Solution:>
1720
1721In your database schema, define a description field in the "Camera" table that
1722can contain text and null values.
1723
1724In DBIC, we'll overload the column accessor to provide a sane default if no
1725custom description is defined. The accessor will either return or generate the
1726description, depending on whether the field is null or not.
1727
1728First, in your "Camera" schema class, define the description field as follows:
1729
1730 __PACKAGE__->add_columns(description => { accessor => '_description' });
1731
1732Next, we'll define the accessor-wrapper subroutine:
1733
1734 sub description {
1735 my $self = shift;
1736
1737 # If there is an update to the column, we'll let the original accessor
1738 # deal with it.
1739 return $self->_description(@_) if @_;
1740
1741 # Fetch the column value.
1742 my $description = $self->_description;
1743
1744 # If there's something in the description field, then just return that.
1745 return $description if defined $description && length $descripton;
1746
1747 # Otherwise, generate a description.
1748 return $self->generate_description;
1749 }
1750
1751=head1 DEBUGGING AND PROFILING
1752
1753=head2 DBIx::Class objects with Data::Dumper
1def3451 1754
1755L<Data::Dumper> can be a very useful tool for debugging, but sometimes it can
1756be hard to find the pertinent data in all the data it can generate.
1757Specifically, if one naively tries to use it like so,
1758
1759 use Data::Dumper;
1760
1761 my $cd = $schema->resultset('CD')->find(1);
1762 print Dumper($cd);
1763
1764several pages worth of data from the CD object's schema and result source will
1765be dumped to the screen. Since usually one is only interested in a few column
1766values of the object, this is not very helpful.
1767
1768Luckily, it is possible to modify the data before L<Data::Dumper> outputs
1769it. Simply define a hook that L<Data::Dumper> will call on the object before
1770dumping it. For example,
1771
1772 package My::DB::CD;
1773
1774 sub _dumper_hook {
99fb1058 1775 $_[0] = bless {
1776 %{ $_[0] },
1def3451 1777 result_source => undef,
99fb1058 1778 }, ref($_[0]);
1def3451 1779 }
1780
1781 [...]
1782
1783 use Data::Dumper;
1784
22139027 1785 local $Data::Dumper::Freezer = '_dumper_hook';
1def3451 1786
1787 my $cd = $schema->resultset('CD')->find(1);
1788 print Dumper($cd);
1789 # dumps $cd without its ResultSource
1790
1791If the structure of your schema is such that there is a common base class for
1792all your table classes, simply put a method similar to C<_dumper_hook> in the
1793base class and set C<$Data::Dumper::Freezer> to its name and L<Data::Dumper>
1794will automagically clean up your data before printing it. See
1795L<Data::Dumper/EXAMPLES> for more information.
1796
4c248161 1797=head2 Profiling
1798
85f78622 1799When you enable L<DBIx::Class::Storage>'s debugging it prints the SQL
4c248161 1800executed as well as notifications of query completion and transaction
1801begin/commit. If you'd like to profile the SQL you can subclass the
1802L<DBIx::Class::Storage::Statistics> class and write your own profiling
1803mechanism:
1804
1805 package My::Profiler;
1806 use strict;
1807
1808 use base 'DBIx::Class::Storage::Statistics';
1809
1810 use Time::HiRes qw(time);
1811
1812 my $start;
1813
1814 sub query_start {
1815 my $self = shift();
1816 my $sql = shift();
1817 my $params = @_;
1818
70f39278 1819 $self->print("Executing $sql: ".join(', ', @params)."\n");
4c248161 1820 $start = time();
1821 }
1822
1823 sub query_end {
1824 my $self = shift();
1825 my $sql = shift();
1826 my @params = @_;
1827
70f39278 1828 my $elapsed = sprintf("%0.4f", time() - $start);
1829 $self->print("Execution took $elapsed seconds.\n");
4c248161 1830 $start = undef;
1831 }
1832
1833 1;
1834
1835You can then install that class as the debugging object:
1836
70f39278 1837 __PACKAGE__->storage->debugobj(new My::Profiler());
1838 __PACKAGE__->storage->debug(1);
4c248161 1839
1840A more complicated example might involve storing each execution of SQL in an
1841array:
1842
1843 sub query_end {
1844 my $self = shift();
1845 my $sql = shift();
1846 my @params = @_;
1847
1848 my $elapsed = time() - $start;
1849 push(@{ $calls{$sql} }, {
1850 params => \@params,
1851 elapsed => $elapsed
1852 });
1853 }
1854
1855You could then create average, high and low execution times for an SQL
1856statement and dig down to see if certain parameters cause aberrant behavior.
70f39278 1857You might want to check out L<DBIx::Class::QueryLog> as well.
4c248161 1858
bc96f260 1859=head1 STARTUP SPEED
1860
1861L<DBIx::Class|DBIx::Class> programs can have a significant startup delay
1862as the ORM loads all the relevant classes. This section examines
1863techniques for reducing the startup delay.
1864
1865These tips are are listed in order of decreasing effectiveness - so the
1866first tip, if applicable, should have the greatest effect on your
1867application.
1868
1869=head2 Statically Define Your Schema
1870
1871If you are using
1872L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to build the
1873classes dynamically based on the database schema then there will be a
1874significant startup delay.
1875
1876For production use a statically defined schema (which can be generated
1877using L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to dump
1878the database schema once - see
1879L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> and
1880L<dump_directory|DBIx::Class::Schema::Loader/dump_directory> for more
1881details on creating static schemas from a database).
1882
1883=head2 Move Common Startup into a Base Class
1884
1885Typically L<DBIx::Class> result classes start off with
1886
1887 use base qw/DBIx::Class/;
1888 __PACKAGE__->load_components(qw/InflateColumn::DateTime Core/);
1889
1890If this preamble is moved into a common base class:-
1891
1892 package MyDBICbase;
0132e136 1893
bc96f260 1894 use base qw/DBIx::Class/;
1895 __PACKAGE__->load_components(qw/InflateColumn::DateTime Core/);
1896 1;
1897
1898and each result class then uses this as a base:-
1899
1900 use base qw/MyDBICbase/;
1901
1902then the load_components is only performed once, which can result in a
1903considerable startup speedup for schemas with many classes.
1904
1905=head2 Explicitly List Schema Result Classes
1906
1907The schema class will normally contain
1908
1909 __PACKAGE__->load_classes();
1910
1911to load the result classes. This will use L<Module::Find|Module::Find>
1912to find and load the appropriate modules. Explicitly defining the
1913classes you wish to load will remove the overhead of
0132e136 1914L<Module::Find|Module::Find> and the related directory operations:
bc96f260 1915
1916 __PACKAGE__->load_classes(qw/ CD Artist Track /);
1917
1918If you are instead using the L<load_namespaces|DBIx::Class::Schema/load_namespaces>
1919syntax to load the appropriate classes there is not a direct alternative
1920avoiding L<Module::Find|Module::Find>.
7aaec96c 1921
f4db5947 1922=head1 MEMORY USAGE
1923
1924=head2 Cached statements
1925
1926L<DBIx::Class> normally caches all statements with L<< prepare_cached()|DBI/prepare_cached >>.
1927This is normally a good idea, but if too many statements are cached, the database may use too much
1928memory and may eventually run out and fail entirely. If you suspect this may be the case, you may want
1929to examine DBI's L<< CachedKids|DBI/CachedKidsCachedKids_(hash_ref) >> hash:
1930
1931 # print all currently cached prepared statements
1932 print for keys %{$schema->storage->dbh->{CachedKids}};
1933 # get a count of currently cached prepared statements
1934 my $count = scalar keys %{$schema->storage->dbh->{CachedKids}};
1935
1936If it's appropriate, you can simply clear these statements, automatically deallocating them in the
1937database:
1938
1939 my $kids = $schema->storage->dbh->{CachedKids};
1940 delete @{$kids}{keys %$kids} if scalar keys %$kids > 100;
1941
1942But what you probably want is to expire unused statements and not those that are used frequently.
1943You can accomplish this with L<Tie::Cache> or L<Tie::Cache::LRU>:
1944
1945 use Tie::Cache;
1946 use DB::Main;
1947 my $schema = DB::Main->connect($dbi_dsn, $user, $pass, {
1948 on_connect_do => sub { tie %{shift->_dbh->{CachedKids}}, 'Tie::Cache', 100 },
1949 });
1950
40dbc108 1951=cut