allow count() with GROUP BY
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use overload
6         '0+'     => 'count',
7         'bool'   => sub { 1; },
8         fallback => 1;
9 use Data::Page;
10 use Storable;
11
12 use base qw/DBIx::Class/;
13 __PACKAGE__->load_components(qw/AccessorGroup/);
14 __PACKAGE__->mk_group_accessors('simple' => 'result_source');
15
16 =head1 NAME
17
18 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
19
20 =head1 SYNOPSIS
21
22   my $rs   = $schema->resultset('User')->search(registered => 1);
23   my @rows = $schema->resultset('Foo')->search(bar => 'baz');
24
25 =head1 DESCRIPTION
26
27 The resultset is also known as an iterator. It is responsible for handling
28 queries that may return an arbitrary number of rows, e.g. via L</search>
29 or a C<has_many> relationship.
30
31 In the examples below, the following table classes are used:
32
33   package MyApp::Schema::Artist;
34   use base qw/DBIx::Class/;
35   __PACKAGE__->table('artist');
36   __PACKAGE__->add_columns(qw/artistid name/);
37   __PACKAGE__->set_primary_key('artistid');
38   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
39   1;
40
41   package MyApp::Schema::CD;
42   use base qw/DBIx::Class/;
43   __PACKAGE__->table('artist');
44   __PACKAGE__->add_columns(qw/cdid artist title year/);
45   __PACKAGE__->set_primary_key('cdid');
46   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
47   1;
48
49 =head1 METHODS
50
51 =head2 new($source, \%$attrs)
52
53 The resultset constructor. Takes a source object (usually a
54 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see L</ATRRIBUTES>
55 below).  Does not perform any queries -- these are executed as needed by the
56 other methods.
57
58 Generally you won't need to construct a resultset manually.  You'll
59 automatically get one from e.g. a L</search> called in scalar context:
60
61   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
62
63 =cut
64
65 sub new {
66   my $class = shift;
67   return $class->new_result(@_) if ref $class;
68   my ($source, $attrs) = @_;
69   #use Data::Dumper; warn Dumper($attrs);
70   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
71   my %seen;
72   my $alias = ($attrs->{alias} ||= 'me');
73   if ($attrs->{cols} || !$attrs->{select}) {
74     delete $attrs->{as} if $attrs->{cols};
75     my @cols = ($attrs->{cols}
76                  ? @{delete $attrs->{cols}}
77                  : $source->columns);
78     $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @cols ];
79   }
80   $attrs->{as} ||= [ map { m/^$alias\.(.*)$/ ? $1 : $_ } @{$attrs->{select}} ];
81   #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
82   $attrs->{from} ||= [ { $alias => $source->from } ];
83   if (my $join = delete $attrs->{join}) {
84     foreach my $j (ref $join eq 'ARRAY'
85               ? (@{$join}) : ($join)) {
86       if (ref $j eq 'HASH') {
87         $seen{$_} = 1 foreach keys %$j;
88       } else {
89         $seen{$j} = 1;
90       }
91     }
92     push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}));
93   }
94   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
95
96   if (my $prefetch = delete $attrs->{prefetch}) {
97     foreach my $p (ref $prefetch eq 'ARRAY'
98               ? (@{$prefetch}) : ($prefetch)) {
99       if( ref $p eq 'HASH' ) {
100         foreach my $key (keys %$p) {
101           push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
102             unless $seen{$key};
103         }
104       }
105       else {
106         push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
107             unless $seen{$p};
108       }
109       my @cols = ();
110       push @cols, $source->resolve_prefetch($p, $attrs->{alias});
111       #die Dumper \@cols;
112       push(@{$attrs->{select}}, @cols);
113       push(@{$attrs->{as}}, @cols);
114     }
115   }
116
117   if ($attrs->{page}) {
118     $attrs->{rows} ||= 10;
119     $attrs->{offset} ||= 0;
120     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
121   }
122   my $new = {
123     result_source => $source,
124     cond => $attrs->{where},
125     from => $attrs->{from},
126     count => undef,
127     page => delete $attrs->{page},
128     pager => undef,
129     attrs => $attrs };
130   bless ($new, $class);
131   return $new;
132 }
133
134 =head2 search
135
136   my @obj    = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
137   my $new_rs = $rs->search({ foo => 3 });
138
139 If you need to pass in additional attributes but no additional condition,
140 call it as C<search({}, \%attrs);>.
141
142   # "SELECT foo, bar FROM $class_table"
143   my @all = $class->search({}, { cols => [qw/foo bar/] });
144
145 =cut
146
147 sub search {
148   my $self = shift;
149
150   #use Data::Dumper;warn Dumper(@_);
151
152   my $attrs = { %{$self->{attrs}} };
153   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
154     $attrs = { %$attrs, %{ pop(@_) } };
155   }
156
157   my $where = (@_ ? ((@_ == 1 || ref $_[0] eq "HASH") ? shift : {@_}) : undef());
158   if (defined $where) {
159     $where = (defined $attrs->{where}
160                 ? { '-and' =>
161                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
162                         $where, $attrs->{where} ] }
163                 : $where);
164     $attrs->{where} = $where;
165   }
166
167   my $rs = (ref $self)->new($self->result_source, $attrs);
168
169   return (wantarray ? $rs->all : $rs);
170 }
171
172 =head2 search_literal
173
174   my @obj    = $rs->search_literal($literal_where_cond, @bind);
175   my $new_rs = $rs->search_literal($literal_where_cond, @bind);
176
177 Pass a literal chunk of SQL to be added to the conditional part of the
178 resultset.
179
180 =cut
181                                                          
182 sub search_literal {
183   my ($self, $cond, @vals) = @_;
184   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
185   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
186   return $self->search(\$cond, $attrs);
187 }
188
189 =head2 find(@colvalues), find(\%cols, \%attrs?)
190
191 Finds a row based on its primary key or unique constraint. For example:
192
193   my $cd = $schema->resultset('CD')->find(5);
194
195 Also takes an optional C<key> attribute, to search by a specific key or unique
196 constraint. For example:
197
198   my $cd = $schema->resultset('CD')->find_or_create(
199     {
200       artist => 'Massive Attack',
201       title  => 'Mezzanine',
202     },
203     { key => 'artist_title' }
204   );
205
206 See also L</find_or_create> and L</update_or_create>.
207
208 =cut
209
210 sub find {
211   my ($self, @vals) = @_;
212   my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
213
214   my @cols = $self->result_source->primary_columns;
215   if (exists $attrs->{key}) {
216     my %uniq = $self->result_source->unique_constraints;
217     $self->( "Unknown key " . $attrs->{key} . " on " . $self->name )
218       unless exists $uniq{$attrs->{key}};
219     @cols = @{ $uniq{$attrs->{key}} };
220   }
221   #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
222   $self->throw_exception( "Can't find unless a primary key or unique constraint is defined" )
223     unless @cols;
224
225   my $query;
226   if (ref $vals[0] eq 'HASH') {
227     $query = $vals[0];
228   } elsif (@cols == @vals) {
229     $query = {};
230     @{$query}{@cols} = @vals;
231   } else {
232     $query = {@vals};
233   }
234   #warn Dumper($query);
235   return $self->search($query)->next;
236 }
237
238 =head2 search_related
239
240   $rs->search_related('relname', $cond?, $attrs?);
241
242 Search the specified relationship. Optionally specify a condition for matching
243 records.
244
245 =cut
246
247 sub search_related {
248   my ($self, $rel, @rest) = @_;
249   my $rel_obj = $self->result_source->relationship_info($rel);
250   $self->throw_exception(
251     "No such relationship ${rel} in search_related")
252       unless $rel_obj;
253   my $rs = $self->search(undef, { join => $rel });
254   return $self->result_source->schema->resultset($rel_obj->{class}
255            )->search( undef,
256              { %{$rs->{attrs}},
257                alias => $rel,
258                select => undef(),
259                as => undef() }
260            )->search(@rest);
261 }
262
263 =head2 cursor
264
265 Returns a storage-driven cursor to the given resultset.
266
267 =cut
268
269 sub cursor {
270   my ($self) = @_;
271   my ($attrs) = $self->{attrs};
272   $attrs = { %$attrs };
273   return $self->{cursor}
274     ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
275           $attrs->{where},$attrs);
276 }
277
278 =head2 search_like
279
280 Perform a search, but use C<LIKE> instead of equality as the condition. Note
281 that this is simply a convenience method; you most likely want to use
282 L</search> with specific operators.
283
284 For more information, see L<DBIx::Class::Manual::Cookbook>.
285
286 =cut
287
288 sub search_like {
289   my $class    = shift;
290   my $attrs = { };
291   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
292     $attrs = pop(@_);
293   }
294   my $query    = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
295   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
296   return $class->search($query, { %$attrs });
297 }
298
299 =head2 slice($first, $last)
300
301 Returns a subset of elements from the resultset.
302
303 =cut
304
305 sub slice {
306   my ($self, $min, $max) = @_;
307   my $attrs = { %{ $self->{attrs} || {} } };
308   $attrs->{offset} ||= 0;
309   $attrs->{offset} += $min;
310   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
311   my $slice = (ref $self)->new($self->result_source, $attrs);
312   return (wantarray ? $slice->all : $slice);
313 }
314
315 =head2 next
316
317 Returns the next element in the resultset (C<undef> is there is none).
318
319 Can be used to efficiently iterate over records in the resultset:
320
321   my $rs = $schema->resultset('CD')->search({});
322   while (my $cd = $rs->next) {
323     print $cd->title;
324   }
325
326 =cut
327
328 sub next {
329   my ($self) = @_;
330   my @row = $self->cursor->next;
331 #  warn Dumper(\@row); use Data::Dumper;
332   return unless (@row);
333   return $self->_construct_object(@row);
334 }
335
336 sub _construct_object {
337   my ($self, @row) = @_;
338   my @as = @{ $self->{attrs}{as} };
339   #warn "@cols -> @row";
340   my $info = [ {}, {} ];
341   foreach my $as (@as) {
342     my $target = $info;
343     my @parts = split(/\./, $as);
344     my $col = pop(@parts);
345     foreach my $p (@parts) {
346       $target = $target->[1]->{$p} ||= [];
347     }
348     $target->[0]->{$col} = shift @row;
349   }
350   #use Data::Dumper; warn Dumper(\@as, $info);
351   my $new = $self->result_source->result_class->inflate_result(
352               $self->result_source, @$info);
353   $new = $self->{attrs}{record_filter}->($new)
354     if exists $self->{attrs}{record_filter};
355   return $new;
356 }
357
358 =head2 result_source 
359
360 Returns a reference to the result source for this recordset.
361
362 =cut
363
364
365 =head2 count
366
367 Performs an SQL C<COUNT> with the same query as the resultset was built
368 with to find the number of elements. If passed arguments, does a search
369 on the resultset and counts the results of that.
370
371 =cut
372
373 sub count {
374   my $self = shift;
375   return $self->search(@_)->count if @_ && defined $_[0];
376   unless (defined $self->{count}) {
377     my $group_by;
378     my $select = { 'count' => '*' };
379     if( $group_by = delete $self->{attrs}{group_by} ) {
380       my @distinct = @$group_by;
381       # todo: try CONCAT for multi-column pk
382       my @pk = $self->result_source->primary_columns;
383       if( scalar(@pk) == 1 ) {
384         my $pk = shift(@pk);
385         my $alias = $self->{attrs}{alias};
386         my $re = qr/^($alias\.)?$pk$/;
387         foreach my $column ( @$group_by ) {
388           if( $column =~ $re ) {
389             @distinct = ( $column );
390             last;
391           }
392         } 
393       }
394
395       $select = { count => { 'distinct' => \@distinct } };
396       #use Data::Dumper; die Dumper $select;
397     }
398
399     my $attrs = { %{ $self->{attrs} },
400                   select => $select,
401                   as => [ 'count' ] };
402     # offset, order by and page are not needed to count. record_filter is cdbi
403     delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
404         
405     ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
406     $self->{attrs}{group_by} = $group_by;
407   }
408   return 0 unless $self->{count};
409   my $count = $self->{count};
410   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
411   $count = $self->{attrs}{rows} if
412     ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
413   return $count;
414 }
415
416 =head2 count_literal
417
418 Calls L</search_literal> with the passed arguments, then L</count>.
419
420 =cut
421
422 sub count_literal { shift->search_literal(@_)->count; }
423
424 =head2 all
425
426 Returns all elements in the resultset. Called implictly if the resultset
427 is returned in list context.
428
429 =cut
430
431 sub all {
432   my ($self) = @_;
433   return map { $self->_construct_object(@$_); }
434            $self->cursor->all;
435 }
436
437 =head2 reset
438
439 Resets the resultset's cursor, so you can iterate through the elements again.
440
441 =cut
442
443 sub reset {
444   my ($self) = @_;
445   $self->cursor->reset;
446   return $self;
447 }
448
449 =head2 first
450
451 Resets the resultset and returns the first element.
452
453 =cut
454
455 sub first {
456   return $_[0]->reset->next;
457 }
458
459 =head2 update(\%values)
460
461 Sets the specified columns in the resultset to the supplied values.
462
463 =cut
464
465 sub update {
466   my ($self, $values) = @_;
467   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
468   return $self->result_source->storage->update(
469            $self->result_source->from, $values, $self->{cond});
470 }
471
472 =head2 update_all(\%values)
473
474 Fetches all objects and updates them one at a time.  Note that C<update_all>
475 will run cascade triggers while L</update> will not.
476
477 =cut
478
479 sub update_all {
480   my ($self, $values) = @_;
481   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
482   foreach my $obj ($self->all) {
483     $obj->set_columns($values)->update;
484   }
485   return 1;
486 }
487
488 =head2 delete
489
490 Deletes the contents of the resultset from its result source.
491
492 =cut
493
494 sub delete {
495   my ($self) = @_;
496   $self->result_source->storage->delete($self->result_source->from, $self->{cond});
497   return 1;
498 }
499
500 =head2 delete_all
501
502 Fetches all objects and deletes them one at a time.  Note that C<delete_all>
503 will run cascade triggers while L</delete> will not.
504
505 =cut
506
507 sub delete_all {
508   my ($self) = @_;
509   $_->delete for $self->all;
510   return 1;
511 }
512
513 =head2 pager
514
515 Returns a L<Data::Page> object for the current resultset. Only makes
516 sense for queries with a C<page> attribute.
517
518 =cut
519
520 sub pager {
521   my ($self) = @_;
522   my $attrs = $self->{attrs};
523   $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
524   $attrs->{rows} ||= 10;
525   $self->count;
526   return $self->{pager} ||= Data::Page->new(
527     $self->{count}, $attrs->{rows}, $self->{page});
528 }
529
530 =head2 page($page_num)
531
532 Returns a new resultset for the specified page.
533
534 =cut
535
536 sub page {
537   my ($self, $page) = @_;
538   my $attrs = { %{$self->{attrs}} };
539   $attrs->{page} = $page;
540   return (ref $self)->new($self->result_source, $attrs);
541 }
542
543 =head2 new_result(\%vals)
544
545 Creates a result in the resultset's result class.
546
547 =cut
548
549 sub new_result {
550   my ($self, $values) = @_;
551   $self->throw_exception( "new_result needs a hash" )
552     unless (ref $values eq 'HASH');
553   $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
554     if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
555   my %new = %$values;
556   my $alias = $self->{attrs}{alias};
557   foreach my $key (keys %{$self->{cond}||{}}) {
558     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
559   }
560   my $obj = $self->result_source->result_class->new(\%new);
561   $obj->result_source($self->result_source) if $obj->can('result_source');
562   $obj;
563 }
564
565 =head2 create(\%vals)
566
567 Inserts a record into the resultset and returns the object.
568
569 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
570
571 =cut
572
573 sub create {
574   my ($self, $attrs) = @_;
575   $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
576   return $self->new_result($attrs)->insert;
577 }
578
579 =head2 find_or_create(\%vals, \%attrs?)
580
581   $class->find_or_create({ key => $val, ... });
582
583 Searches for a record matching the search condition; if it doesn't find one,    
584 creates one and returns that instead.                                       
585
586   my $cd = $schema->resultset('CD')->find_or_create({
587     cdid   => 5,
588     artist => 'Massive Attack',
589     title  => 'Mezzanine',
590     year   => 2005,
591   });
592
593 Also takes an optional C<key> attribute, to search by a specific key or unique
594 constraint. For example:
595
596   my $cd = $schema->resultset('CD')->find_or_create(
597     {
598       artist => 'Massive Attack',
599       title  => 'Mezzanine',
600     },
601     { key => 'artist_title' }
602   );
603
604 See also L</find> and L</update_or_create>.
605
606 =cut
607
608 sub find_or_create {
609   my $self     = shift;
610   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
611   my $hash     = ref $_[0] eq "HASH" ? shift : {@_};
612   my $exists   = $self->find($hash, $attrs);
613   return defined($exists) ? $exists : $self->create($hash);
614 }
615
616 =head2 update_or_create
617
618   $class->update_or_create({ key => $val, ... });
619
620 First, search for an existing row matching one of the unique constraints
621 (including the primary key) on the source of this resultset.  If a row is
622 found, update it with the other given column values.  Otherwise, create a new
623 row.
624
625 Takes an optional C<key> attribute to search on a specific unique constraint.
626 For example:
627
628   # In your application
629   my $cd = $schema->resultset('CD')->update_or_create(
630     {
631       artist => 'Massive Attack',
632       title  => 'Mezzanine',
633       year   => 1998,
634     },
635     { key => 'artist_title' }
636   );
637
638 If no C<key> is specified, it searches on all unique constraints defined on the
639 source, including the primary key.
640
641 If the C<key> is specified as C<primary>, search only on the primary key.
642
643 See also L</find> and L</find_or_create>.
644
645 =cut
646
647 sub update_or_create {
648   my $self = shift;
649
650   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
651   my $hash  = ref $_[0] eq "HASH" ? shift : {@_};
652
653   my %unique_constraints = $self->result_source->unique_constraints;
654   my @constraint_names   = (exists $attrs->{key}
655                             ? ($attrs->{key})
656                             : keys %unique_constraints);
657
658   my @unique_hashes;
659   foreach my $name (@constraint_names) {
660     my @unique_cols = @{ $unique_constraints{$name} };
661     my %unique_hash =
662       map  { $_ => $hash->{$_} }
663       grep { exists $hash->{$_} }
664       @unique_cols;
665
666     push @unique_hashes, \%unique_hash
667       if (scalar keys %unique_hash == scalar @unique_cols);
668   }
669
670   my $row;
671   if (@unique_hashes) {
672     $row = $self->search(\@unique_hashes, { rows => 1 })->first;
673     if ($row) {
674       $row->set_columns($hash);
675       $row->update;
676     }
677   }
678
679   unless ($row) {
680     $row = $self->create($hash);
681   }
682
683   return $row;
684 }
685
686 =head2 throw_exception
687
688 See Schema's throw_exception
689
690 =cut
691
692 sub throw_exception {
693   my $self=shift;
694   $self->result_source->schema->throw_exception(@_);
695 }
696
697 =head1 ATTRIBUTES
698
699 The resultset takes various attributes that modify its behavior. Here's an
700 overview of them:
701
702 =head2 order_by
703
704 Which column(s) to order the results by. This is currently passed through
705 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
706
707 =head2 cols (arrayref)
708
709 Shortcut to request a particular set of columns to be retrieved.  Adds
710 C<me.> onto the start of any column without a C<.> in it and sets C<select>
711 from that, then auto-populates C<as> from C<select> as normal.
712
713 =head2 select (arrayref)
714
715 Indicates which columns should be selected from the storage. You can use
716 column names, or in the case of RDBMS back ends, function or stored procedure
717 names:
718
719   $rs = $schema->resultset('Foo')->search(
720     {},
721     {
722       select => [
723         'column_name',
724         { count => 'column_to_count' },
725         { sum => 'column_to_sum' }
726       ]
727     }
728   );
729
730 When you use function/stored procedure names and do not supply an C<as>
731 attribute, the column names returned are storage-dependent. E.g. MySQL would
732 return a column named C<count(column_to_count)> in the above example.
733
734 =head2 as (arrayref)
735
736 Indicates column names for object inflation. This is used in conjunction with
737 C<select>, usually when C<select> contains one or more function or stored
738 procedure names:
739
740   $rs = $schema->resultset('Foo')->search(
741     {},
742     {
743       select => [
744         'column1',
745         { count => 'column2' }
746       ],
747       as => [qw/ column1 column2_count /]
748     }
749   );
750
751   my $foo = $rs->first(); # get the first Foo
752
753 If the object against which the search is performed already has an accessor
754 matching a column name specified in C<as>, the value can be retrieved using
755 the accessor as normal:
756
757   my $column1 = $foo->column1();
758
759 If on the other hand an accessor does not exist in the object, you need to
760 use C<get_column> instead:
761
762   my $column2_count = $foo->get_column('column2_count');
763
764 You can create your own accessors if required - see
765 L<DBIx::Class::Manual::Cookbook> for details.
766
767 =head2 join
768
769 Contains a list of relationships that should be joined for this query.  For
770 example:
771
772   # Get CDs by Nine Inch Nails
773   my $rs = $schema->resultset('CD')->search(
774     { 'artist.name' => 'Nine Inch Nails' },
775     { join => 'artist' }
776   );
777
778 Can also contain a hash reference to refer to the other relation's relations.
779 For example:
780
781   package MyApp::Schema::Track;
782   use base qw/DBIx::Class/;
783   __PACKAGE__->table('track');
784   __PACKAGE__->add_columns(qw/trackid cd position title/);
785   __PACKAGE__->set_primary_key('trackid');
786   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
787   1;
788
789   # In your application
790   my $rs = $schema->resultset('Artist')->search(
791     { 'track.title' => 'Teardrop' },
792     {
793       join     => { cd => 'track' },
794       order_by => 'artist.name',
795     }
796   );
797
798 If you want to fetch columns from related tables as well, see C<prefetch>
799 below.
800
801 =head2 prefetch arrayref/hashref
802
803 Contains one or more relationships that should be fetched along with the main 
804 query (when they are accessed afterwards they will have already been
805 "prefetched").  This is useful for when you know you will need the related
806 objects, because it saves at least one query:
807
808   my $rs = $schema->resultset('Tag')->search(
809     {},
810     {
811       prefetch => {
812         cd => 'artist'
813       }
814     }
815   );
816
817 The initial search results in SQL like the following:
818
819   SELECT tag.*, cd.*, artist.* FROM tag
820   JOIN cd ON tag.cd = cd.cdid
821   JOIN artist ON cd.artist = artist.artistid
822
823 L<DBIx::Class> has no need to go back to the database when we access the
824 C<cd> or C<artist> relationships, which saves us two SQL statements in this
825 case.
826
827 Any prefetched relationship will be joined automatically, so there is no need
828 for a C<join> attribute in the above search.
829
830 C<prefetch> can be used with the following relationship types: C<belongs_to>,
831 C<has_one>.
832
833 =head2 from (arrayref)
834
835 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
836 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
837 clauses.
838
839 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
840 C<join> will usually do what you need and it is strongly recommended that you
841 avoid using C<from> unless you cannot achieve the desired result using C<join>.
842
843 In simple terms, C<from> works as follows:
844
845     [
846         { <alias> => <table>, -join-type => 'inner|left|right' }
847         [] # nested JOIN (optional)
848         { <table.column> = <foreign_table.foreign_key> }
849     ]
850
851     JOIN
852         <alias> <table>
853         [JOIN ...]
854     ON <table.column> = <foreign_table.foreign_key>
855
856 An easy way to follow the examples below is to remember the following:
857
858     Anything inside "[]" is a JOIN
859     Anything inside "{}" is a condition for the enclosing JOIN
860
861 The following examples utilize a "person" table in a family tree application.
862 In order to express parent->child relationships, this table is self-joined:
863
864     # Person->belongs_to('father' => 'Person');
865     # Person->belongs_to('mother' => 'Person');
866
867 C<from> can be used to nest joins. Here we return all children with a father,
868 then search against all mothers of those children:
869
870   $rs = $schema->resultset('Person')->search(
871       {},
872       {
873           alias => 'mother', # alias columns in accordance with "from"
874           from => [
875               { mother => 'person' },
876               [
877                   [
878                       { child => 'person' },
879                       [
880                           { father => 'person' },
881                           { 'father.person_id' => 'child.father_id' }
882                       ]
883                   ],
884                   { 'mother.person_id' => 'child.mother_id' }
885               ],                
886           ]
887       },
888   );
889
890   # Equivalent SQL:
891   # SELECT mother.* FROM person mother
892   # JOIN (
893   #   person child
894   #   JOIN person father
895   #   ON ( father.person_id = child.father_id )
896   # )
897   # ON ( mother.person_id = child.mother_id )
898
899 The type of any join can be controlled manually. To search against only people
900 with a father in the person table, we could explicitly use C<INNER JOIN>:
901
902     $rs = $schema->resultset('Person')->search(
903         {},
904         {
905             alias => 'child', # alias columns in accordance with "from"
906             from => [
907                 { child => 'person' },
908                 [
909                     { father => 'person', -join-type => 'inner' },
910                     { 'father.id' => 'child.father_id' }
911                 ],
912             ]
913         },
914     );
915
916     # Equivalent SQL:
917     # SELECT child.* FROM person child
918     # INNER JOIN person father ON child.father_id = father.id
919
920 =head2 page
921
922 For a paged resultset, specifies which page to retrieve.  Leave unset
923 for an unpaged resultset.
924
925 =head2 rows
926
927 For a paged resultset, how many rows per page:
928
929   rows => 10
930
931 Can also be used to simulate an SQL C<LIMIT>.
932
933 =head2 group_by (arrayref)
934
935 A arrayref of columns to group by. Can include columns of joined tables. Note
936 note that L</count> doesn't work on grouped resultsets.
937
938   group_by => [qw/ column1 column2 ... /]
939
940 =head2 distinct
941
942 Set to 1 to group by all columns.
943
944 For more examples of using these attributes, see
945 L<DBIx::Class::Manual::Cookbook>.
946
947 =cut
948
949 1;