Fix to find for complex resultsets
[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   foreach (keys %$query) {
235     next if m/\./;
236     $query->{$self->{attrs}{alias}.'.'.$_} = delete $query->{$_};
237   }
238   #warn Dumper($query);
239   return $self->search($query)->next;
240 }
241
242 =head2 search_related
243
244   $rs->search_related('relname', $cond?, $attrs?);
245
246 Search the specified relationship. Optionally specify a condition for matching
247 records.
248
249 =cut
250
251 sub search_related {
252   my ($self, $rel, @rest) = @_;
253   my $rel_obj = $self->result_source->relationship_info($rel);
254   $self->throw_exception(
255     "No such relationship ${rel} in search_related")
256       unless $rel_obj;
257   my $rs = $self->search(undef, { join => $rel });
258   return $self->result_source->schema->resultset($rel_obj->{class}
259            )->search( undef,
260              { %{$rs->{attrs}},
261                alias => $rel,
262                select => undef(),
263                as => undef() }
264            )->search(@rest);
265 }
266
267 =head2 cursor
268
269 Returns a storage-driven cursor to the given resultset.
270
271 =cut
272
273 sub cursor {
274   my ($self) = @_;
275   my ($attrs) = $self->{attrs};
276   $attrs = { %$attrs };
277   return $self->{cursor}
278     ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
279           $attrs->{where},$attrs);
280 }
281
282 =head2 search_like
283
284 Perform a search, but use C<LIKE> instead of equality as the condition. Note
285 that this is simply a convenience method; you most likely want to use
286 L</search> with specific operators.
287
288 For more information, see L<DBIx::Class::Manual::Cookbook>.
289
290 =cut
291
292 sub search_like {
293   my $class    = shift;
294   my $attrs = { };
295   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
296     $attrs = pop(@_);
297   }
298   my $query    = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
299   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
300   return $class->search($query, { %$attrs });
301 }
302
303 =head2 slice($first, $last)
304
305 Returns a subset of elements from the resultset.
306
307 =cut
308
309 sub slice {
310   my ($self, $min, $max) = @_;
311   my $attrs = { %{ $self->{attrs} || {} } };
312   $attrs->{offset} ||= 0;
313   $attrs->{offset} += $min;
314   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
315   my $slice = (ref $self)->new($self->result_source, $attrs);
316   return (wantarray ? $slice->all : $slice);
317 }
318
319 =head2 next
320
321 Returns the next element in the resultset (C<undef> is there is none).
322
323 Can be used to efficiently iterate over records in the resultset:
324
325   my $rs = $schema->resultset('CD')->search({});
326   while (my $cd = $rs->next) {
327     print $cd->title;
328   }
329
330 =cut
331
332 sub next {
333   my ($self) = @_;
334   my @row = $self->cursor->next;
335 #  warn Dumper(\@row); use Data::Dumper;
336   return unless (@row);
337   return $self->_construct_object(@row);
338 }
339
340 sub _construct_object {
341   my ($self, @row) = @_;
342   my @as = @{ $self->{attrs}{as} };
343   #warn "@cols -> @row";
344   my $info = [ {}, {} ];
345   foreach my $as (@as) {
346     my $target = $info;
347     my @parts = split(/\./, $as);
348     my $col = pop(@parts);
349     foreach my $p (@parts) {
350       $target = $target->[1]->{$p} ||= [];
351     }
352     $target->[0]->{$col} = shift @row;
353   }
354   #use Data::Dumper; warn Dumper(\@as, $info);
355   my $new = $self->result_source->result_class->inflate_result(
356               $self->result_source, @$info);
357   $new = $self->{attrs}{record_filter}->($new)
358     if exists $self->{attrs}{record_filter};
359   return $new;
360 }
361
362 =head2 result_source 
363
364 Returns a reference to the result source for this recordset.
365
366 =cut
367
368
369 =head2 count
370
371 Performs an SQL C<COUNT> with the same query as the resultset was built
372 with to find the number of elements. If passed arguments, does a search
373 on the resultset and counts the results of that.
374
375 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
376 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
377 not support C<DISTINCT> with multiple columns. If you are using such a
378 database, you should only use columns from the main table in your C<group_by>
379 clause.
380
381 =cut
382
383 sub count {
384   my $self = shift;
385   return $self->search(@_)->count if @_ && defined $_[0];
386   unless (defined $self->{count}) {
387     my $group_by;
388     my $select = { 'count' => '*' };
389     if( $group_by = delete $self->{attrs}{group_by} ) {
390       my @distinct = @$group_by;
391       # todo: try CONCAT for multi-column pk
392       my @pk = $self->result_source->primary_columns;
393       if( scalar(@pk) == 1 ) {
394         my $pk = shift(@pk);
395         my $alias = $self->{attrs}{alias};
396         my $re = qr/^($alias\.)?$pk$/;
397         foreach my $column ( @$group_by ) {
398           if( $column =~ $re ) {
399             @distinct = ( $column );
400             last;
401           }
402         } 
403       }
404
405       $select = { count => { 'distinct' => \@distinct } };
406       #use Data::Dumper; die Dumper $select;
407     }
408
409     my $attrs = { %{ $self->{attrs} },
410                   select => $select,
411                   as => [ 'count' ] };
412     # offset, order by and page are not needed to count. record_filter is cdbi
413     delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
414         
415     ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
416     $self->{attrs}{group_by} = $group_by;
417   }
418   return 0 unless $self->{count};
419   my $count = $self->{count};
420   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
421   $count = $self->{attrs}{rows} if
422     ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
423   return $count;
424 }
425
426 =head2 count_literal
427
428 Calls L</search_literal> with the passed arguments, then L</count>.
429
430 =cut
431
432 sub count_literal { shift->search_literal(@_)->count; }
433
434 =head2 all
435
436 Returns all elements in the resultset. Called implictly if the resultset
437 is returned in list context.
438
439 =cut
440
441 sub all {
442   my ($self) = @_;
443   return map { $self->_construct_object(@$_); }
444            $self->cursor->all;
445 }
446
447 =head2 reset
448
449 Resets the resultset's cursor, so you can iterate through the elements again.
450
451 =cut
452
453 sub reset {
454   my ($self) = @_;
455   $self->cursor->reset;
456   return $self;
457 }
458
459 =head2 first
460
461 Resets the resultset and returns the first element.
462
463 =cut
464
465 sub first {
466   return $_[0]->reset->next;
467 }
468
469 =head2 update(\%values)
470
471 Sets the specified columns in the resultset to the supplied values.
472
473 =cut
474
475 sub update {
476   my ($self, $values) = @_;
477   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
478   return $self->result_source->storage->update(
479            $self->result_source->from, $values, $self->{cond});
480 }
481
482 =head2 update_all(\%values)
483
484 Fetches all objects and updates them one at a time.  Note that C<update_all>
485 will run cascade triggers while L</update> will not.
486
487 =cut
488
489 sub update_all {
490   my ($self, $values) = @_;
491   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
492   foreach my $obj ($self->all) {
493     $obj->set_columns($values)->update;
494   }
495   return 1;
496 }
497
498 =head2 delete
499
500 Deletes the contents of the resultset from its result source.
501
502 =cut
503
504 sub delete {
505   my ($self) = @_;
506   $self->result_source->storage->delete($self->result_source->from, $self->{cond});
507   return 1;
508 }
509
510 =head2 delete_all
511
512 Fetches all objects and deletes them one at a time.  Note that C<delete_all>
513 will run cascade triggers while L</delete> will not.
514
515 =cut
516
517 sub delete_all {
518   my ($self) = @_;
519   $_->delete for $self->all;
520   return 1;
521 }
522
523 =head2 pager
524
525 Returns a L<Data::Page> object for the current resultset. Only makes
526 sense for queries with a C<page> attribute.
527
528 =cut
529
530 sub pager {
531   my ($self) = @_;
532   my $attrs = $self->{attrs};
533   $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
534   $attrs->{rows} ||= 10;
535   $self->count;
536   return $self->{pager} ||= Data::Page->new(
537     $self->{count}, $attrs->{rows}, $self->{page});
538 }
539
540 =head2 page($page_num)
541
542 Returns a new resultset for the specified page.
543
544 =cut
545
546 sub page {
547   my ($self, $page) = @_;
548   my $attrs = { %{$self->{attrs}} };
549   $attrs->{page} = $page;
550   return (ref $self)->new($self->result_source, $attrs);
551 }
552
553 =head2 new_result(\%vals)
554
555 Creates a result in the resultset's result class.
556
557 =cut
558
559 sub new_result {
560   my ($self, $values) = @_;
561   $self->throw_exception( "new_result needs a hash" )
562     unless (ref $values eq 'HASH');
563   $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
564     if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
565   my %new = %$values;
566   my $alias = $self->{attrs}{alias};
567   foreach my $key (keys %{$self->{cond}||{}}) {
568     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
569   }
570   my $obj = $self->result_source->result_class->new(\%new);
571   $obj->result_source($self->result_source) if $obj->can('result_source');
572   $obj;
573 }
574
575 =head2 create(\%vals)
576
577 Inserts a record into the resultset and returns the object.
578
579 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
580
581 =cut
582
583 sub create {
584   my ($self, $attrs) = @_;
585   $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
586   return $self->new_result($attrs)->insert;
587 }
588
589 =head2 find_or_create(\%vals, \%attrs?)
590
591   $class->find_or_create({ key => $val, ... });
592
593 Searches for a record matching the search condition; if it doesn't find one,    
594 creates one and returns that instead.                                       
595
596   my $cd = $schema->resultset('CD')->find_or_create({
597     cdid   => 5,
598     artist => 'Massive Attack',
599     title  => 'Mezzanine',
600     year   => 2005,
601   });
602
603 Also takes an optional C<key> attribute, to search by a specific key or unique
604 constraint. For example:
605
606   my $cd = $schema->resultset('CD')->find_or_create(
607     {
608       artist => 'Massive Attack',
609       title  => 'Mezzanine',
610     },
611     { key => 'artist_title' }
612   );
613
614 See also L</find> and L</update_or_create>.
615
616 =cut
617
618 sub find_or_create {
619   my $self     = shift;
620   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
621   my $hash     = ref $_[0] eq "HASH" ? shift : {@_};
622   my $exists   = $self->find($hash, $attrs);
623   return defined($exists) ? $exists : $self->create($hash);
624 }
625
626 =head2 update_or_create
627
628   $class->update_or_create({ key => $val, ... });
629
630 First, search for an existing row matching one of the unique constraints
631 (including the primary key) on the source of this resultset.  If a row is
632 found, update it with the other given column values.  Otherwise, create a new
633 row.
634
635 Takes an optional C<key> attribute to search on a specific unique constraint.
636 For example:
637
638   # In your application
639   my $cd = $schema->resultset('CD')->update_or_create(
640     {
641       artist => 'Massive Attack',
642       title  => 'Mezzanine',
643       year   => 1998,
644     },
645     { key => 'artist_title' }
646   );
647
648 If no C<key> is specified, it searches on all unique constraints defined on the
649 source, including the primary key.
650
651 If the C<key> is specified as C<primary>, search only on the primary key.
652
653 See also L</find> and L</find_or_create>.
654
655 =cut
656
657 sub update_or_create {
658   my $self = shift;
659
660   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
661   my $hash  = ref $_[0] eq "HASH" ? shift : {@_};
662
663   my %unique_constraints = $self->result_source->unique_constraints;
664   my @constraint_names   = (exists $attrs->{key}
665                             ? ($attrs->{key})
666                             : keys %unique_constraints);
667
668   my @unique_hashes;
669   foreach my $name (@constraint_names) {
670     my @unique_cols = @{ $unique_constraints{$name} };
671     my %unique_hash =
672       map  { $_ => $hash->{$_} }
673       grep { exists $hash->{$_} }
674       @unique_cols;
675
676     push @unique_hashes, \%unique_hash
677       if (scalar keys %unique_hash == scalar @unique_cols);
678   }
679
680   my $row;
681   if (@unique_hashes) {
682     $row = $self->search(\@unique_hashes, { rows => 1 })->first;
683     if ($row) {
684       $row->set_columns($hash);
685       $row->update;
686     }
687   }
688
689   unless ($row) {
690     $row = $self->create($hash);
691   }
692
693   return $row;
694 }
695
696 =head2 throw_exception
697
698 See Schema's throw_exception
699
700 =cut
701
702 sub throw_exception {
703   my $self=shift;
704   $self->result_source->schema->throw_exception(@_);
705 }
706
707 =head1 ATTRIBUTES
708
709 The resultset takes various attributes that modify its behavior. Here's an
710 overview of them:
711
712 =head2 order_by
713
714 Which column(s) to order the results by. This is currently passed through
715 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
716
717 =head2 cols (arrayref)
718
719 Shortcut to request a particular set of columns to be retrieved.  Adds
720 C<me.> onto the start of any column without a C<.> in it and sets C<select>
721 from that, then auto-populates C<as> from C<select> as normal.
722
723 =head2 select (arrayref)
724
725 Indicates which columns should be selected from the storage. You can use
726 column names, or in the case of RDBMS back ends, function or stored procedure
727 names:
728
729   $rs = $schema->resultset('Foo')->search(
730     {},
731     {
732       select => [
733         'column_name',
734         { count => 'column_to_count' },
735         { sum => 'column_to_sum' }
736       ]
737     }
738   );
739
740 When you use function/stored procedure names and do not supply an C<as>
741 attribute, the column names returned are storage-dependent. E.g. MySQL would
742 return a column named C<count(column_to_count)> in the above example.
743
744 =head2 as (arrayref)
745
746 Indicates column names for object inflation. This is used in conjunction with
747 C<select>, usually when C<select> contains one or more function or stored
748 procedure names:
749
750   $rs = $schema->resultset('Foo')->search(
751     {},
752     {
753       select => [
754         'column1',
755         { count => 'column2' }
756       ],
757       as => [qw/ column1 column2_count /]
758     }
759   );
760
761   my $foo = $rs->first(); # get the first Foo
762
763 If the object against which the search is performed already has an accessor
764 matching a column name specified in C<as>, the value can be retrieved using
765 the accessor as normal:
766
767   my $column1 = $foo->column1();
768
769 If on the other hand an accessor does not exist in the object, you need to
770 use C<get_column> instead:
771
772   my $column2_count = $foo->get_column('column2_count');
773
774 You can create your own accessors if required - see
775 L<DBIx::Class::Manual::Cookbook> for details.
776
777 =head2 join
778
779 Contains a list of relationships that should be joined for this query.  For
780 example:
781
782   # Get CDs by Nine Inch Nails
783   my $rs = $schema->resultset('CD')->search(
784     { 'artist.name' => 'Nine Inch Nails' },
785     { join => 'artist' }
786   );
787
788 Can also contain a hash reference to refer to the other relation's relations.
789 For example:
790
791   package MyApp::Schema::Track;
792   use base qw/DBIx::Class/;
793   __PACKAGE__->table('track');
794   __PACKAGE__->add_columns(qw/trackid cd position title/);
795   __PACKAGE__->set_primary_key('trackid');
796   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
797   1;
798
799   # In your application
800   my $rs = $schema->resultset('Artist')->search(
801     { 'track.title' => 'Teardrop' },
802     {
803       join     => { cd => 'track' },
804       order_by => 'artist.name',
805     }
806   );
807
808 If you want to fetch columns from related tables as well, see C<prefetch>
809 below.
810
811 =head2 prefetch arrayref/hashref
812
813 Contains one or more relationships that should be fetched along with the main 
814 query (when they are accessed afterwards they will have already been
815 "prefetched").  This is useful for when you know you will need the related
816 objects, because it saves at least one query:
817
818   my $rs = $schema->resultset('Tag')->search(
819     {},
820     {
821       prefetch => {
822         cd => 'artist'
823       }
824     }
825   );
826
827 The initial search results in SQL like the following:
828
829   SELECT tag.*, cd.*, artist.* FROM tag
830   JOIN cd ON tag.cd = cd.cdid
831   JOIN artist ON cd.artist = artist.artistid
832
833 L<DBIx::Class> has no need to go back to the database when we access the
834 C<cd> or C<artist> relationships, which saves us two SQL statements in this
835 case.
836
837 Any prefetched relationship will be joined automatically, so there is no need
838 for a C<join> attribute in the above search.
839
840 C<prefetch> can be used with the following relationship types: C<belongs_to>,
841 C<has_one>.
842
843 =head2 from (arrayref)
844
845 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
846 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
847 clauses.
848
849 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
850 C<join> will usually do what you need and it is strongly recommended that you
851 avoid using C<from> unless you cannot achieve the desired result using C<join>.
852
853 In simple terms, C<from> works as follows:
854
855     [
856         { <alias> => <table>, -join-type => 'inner|left|right' }
857         [] # nested JOIN (optional)
858         { <table.column> = <foreign_table.foreign_key> }
859     ]
860
861     JOIN
862         <alias> <table>
863         [JOIN ...]
864     ON <table.column> = <foreign_table.foreign_key>
865
866 An easy way to follow the examples below is to remember the following:
867
868     Anything inside "[]" is a JOIN
869     Anything inside "{}" is a condition for the enclosing JOIN
870
871 The following examples utilize a "person" table in a family tree application.
872 In order to express parent->child relationships, this table is self-joined:
873
874     # Person->belongs_to('father' => 'Person');
875     # Person->belongs_to('mother' => 'Person');
876
877 C<from> can be used to nest joins. Here we return all children with a father,
878 then search against all mothers of those children:
879
880   $rs = $schema->resultset('Person')->search(
881       {},
882       {
883           alias => 'mother', # alias columns in accordance with "from"
884           from => [
885               { mother => 'person' },
886               [
887                   [
888                       { child => 'person' },
889                       [
890                           { father => 'person' },
891                           { 'father.person_id' => 'child.father_id' }
892                       ]
893                   ],
894                   { 'mother.person_id' => 'child.mother_id' }
895               ],                
896           ]
897       },
898   );
899
900   # Equivalent SQL:
901   # SELECT mother.* FROM person mother
902   # JOIN (
903   #   person child
904   #   JOIN person father
905   #   ON ( father.person_id = child.father_id )
906   # )
907   # ON ( mother.person_id = child.mother_id )
908
909 The type of any join can be controlled manually. To search against only people
910 with a father in the person table, we could explicitly use C<INNER JOIN>:
911
912     $rs = $schema->resultset('Person')->search(
913         {},
914         {
915             alias => 'child', # alias columns in accordance with "from"
916             from => [
917                 { child => 'person' },
918                 [
919                     { father => 'person', -join-type => 'inner' },
920                     { 'father.id' => 'child.father_id' }
921                 ],
922             ]
923         },
924     );
925
926     # Equivalent SQL:
927     # SELECT child.* FROM person child
928     # INNER JOIN person father ON child.father_id = father.id
929
930 =head2 page
931
932 For a paged resultset, specifies which page to retrieve.  Leave unset
933 for an unpaged resultset.
934
935 =head2 rows
936
937 For a paged resultset, how many rows per page:
938
939   rows => 10
940
941 Can also be used to simulate an SQL C<LIMIT>.
942
943 =head2 group_by (arrayref)
944
945 A arrayref of columns to group by. Can include columns of joined tables.
946
947   group_by => [qw/ column1 column2 ... /]
948
949 =head2 distinct
950
951 Set to 1 to group by all columns.
952
953 For more examples of using these attributes, see
954 L<DBIx::Class::Manual::Cookbook>.
955
956 =cut
957
958 1;