failing test case and more resultset refactorage
[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 use Scalar::Util qw/weaken/;
12
13 use DBIx::Class::ResultSetColumn;
14 use base qw/DBIx::Class/;
15 __PACKAGE__->load_components(qw/AccessorGroup/);
16 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
17
18 =head1 NAME
19
20 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
21
22 =head1 SYNOPSIS
23
24   my $rs   = $schema->resultset('User')->search(registered => 1);
25   my @rows = $schema->resultset('CD')->search(year => 2005);
26
27 =head1 DESCRIPTION
28
29 The resultset is also known as an iterator. It is responsible for handling
30 queries that may return an arbitrary number of rows, e.g. via L</search>
31 or a C<has_many> relationship.
32
33 In the examples below, the following table classes are used:
34
35   package MyApp::Schema::Artist;
36   use base qw/DBIx::Class/;
37   __PACKAGE__->load_components(qw/Core/);
38   __PACKAGE__->table('artist');
39   __PACKAGE__->add_columns(qw/artistid name/);
40   __PACKAGE__->set_primary_key('artistid');
41   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
42   1;
43
44   package MyApp::Schema::CD;
45   use base qw/DBIx::Class/;
46   __PACKAGE__->load_components(qw/Core/);
47   __PACKAGE__->table('cd');
48   __PACKAGE__->add_columns(qw/cdid artist title year/);
49   __PACKAGE__->set_primary_key('cdid');
50   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
51   1;
52
53 =head1 METHODS
54
55 =head2 new
56
57 =over 4
58
59 =item Arguments: $source, \%$attrs
60
61 =item Return Value: $rs
62
63 =back
64
65 The resultset constructor. Takes a source object (usually a
66 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
67 L</ATTRIBUTES> below).  Does not perform any queries -- these are
68 executed as needed by the other methods.
69
70 Generally you won't need to construct a resultset manually.  You'll
71 automatically get one from e.g. a L</search> called in scalar context:
72
73   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
74
75 IMPORTANT: If called on an object, proxies to new_result instead so
76
77   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
78
79 will return a CD object, not a ResultSet.
80
81 =cut
82
83 sub new {
84   my $class = shift;
85   return $class->new_result(@_) if ref $class;
86   
87   my ($source, $attrs) = @_;
88   weaken $source;
89
90   if ($attrs->{page}) {
91     $attrs->{rows} ||= 10;
92     $attrs->{offset} ||= 0;
93     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
94   }
95
96   $attrs->{alias} ||= 'me';
97
98   bless {
99     result_source => $source,
100     result_class => $attrs->{result_class} || $source->result_class,
101     cond => $attrs->{where},
102 #    from => $attrs->{from},
103 #    collapse => $collapse,
104     count => undef,
105     page => delete $attrs->{page},
106     pager => undef,
107     attrs => $attrs
108   }, $class;
109 }
110
111 =head2 search
112
113 =over 4
114
115 =item Arguments: $cond, \%attrs?
116
117 =item Return Value: $resultset (scalar context), @row_objs (list context)
118
119 =back
120
121   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
122   my $new_rs = $cd_rs->search({ year => 2005 });
123
124   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
125                  # year = 2005 OR year = 2004
126
127 If you need to pass in additional attributes but no additional condition,
128 call it as C<search(undef, \%attrs)>.
129
130   # "SELECT name, artistid FROM $artist_table"
131   my @all_artists = $schema->resultset('Artist')->search(undef, {
132     columns => [qw/name artistid/],
133   });
134
135 =cut
136
137 sub search {
138   my $self = shift;
139     
140   my $attrs = { %{$self->{attrs}} };
141   my $having = delete $attrs->{having};
142   $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH';
143
144   my $where = (@_
145                 ? ((@_ == 1 || ref $_[0] eq "HASH")
146                     ? shift
147                     : ((@_ % 2)
148                         ? $self->throw_exception(
149                             "Odd number of arguments to search")
150                         : {@_}))
151                 : undef());
152   if (defined $where) {
153     $attrs->{where} = (defined $attrs->{where}
154               ? { '-and' =>
155                   [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
156                       $where, $attrs->{where} ] }
157               : $where);
158   }
159
160   if (defined $having) {
161     $attrs->{having} = (defined $attrs->{having}
162               ? { '-and' =>
163                   [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
164                       $having, $attrs->{having} ] }
165               : $having);
166   }
167
168   my $rs = (ref $self)->new($self->result_source, $attrs);
169   $rs->{_parent_rs} = $self->{_parent_rs} if ($self->{_parent_rs}); #XXX - hack to pass through parent of related resultsets
170
171   unless (@_) { # no search, effectively just a clone
172     my $rows = $self->get_cache;
173     if( @{$rows} ) {
174       $rs->set_cache($rows);
175     }
176   }
177   
178   return (wantarray ? $rs->all : $rs);
179 }
180
181 =head2 search_literal
182
183 =over 4
184
185 =item Arguments: $sql_fragment, @bind_values
186
187 =item Return Value: $resultset (scalar context), @row_objs (list context)
188
189 =back
190
191   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
192   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
193
194 Pass a literal chunk of SQL to be added to the conditional part of the
195 resultset query.
196
197 =cut
198
199 sub search_literal {
200   my ($self, $cond, @vals) = @_;
201   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
202   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
203   return $self->search(\$cond, $attrs);
204 }
205
206 =head2 find
207
208 =over 4
209
210 =item Arguments: @values | \%cols, \%attrs?
211
212 =item Return Value: $row_object
213
214 =back
215
216 Finds a row based on its primary key or unique constraint. For example, to find
217 a row by its primary key:
218
219   my $cd = $schema->resultset('CD')->find(5);
220
221 You can also find a row by a specific unique constraint using the C<key>
222 attribute. For example:
223
224   my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', { key => 'artist_title' });
225
226 Additionally, you can specify the columns explicitly by name:
227
228   my $cd = $schema->resultset('CD')->find(
229     {
230       artist => 'Massive Attack',
231       title  => 'Mezzanine',
232     },
233     { key => 'artist_title' }
234   );
235
236 If no C<key> is specified and you explicitly name columns, it searches on all
237 unique constraints defined on the source, including the primary key.
238
239 If the C<key> is specified as C<primary>, it searches only on the primary key.
240
241 See also L</find_or_create> and L</update_or_create>. For information on how to
242 declare unique constraints, see
243 L<DBIx::Class::ResultSource/add_unique_constraint>.
244
245 =cut
246
247 sub find {
248   my $self = shift;
249   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
250
251   # Parse out a hash from input
252   my @cols = exists $attrs->{key}
253     ? $self->result_source->unique_constraint_columns($attrs->{key})
254     : $self->result_source->primary_columns;
255
256   my $hash;
257   if (ref $_[0] eq 'HASH') {
258     $hash = { %{$_[0]} };
259   }
260   elsif (@_ == @cols) {
261     $hash = {};
262     @{$hash}{@cols} = @_;
263   }
264   else {
265     $self->throw_exception(
266       "Arguments to find must be a hashref or match the number of columns in the "
267         . exists $attrs->{key} ? "$attrs->{key} unique constraint" : "primary key"
268     );
269   }
270
271   # Check the hash we just parsed against our source's unique constraints
272   my @constraint_names = exists $attrs->{key}
273     ? ($attrs->{key})
274     : $self->result_source->unique_constraint_names;
275   $self->throw_exception(
276     "Can't find unless a primary key or unique constraint is defined"
277   ) unless @constraint_names;
278
279   my @unique_queries;
280   foreach my $name (@constraint_names) {
281     my @unique_cols = $self->result_source->unique_constraint_columns($name);
282     my $unique_query = $self->_build_unique_query($hash, \@unique_cols);
283
284     # Add the ResultSet's alias
285     foreach my $key (grep { ! m/\./ } keys %$unique_query) {
286       my $alias = $self->{attrs}->{alias};
287       $unique_query->{"$alias.$key"} = delete $unique_query->{$key};
288     }
289
290     push @unique_queries, $unique_query if %$unique_query;
291   }
292
293   # Handle cases where the ResultSet already defines the query
294   my $query = @unique_queries ? \@unique_queries : undef;
295
296   # Run the query
297
298   if (keys %$attrs) {
299     my $rs = $self->search($query, $attrs);
300     $rs->_resolve;
301     return keys %{$rs->{_attrs}->{collapse}} ? $rs->next : $rs->single;
302   }
303   else {
304     $self->_resolve;  
305     return (keys %{$self->{_attrs}->{collapse}})
306       ? $self->search($query)->next
307       : $self->single($query);
308   }
309 }
310
311 # _build_unique_query
312 #
313 # Constrain the specified query hash based on the specified column names.
314
315 sub _build_unique_query {
316   my ($self, $query, $unique_cols) = @_;
317
318   my %unique_query =
319     map  { $_ => $query->{$_} }
320     grep { exists $query->{$_} }
321     @$unique_cols;
322
323   return \%unique_query;
324 }
325
326 =head2 search_related
327
328 =over 4
329
330 =item Arguments: $cond, \%attrs?
331
332 =item Return Value: $new_resultset
333
334 =back
335
336   $new_rs = $cd_rs->search_related('artist', {
337     name => 'Emo-R-Us',
338   });
339
340 Searches the specified relationship, optionally specifying a condition and
341 attributes for matching records. See L</ATTRIBUTES> for more information.
342
343 =cut
344
345 sub search_related {
346   return shift->related_resultset(shift)->search(@_);
347 }
348
349 =head2 cursor
350
351 =over 4
352
353 =item Arguments: none
354
355 =item Return Value: $cursor
356
357 =back
358
359 Returns a storage-driven cursor to the given resultset. See
360 L<DBIx::Class::Cursor> for more information.
361
362 =cut
363
364 sub cursor {
365   my ($self) = @_;
366
367   $self->_resolve;
368   my $attrs = { %{$self->{_attrs}} };
369   return $self->{cursor}
370     ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
371           $attrs->{where},$attrs);
372 }
373
374 =head2 single
375
376 =over 4
377
378 =item Arguments: $cond?
379
380 =item Return Value: $row_object?
381
382 =back
383
384   my $cd = $schema->resultset('CD')->single({ year => 2001 });
385
386 Inflates the first result without creating a cursor if the resultset has
387 any records in it; if not returns nothing. Used by L</find> as an optimisation.
388
389 =cut
390
391 sub single {
392   my ($self, $where) = @_;
393   $self->_resolve;
394   my $attrs = { %{$self->{_attrs}} };
395   if ($where) {
396     if (defined $attrs->{where}) {
397       $attrs->{where} = {
398         '-and' =>
399             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
400                $where, delete $attrs->{where} ]
401       };
402     } else {
403       $attrs->{where} = $where;
404     }
405   }
406
407   my @data = $self->result_source->storage->select_single(
408           $attrs->{from}, $attrs->{select},
409           $attrs->{where},$attrs);
410   return (@data ? $self->_construct_object(@data) : ());
411 }
412
413 =head2 get_column
414
415 =over 4
416
417 =item Arguments: $cond?
418
419 =item Return Value: $resultsetcolumn
420
421 =back
422
423   my $max_length = $rs->get_column('length')->max;
424
425 Returns a ResultSetColumn instance for $column based on $self
426
427 =cut
428
429 sub get_column {
430   my ($self, $column) = @_;
431
432   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
433   return $new;
434 }
435
436 =head2 search_like
437
438 =over 4
439
440 =item Arguments: $cond, \%attrs?
441
442 =item Return Value: $resultset (scalar context), @row_objs (list context)
443
444 =back
445
446   # WHERE title LIKE '%blue%'
447   $cd_rs = $rs->search_like({ title => '%blue%'});
448
449 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
450 that this is simply a convenience method. You most likely want to use
451 L</search> with specific operators.
452
453 For more information, see L<DBIx::Class::Manual::Cookbook>.
454
455 =cut
456
457 sub search_like {
458   my $class = shift;
459   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
460   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
461   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
462   return $class->search($query, { %$attrs });
463 }
464
465 =head2 slice
466
467 =over 4
468
469 =item Arguments: $first, $last
470
471 =item Return Value: $resultset (scalar context), @row_objs (list context)
472
473 =back
474
475 Returns a resultset or object list representing a subset of elements from the
476 resultset slice is called on. Indexes are from 0, i.e., to get the first
477 three records, call:
478
479   my ($one, $two, $three) = $rs->slice(0, 2);
480
481 =cut
482
483 sub slice {
484   my ($self, $min, $max) = @_;
485   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
486   $attrs->{offset} = $self->{attrs}{offset} || 0;
487   $attrs->{offset} += $min;
488   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
489   return $self->search(undef(), $attrs);
490   #my $slice = (ref $self)->new($self->result_source, $attrs);
491   #return (wantarray ? $slice->all : $slice);
492 }
493
494 =head2 next
495
496 =over 4
497
498 =item Arguments: none
499
500 =item Return Value: $result?
501
502 =back
503
504 Returns the next element in the resultset (C<undef> is there is none).
505
506 Can be used to efficiently iterate over records in the resultset:
507
508   my $rs = $schema->resultset('CD')->search;
509   while (my $cd = $rs->next) {
510     print $cd->title;
511   }
512
513 Note that you need to store the resultset object, and call C<next> on it. 
514 Calling C<< resultset('Table')->next >> repeatedly will always return the
515 first record from the resultset.
516
517 =cut
518
519 sub next {
520   my ($self) = @_;
521   if (@{$self->{all_cache} || []}) {
522     $self->{all_cache_position} ||= 0;
523     return $self->{all_cache}->[$self->{all_cache_position}++];
524   }
525   if ($self->{attrs}{cache}) {
526     $self->{all_cache_position} = 1;
527     return ($self->all)[0];
528   }
529   my @row = (exists $self->{stashed_row} ?
530                @{delete $self->{stashed_row}} :
531                $self->cursor->next
532   );
533   return unless (@row);
534   return $self->_construct_object(@row);
535 }
536
537 # XXX - this is essentially just the old new(). rewrite / tidy up?
538 sub _resolve {
539   my $self = shift;
540
541   return if(exists $self->{_attrs}); #return if _resolve has already been called
542
543   my $attrs = $self->{attrs};  
544   my $source = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->{result_source};
545
546   # XXX - this is a hack to prevent dclone dieing because of the code ref, get's put back in $attrs afterwards
547   my $record_filter = delete $attrs->{record_filter} if (defined $attrs->{record_filter});
548   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
549   $attrs->{record_filter} = $record_filter if ($record_filter);
550   $self->{attrs}->{record_filter} = $record_filter if ($record_filter);
551
552   my $alias = $attrs->{alias};
553  
554   $attrs->{columns} ||= delete $attrs->{cols} if $attrs->{cols};
555   delete $attrs->{as} if $attrs->{columns};
556   $attrs->{columns} ||= [ $self->{result_source}->columns ] unless $attrs->{select};
557   my $select_alias = ($self->{_parent_rs}) ? $self->{attrs}->{_live_join} : $alias;
558   $attrs->{select} = [
559                       map { m/\./ ? $_ : "${select_alias}.$_" } @{delete $attrs->{columns}}
560                       ] if $attrs->{columns};
561   $attrs->{as} ||= [
562                     map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}}
563                     ];
564   if (my $include = delete $attrs->{include_columns}) {
565       push(@{$attrs->{select}}, @$include);
566       push(@{$attrs->{as}}, map { m/([^.]+)$/; $1; } @$include);
567   }
568
569   $attrs->{from} ||= [ { $alias => $source->from } ];
570   $attrs->{seen_join} ||= {};
571   my %seen;
572   if (my $join = delete $attrs->{join}) {
573       foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
574           if (ref $j eq 'HASH') {
575               $seen{$_} = 1 foreach keys %$j;
576           } else {
577               $seen{$j} = 1;
578           }
579       }
580
581       push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}, $attrs->{seen_join}));
582   }
583   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
584   $attrs->{order_by} = [ $attrs->{order_by} ] if
585       $attrs->{order_by} and !ref($attrs->{order_by});
586   $attrs->{order_by} ||= [];
587   
588   my $collapse = $attrs->{collapse} || {};
589   if (my $prefetch = delete $attrs->{prefetch}) {
590       my @pre_order;
591       foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
592           if ( ref $p eq 'HASH' ) {
593               foreach my $key (keys %$p) {
594                   push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
595                       unless $seen{$key};
596               }
597           } else {
598               push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
599                   unless $seen{$p};
600           }
601           my @prefetch = $source->resolve_prefetch(
602                                                    $p, $attrs->{alias}, {}, \@pre_order, $collapse);
603           push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
604           push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
605       }
606       push(@{$attrs->{order_by}}, @pre_order);
607   }
608   $attrs->{collapse} = $collapse;
609   $self->{_attrs} = $attrs;
610 }
611
612 sub _construct_object {
613   my ($self, @row) = @_;
614   my @as = @{ $self->{_attrs}{as} };
615
616   my $info = $self->_collapse_result(\@as, \@row);
617   my $new = $self->result_class->inflate_result($self->result_source, @$info, $self->{_parent_rs});
618   $new = $self->{_attrs}{record_filter}->($new)
619     if exists $self->{_attrs}{record_filter};
620   return $new;
621 }
622
623 sub _collapse_result {
624   my ($self, $as, $row, $prefix) = @_;
625
626   my $live_join = $self->{attrs}->{_live_join} ||="";
627   my %const;
628
629   my @copy = @$row;
630   foreach my $this_as (@$as) {
631     my $val = shift @copy;
632     if (defined $prefix) {
633       if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
634         my $remain = $1;
635         $remain =~ /^(?:(.*)\.)?([^.]+)$/;
636         $const{$1||''}{$2} = $val;
637       }
638     } else {
639       $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
640       $const{$1||''}{$2} = $val;
641     }
642   }
643
644   my $info = [ {}, {} ];
645   foreach my $key (keys %const) {
646     if (length $key && $key ne $live_join) {
647       my $target = $info;
648       my @parts = split(/\./, $key);
649       foreach my $p (@parts) {
650         $target = $target->[1]->{$p} ||= [];
651       }
652       $target->[0] = $const{$key};
653     } else {
654       $info->[0] = $const{$key};
655     }
656   }
657
658   my @collapse;
659   if (defined $prefix) {
660     @collapse = map {
661         m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
662     } keys %{$self->{_attrs}->{collapse}}
663   } else {
664     @collapse = keys %{$self->{_attrs}->{collapse}};
665   };
666
667   if (@collapse) {
668     my ($c) = sort { length $a <=> length $b } @collapse;
669     my $target = $info;
670     foreach my $p (split(/\./, $c)) {
671       $target = $target->[1]->{$p} ||= [];
672     }
673     my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
674     my @co_key = @{$self->{_attrs}->{collapse}{$c_prefix}};
675     my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
676     my $tree = $self->_collapse_result($as, $row, $c_prefix);
677     my (@final, @raw);
678     while ( !(grep {
679                 !defined($tree->[0]->{$_}) ||
680                 $co_check{$_} ne $tree->[0]->{$_}
681               } @co_key) ) {
682       push(@final, $tree);
683       last unless (@raw = $self->cursor->next);
684       $row = $self->{stashed_row} = \@raw;
685       $tree = $self->_collapse_result($as, $row, $c_prefix);
686     }
687     @$target = @final;
688   }
689   return $info;
690 }
691
692 =head2 result_source
693
694 =over 4
695
696 =item Arguments: $result_source?
697
698 =item Return Value: $result_source
699
700 =back
701
702 An accessor for the primary ResultSource object from which this ResultSet
703 is derived.
704
705 =cut
706
707
708 =head2 count
709
710 =over 4
711
712 =item Arguments: $cond, \%attrs??
713
714 =item Return Value: $count
715
716 =back
717
718 Performs an SQL C<COUNT> with the same query as the resultset was built
719 with to find the number of elements. If passed arguments, does a search
720 on the resultset and counts the results of that.
721
722 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
723 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
724 not support C<DISTINCT> with multiple columns. If you are using such a
725 database, you should only use columns from the main table in your C<group_by>
726 clause.
727
728 =cut
729
730 sub count {
731   my $self = shift;
732   return $self->search(@_)->count if @_ and defined $_[0];
733   return scalar @{ $self->get_cache } if @{ $self->get_cache };
734
735   my $count = $self->_count;
736   return 0 unless $count;
737
738   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
739   $count = $self->{attrs}{rows} if
740     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
741   return $count;
742 }
743
744 sub _count { # Separated out so pager can get the full count
745   my $self = shift;
746   my $select = { count => '*' };
747   
748   $self->_resolve;
749   my $attrs = { %{ $self->{_attrs} } };
750   if ($attrs->{distinct} && (my $group_by = $attrs->{group_by} || $attrs->{select})) {
751     delete $attrs->{having};
752     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
753     # todo: try CONCAT for multi-column pk
754     my @pk = $self->result_source->primary_columns;
755     if (@pk == 1) {
756       foreach my $column (@distinct) {
757         if ($column =~ qr/^(?:\Q$attrs->{alias}.\E)?$pk[0]$/) {
758           @distinct = ($column);
759           last;
760         }
761       }
762     }
763
764     $select = { count => { distinct => \@distinct } };
765     #use Data::Dumper; die Dumper $select;
766   }
767
768   $attrs->{select} = $select;
769   $attrs->{as} = [qw/count/];
770
771   # offset, order by and page are not needed to count. record_filter is cdbi
772   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
773   my ($count) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
774   return $count;
775 }
776
777 =head2 count_literal
778
779 =over 4
780
781 =item Arguments: $sql_fragment, @bind_values
782
783 =item Return Value: $count
784
785 =back
786
787 Counts the results in a literal query. Equivalent to calling L</search_literal>
788 with the passed arguments, then L</count>.
789
790 =cut
791
792 sub count_literal { shift->search_literal(@_)->count; }
793
794 =head2 all
795
796 =over 4
797
798 =item Arguments: none
799
800 =item Return Value: @objects
801
802 =back
803
804 Returns all elements in the resultset. Called implicitly if the resultset
805 is returned in list context.
806
807 =cut
808
809 sub all {
810   my ($self) = @_;
811   return @{ $self->get_cache } if @{ $self->get_cache };
812
813   my @obj;
814
815   # TODO: don't call resolve here
816   $self->_resolve;
817   if (keys %{$self->{_attrs}->{collapse}}) {
818 #  if ($self->{attrs}->{prefetch}) {
819       # Using $self->cursor->all is really just an optimisation.
820       # If we're collapsing has_many prefetches it probably makes
821       # very little difference, and this is cleaner than hacking
822       # _construct_object to survive the approach
823     my @row = $self->cursor->next;
824     while (@row) {
825       push(@obj, $self->_construct_object(@row));
826       @row = (exists $self->{stashed_row}
827                ? @{delete $self->{stashed_row}}
828                : $self->cursor->next);
829     }
830   } else {
831     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
832   }
833
834   $self->set_cache(\@obj) if $self->{attrs}{cache};
835   return @obj;
836 }
837
838 =head2 reset
839
840 =over 4
841
842 =item Arguments: none
843
844 =item Return Value: $self
845
846 =back
847
848 Resets the resultset's cursor, so you can iterate through the elements again.
849
850 =cut
851
852 sub reset {
853   my ($self) = @_;
854   delete $self->{_attrs} if (exists $self->{_attrs});
855
856   $self->{all_cache_position} = 0;
857   $self->cursor->reset;
858   return $self;
859 }
860
861 =head2 first
862
863 =over 4
864
865 =item Arguments: none
866
867 =item Return Value: $object?
868
869 =back
870
871 Resets the resultset and returns an object for the first result (if the
872 resultset returns anything).
873
874 =cut
875
876 sub first {
877   return $_[0]->reset->next;
878 }
879
880 # _cond_for_update_delete
881 #
882 # update/delete require the condition to be modified to handle
883 # the differing SQL syntax available.  This transforms the $self->{cond}
884 # appropriately, returning the new condition.
885
886 sub _cond_for_update_delete {
887   my ($self) = @_;
888   my $cond = {};
889
890   if (!ref($self->{cond})) {
891     # No-op. No condition, we're updating/deleting everything
892   }
893   elsif (ref $self->{cond} eq 'ARRAY') {
894     $cond = [
895       map {
896         my %hash;
897         foreach my $key (keys %{$_}) {
898           $key =~ /([^.]+)$/;
899           $hash{$1} = $_->{$key};
900         }
901         \%hash;
902       } @{$self->{cond}}
903     ];
904   }
905   elsif (ref $self->{cond} eq 'HASH') {
906     if ((keys %{$self->{cond}})[0] eq '-and') {
907       $cond->{-and} = [];
908
909       my @cond = @{$self->{cond}{-and}};
910       for (my $i = 0; $i < @cond - 1; $i++) {
911         my $entry = $cond[$i];
912
913         my %hash;
914         if (ref $entry eq 'HASH') {
915           foreach my $key (keys %{$entry}) {
916             $key =~ /([^.]+)$/;
917             $hash{$1} = $entry->{$key};
918           }
919         }
920         else {
921           $entry =~ /([^.]+)$/;
922           $hash{$entry} = $cond[++$i];
923         }
924
925         push @{$cond->{-and}}, \%hash;
926       }
927     }
928     else {
929       foreach my $key (keys %{$self->{cond}}) {
930         $key =~ /([^.]+)$/;
931         $cond->{$1} = $self->{cond}{$key};
932       }
933     }
934   }
935   else {
936     $self->throw_exception(
937       "Can't update/delete on resultset with condition unless hash or array"
938     );
939   }
940
941   return $cond;
942 }
943
944
945 =head2 update
946
947 =over 4
948
949 =item Arguments: \%values
950
951 =item Return Value: $storage_rv
952
953 =back
954
955 Sets the specified columns in the resultset to the supplied values in a
956 single query. Return value will be true if the update succeeded or false
957 if no records were updated; exact type of success value is storage-dependent.
958
959 =cut
960
961 sub update {
962   my ($self, $values) = @_;
963   $self->throw_exception("Values for update must be a hash")
964     unless ref $values eq 'HASH';
965
966   my $cond = $self->_cond_for_update_delete;
967
968   return $self->result_source->storage->update(
969     $self->result_source->from, $values, $cond
970   );
971 }
972
973 =head2 update_all
974
975 =over 4
976
977 =item Arguments: \%values
978
979 =item Return Value: 1
980
981 =back
982
983 Fetches all objects and updates them one at a time. Note that C<update_all>
984 will run DBIC cascade triggers, while L</update> will not.
985
986 =cut
987
988 sub update_all {
989   my ($self, $values) = @_;
990   $self->throw_exception("Values for update must be a hash")
991     unless ref $values eq 'HASH';
992   foreach my $obj ($self->all) {
993     $obj->set_columns($values)->update;
994   }
995   return 1;
996 }
997
998 =head2 delete
999
1000 =over 4
1001
1002 =item Arguments: none
1003
1004 =item Return Value: 1
1005
1006 =back
1007
1008 Deletes the contents of the resultset from its result source. Note that this
1009 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1010 to run.
1011
1012 =cut
1013
1014 sub delete {
1015   my ($self) = @_;
1016   my $del = {};
1017
1018   my $cond = $self->_cond_for_update_delete;
1019
1020   $self->result_source->storage->delete($self->result_source->from, $cond);
1021   return 1;
1022 }
1023
1024 =head2 delete_all
1025
1026 =over 4
1027
1028 =item Arguments: none
1029
1030 =item Return Value: 1
1031
1032 =back
1033
1034 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1035 will run DBIC cascade triggers, while L</delete> will not.
1036
1037 =cut
1038
1039 sub delete_all {
1040   my ($self) = @_;
1041   $_->delete for $self->all;
1042   return 1;
1043 }
1044
1045 =head2 pager
1046
1047 =over 4
1048
1049 =item Arguments: none
1050
1051 =item Return Value: $pager
1052
1053 =back
1054
1055 Return Value a L<Data::Page> object for the current resultset. Only makes
1056 sense for queries with a C<page> attribute.
1057
1058 =cut
1059
1060 sub pager {
1061   my ($self) = @_;
1062   my $attrs = $self->{attrs};
1063   $self->throw_exception("Can't create pager for non-paged rs")
1064     unless $self->{page};
1065   $attrs->{rows} ||= 10;
1066   return $self->{pager} ||= Data::Page->new(
1067     $self->_count, $attrs->{rows}, $self->{page});
1068 }
1069
1070 =head2 page
1071
1072 =over 4
1073
1074 =item Arguments: $page_number
1075
1076 =item Return Value: $rs
1077
1078 =back
1079
1080 Returns a resultset for the $page_number page of the resultset on which page
1081 is called, where each page contains a number of rows equal to the 'rows'
1082 attribute set on the resultset (10 by default).
1083
1084 =cut
1085
1086 sub page {
1087   my ($self, $page) = @_;
1088   my $attrs = { %{$self->{attrs}} };
1089   $attrs->{page} = $page;
1090   return (ref $self)->new($self->result_source, $attrs);
1091 }
1092
1093 =head2 new_result
1094
1095 =over 4
1096
1097 =item Arguments: \%vals
1098
1099 =item Return Value: $object
1100
1101 =back
1102
1103 Creates an object in the resultset's result class and returns it.
1104
1105 =cut
1106
1107 sub new_result {
1108   my ($self, $values) = @_;
1109   $self->throw_exception( "new_result needs a hash" )
1110     unless (ref $values eq 'HASH');
1111   $self->throw_exception(
1112     "Can't abstract implicit construct, condition not a hash"
1113   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1114   my %new = %$values;
1115   my $alias = $self->{attrs}{alias};
1116   foreach my $key (keys %{$self->{cond}||{}}) {
1117     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:\Q${alias}.\E)?([^.]+)$/);
1118   }
1119   my $obj = $self->result_class->new(\%new);
1120   $obj->result_source($self->result_source) if $obj->can('result_source');
1121   return $obj;
1122 }
1123
1124 =head2 find_or_new
1125
1126 =over 4
1127
1128 =item Arguments: \%vals, \%attrs?
1129
1130 =item Return Value: $object
1131
1132 =back
1133
1134 Find an existing record from this resultset. If none exists, instantiate a new
1135 result object and return it. The object will not be saved into your storage
1136 until you call L<DBIx::Class::Row/insert> on it.
1137
1138 If you want objects to be saved immediately, use L</find_or_create> instead.
1139
1140 =cut
1141
1142 sub find_or_new {
1143   my $self     = shift;
1144   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1145   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1146   my $exists   = $self->find($hash, $attrs);
1147   return defined $exists ? $exists : $self->new_result($hash);
1148 }
1149
1150 =head2 create
1151
1152 =over 4
1153
1154 =item Arguments: \%vals
1155
1156 =item Return Value: $object
1157
1158 =back
1159
1160 Inserts a record into the resultset and returns the object representing it.
1161
1162 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1163
1164 =cut
1165
1166 sub create {
1167   my ($self, $attrs) = @_;
1168   $self->throw_exception( "create needs a hashref" )
1169     unless ref $attrs eq 'HASH';
1170   return $self->new_result($attrs)->insert;
1171 }
1172
1173 =head2 find_or_create
1174
1175 =over 4
1176
1177 =item Arguments: \%vals, \%attrs?
1178
1179 =item Return Value: $object
1180
1181 =back
1182
1183   $class->find_or_create({ key => $val, ... });
1184
1185 Searches for a record matching the search condition; if it doesn't find one,
1186 creates one and returns that instead.
1187
1188   my $cd = $schema->resultset('CD')->find_or_create({
1189     cdid   => 5,
1190     artist => 'Massive Attack',
1191     title  => 'Mezzanine',
1192     year   => 2005,
1193   });
1194
1195 Also takes an optional C<key> attribute, to search by a specific key or unique
1196 constraint. For example:
1197
1198   my $cd = $schema->resultset('CD')->find_or_create(
1199     {
1200       artist => 'Massive Attack',
1201       title  => 'Mezzanine',
1202     },
1203     { key => 'artist_title' }
1204   );
1205
1206 See also L</find> and L</update_or_create>. For information on how to declare
1207 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1208
1209 =cut
1210
1211 sub find_or_create {
1212   my $self     = shift;
1213   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1214   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1215   my $exists   = $self->find($hash, $attrs);
1216   return defined $exists ? $exists : $self->create($hash);
1217 }
1218
1219 =head2 update_or_create
1220
1221 =over 4
1222
1223 =item Arguments: \%col_values, { key => $unique_constraint }?
1224
1225 =item Return Value: $object
1226
1227 =back
1228
1229   $class->update_or_create({ col => $val, ... });
1230
1231 First, searches for an existing row matching one of the unique constraints
1232 (including the primary key) on the source of this resultset. If a row is
1233 found, updates it with the other given column values. Otherwise, creates a new
1234 row.
1235
1236 Takes an optional C<key> attribute to search on a specific unique constraint.
1237 For example:
1238
1239   # In your application
1240   my $cd = $schema->resultset('CD')->update_or_create(
1241     {
1242       artist => 'Massive Attack',
1243       title  => 'Mezzanine',
1244       year   => 1998,
1245     },
1246     { key => 'artist_title' }
1247   );
1248
1249 If no C<key> is specified, it searches on all unique constraints defined on the
1250 source, including the primary key.
1251
1252 If the C<key> is specified as C<primary>, it searches only on the primary key.
1253
1254 See also L</find> and L</find_or_create>. For information on how to declare
1255 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1256
1257 =cut
1258
1259 sub update_or_create {
1260   my $self = shift;
1261   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1262   my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1263
1264   my $row = $self->find($hash, $attrs);
1265   if (defined $row) {
1266     $row->set_columns($hash);
1267     $row->update;
1268     return $row;
1269   }
1270
1271   return $self->create($hash);
1272 }
1273
1274 =head2 get_cache
1275
1276 =over 4
1277
1278 =item Arguments: none
1279
1280 =item Return Value: \@cache_objects?
1281
1282 =back
1283
1284 Gets the contents of the cache for the resultset, if the cache is set.
1285
1286 =cut
1287
1288 sub get_cache {
1289   shift->{all_cache} || [];
1290 }
1291
1292 =head2 set_cache
1293
1294 =over 4
1295
1296 =item Arguments: \@cache_objects
1297
1298 =item Return Value: \@cache_objects
1299
1300 =back
1301
1302 Sets the contents of the cache for the resultset. Expects an arrayref
1303 of objects of the same class as those produced by the resultset. Note that
1304 if the cache is set the resultset will return the cached objects rather
1305 than re-querying the database even if the cache attr is not set.
1306
1307 =cut
1308
1309 sub set_cache {
1310   my ( $self, $data ) = @_;
1311   $self->throw_exception("set_cache requires an arrayref")
1312     if ref $data ne 'ARRAY';
1313   my $result_class = $self->result_class;
1314   foreach( @$data ) {
1315     $self->throw_exception(
1316       "cannot cache object of type '$_', expected '$result_class'"
1317     ) if ref $_ ne $result_class;
1318   }
1319   $self->{all_cache} = $data;
1320 }
1321
1322 =head2 clear_cache
1323
1324 =over 4
1325
1326 =item Arguments: none
1327
1328 =item Return Value: []
1329
1330 =back
1331
1332 Clears the cache for the resultset.
1333
1334 =cut
1335
1336 sub clear_cache {
1337   shift->set_cache([]);
1338 }
1339
1340 =head2 related_resultset
1341
1342 =over 4
1343
1344 =item Arguments: $relationship_name
1345
1346 =item Return Value: $resultset
1347
1348 =back
1349
1350 Returns a related resultset for the supplied relationship name.
1351
1352   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1353
1354 =cut
1355
1356 sub related_resultset {
1357   my ( $self, $rel ) = @_;
1358
1359   $self->{related_resultsets} ||= {};
1360   return $self->{related_resultsets}{$rel} ||= do {
1361       #warn "fetching related resultset for rel '$rel' " . $self->result_source->{name};
1362       my $rel_obj = $self->result_source->relationship_info($rel);
1363       $self->throw_exception(
1364         "search_related: result source '" . $self->result_source->name .
1365         "' has no such relationship ${rel}")
1366         unless $rel_obj; #die Dumper $self->{attrs};
1367
1368       my $rs = $self->result_source->schema->resultset($rel_obj->{class}
1369            )->search( undef,
1370              { %{$self->{attrs}},
1371                select => undef,
1372                as => undef,
1373                join => $rel,
1374                _live_join => $rel }
1375            );
1376
1377       # keep reference of the original resultset
1378       $rs->{_parent_rs} = $self->result_source;
1379       return $rs;
1380   };
1381 }
1382
1383 =head2 throw_exception
1384
1385 See L<DBIx::Class::Schema/throw_exception> for details.
1386
1387 =cut
1388
1389 sub throw_exception {
1390   my $self=shift;
1391   $self->result_source->schema->throw_exception(@_);
1392 }
1393
1394 # XXX: FIXME: Attributes docs need clearing up
1395
1396 =head1 ATTRIBUTES
1397
1398 The resultset takes various attributes that modify its behavior. Here's an
1399 overview of them:
1400
1401 =head2 order_by
1402
1403 =over 4
1404
1405 =item Value: ($order_by | \@order_by)
1406
1407 =back
1408
1409 Which column(s) to order the results by. This is currently passed
1410 through directly to SQL, so you can give e.g. C<year DESC> for a
1411 descending order on the column `year'.
1412
1413 =head2 columns
1414
1415 =over 4
1416
1417 =item Value: \@columns
1418
1419 =back
1420
1421 Shortcut to request a particular set of columns to be retrieved.  Adds
1422 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1423 from that, then auto-populates C<as> from C<select> as normal. (You may also
1424 use the C<cols> attribute, as in earlier versions of DBIC.)
1425
1426 =head2 include_columns
1427
1428 =over 4
1429
1430 =item Value: \@columns
1431
1432 =back
1433
1434 Shortcut to include additional columns in the returned results - for example
1435
1436   $schema->resultset('CD')->search(undef, {
1437     include_columns => ['artist.name'],
1438     join => ['artist']
1439   });
1440
1441 would return all CDs and include a 'name' column to the information
1442 passed to object inflation
1443
1444 =head2 select
1445
1446 =over 4
1447
1448 =item Value: \@select_columns
1449
1450 =back
1451
1452 Indicates which columns should be selected from the storage. You can use
1453 column names, or in the case of RDBMS back ends, function or stored procedure
1454 names:
1455
1456   $rs = $schema->resultset('Employee')->search(undef, {
1457     select => [
1458       'name',
1459       { count => 'employeeid' },
1460       { sum => 'salary' }
1461     ]
1462   });
1463
1464 When you use function/stored procedure names and do not supply an C<as>
1465 attribute, the column names returned are storage-dependent. E.g. MySQL would
1466 return a column named C<count(employeeid)> in the above example.
1467
1468 =head2 as
1469
1470 =over 4
1471
1472 =item Value: \@inflation_names
1473
1474 =back
1475
1476 Indicates column names for object inflation. This is used in conjunction with
1477 C<select>, usually when C<select> contains one or more function or stored
1478 procedure names:
1479
1480   $rs = $schema->resultset('Employee')->search(undef, {
1481     select => [
1482       'name',
1483       { count => 'employeeid' }
1484     ],
1485     as => ['name', 'employee_count'],
1486   });
1487
1488   my $employee = $rs->first(); # get the first Employee
1489
1490 If the object against which the search is performed already has an accessor
1491 matching a column name specified in C<as>, the value can be retrieved using
1492 the accessor as normal:
1493
1494   my $name = $employee->name();
1495
1496 If on the other hand an accessor does not exist in the object, you need to
1497 use C<get_column> instead:
1498
1499   my $employee_count = $employee->get_column('employee_count');
1500
1501 You can create your own accessors if required - see
1502 L<DBIx::Class::Manual::Cookbook> for details.
1503
1504 =head2 join
1505
1506 =over 4
1507
1508 =item Value: ($rel_name | \@rel_names | \%rel_names)
1509
1510 =back
1511
1512 Contains a list of relationships that should be joined for this query.  For
1513 example:
1514
1515   # Get CDs by Nine Inch Nails
1516   my $rs = $schema->resultset('CD')->search(
1517     { 'artist.name' => 'Nine Inch Nails' },
1518     { join => 'artist' }
1519   );
1520
1521 Can also contain a hash reference to refer to the other relation's relations.
1522 For example:
1523
1524   package MyApp::Schema::Track;
1525   use base qw/DBIx::Class/;
1526   __PACKAGE__->table('track');
1527   __PACKAGE__->add_columns(qw/trackid cd position title/);
1528   __PACKAGE__->set_primary_key('trackid');
1529   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1530   1;
1531
1532   # In your application
1533   my $rs = $schema->resultset('Artist')->search(
1534     { 'track.title' => 'Teardrop' },
1535     {
1536       join     => { cd => 'track' },
1537       order_by => 'artist.name',
1538     }
1539   );
1540
1541 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1542 similarly for a third time). For e.g.
1543
1544   my $rs = $schema->resultset('Artist')->search({
1545     'cds.title'   => 'Down to Earth',
1546     'cds_2.title' => 'Popular',
1547   }, {
1548     join => [ qw/cds cds/ ],
1549   });
1550
1551 will return a set of all artists that have both a cd with title 'Down
1552 to Earth' and a cd with title 'Popular'.
1553
1554 If you want to fetch related objects from other tables as well, see C<prefetch>
1555 below.
1556
1557 =head2 prefetch
1558
1559 =over 4
1560
1561 =item Value: ($rel_name | \@rel_names | \%rel_names)
1562
1563 =back
1564
1565 Contains one or more relationships that should be fetched along with the main
1566 query (when they are accessed afterwards they will have already been
1567 "prefetched").  This is useful for when you know you will need the related
1568 objects, because it saves at least one query:
1569
1570   my $rs = $schema->resultset('Tag')->search(
1571     undef,
1572     {
1573       prefetch => {
1574         cd => 'artist'
1575       }
1576     }
1577   );
1578
1579 The initial search results in SQL like the following:
1580
1581   SELECT tag.*, cd.*, artist.* FROM tag
1582   JOIN cd ON tag.cd = cd.cdid
1583   JOIN artist ON cd.artist = artist.artistid
1584
1585 L<DBIx::Class> has no need to go back to the database when we access the
1586 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1587 case.
1588
1589 Simple prefetches will be joined automatically, so there is no need
1590 for a C<join> attribute in the above search. If you're prefetching to
1591 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1592 specify the join as well.
1593
1594 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1595 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1596 with an accessor type of 'single' or 'filter').
1597
1598 =head2 from
1599
1600 =over 4
1601
1602 =item Value: \@from_clause
1603
1604 =back
1605
1606 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1607 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1608 clauses.
1609
1610 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1611 C<join> will usually do what you need and it is strongly recommended that you
1612 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1613
1614 In simple terms, C<from> works as follows:
1615
1616     [
1617         { <alias> => <table>, -join_type => 'inner|left|right' }
1618         [] # nested JOIN (optional)
1619         { <table.column> => <foreign_table.foreign_key> }
1620     ]
1621
1622     JOIN
1623         <alias> <table>
1624         [JOIN ...]
1625     ON <table.column> = <foreign_table.foreign_key>
1626
1627 An easy way to follow the examples below is to remember the following:
1628
1629     Anything inside "[]" is a JOIN
1630     Anything inside "{}" is a condition for the enclosing JOIN
1631
1632 The following examples utilize a "person" table in a family tree application.
1633 In order to express parent->child relationships, this table is self-joined:
1634
1635     # Person->belongs_to('father' => 'Person');
1636     # Person->belongs_to('mother' => 'Person');
1637
1638 C<from> can be used to nest joins. Here we return all children with a father,
1639 then search against all mothers of those children:
1640
1641   $rs = $schema->resultset('Person')->search(
1642       undef,
1643       {
1644           alias => 'mother', # alias columns in accordance with "from"
1645           from => [
1646               { mother => 'person' },
1647               [
1648                   [
1649                       { child => 'person' },
1650                       [
1651                           { father => 'person' },
1652                           { 'father.person_id' => 'child.father_id' }
1653                       ]
1654                   ],
1655                   { 'mother.person_id' => 'child.mother_id' }
1656               ],
1657           ]
1658       },
1659   );
1660
1661   # Equivalent SQL:
1662   # SELECT mother.* FROM person mother
1663   # JOIN (
1664   #   person child
1665   #   JOIN person father
1666   #   ON ( father.person_id = child.father_id )
1667   # )
1668   # ON ( mother.person_id = child.mother_id )
1669
1670 The type of any join can be controlled manually. To search against only people
1671 with a father in the person table, we could explicitly use C<INNER JOIN>:
1672
1673     $rs = $schema->resultset('Person')->search(
1674         undef,
1675         {
1676             alias => 'child', # alias columns in accordance with "from"
1677             from => [
1678                 { child => 'person' },
1679                 [
1680                     { father => 'person', -join_type => 'inner' },
1681                     { 'father.id' => 'child.father_id' }
1682                 ],
1683             ]
1684         },
1685     );
1686
1687     # Equivalent SQL:
1688     # SELECT child.* FROM person child
1689     # INNER JOIN person father ON child.father_id = father.id
1690
1691 =head2 page
1692
1693 =over 4
1694
1695 =item Value: $page
1696
1697 =back
1698
1699 Makes the resultset paged and specifies the page to retrieve. Effectively
1700 identical to creating a non-pages resultset and then calling ->page($page)
1701 on it.
1702
1703 =head2 rows
1704
1705 =over 4
1706
1707 =item Value: $rows
1708
1709 =back
1710
1711 Specifes the maximum number of rows for direct retrieval or the number of
1712 rows per page if the page attribute or method is used.
1713
1714 =head2 group_by
1715
1716 =over 4
1717
1718 =item Value: \@columns
1719
1720 =back
1721
1722 A arrayref of columns to group by. Can include columns of joined tables.
1723
1724   group_by => [qw/ column1 column2 ... /]
1725
1726 =head2 having
1727
1728 =over 4
1729
1730 =item Value: $condition
1731
1732 =back
1733
1734 HAVING is a select statement attribute that is applied between GROUP BY and
1735 ORDER BY. It is applied to the after the grouping calculations have been
1736 done. 
1737
1738   having => { 'count(employee)' => { '>=', 100 } }
1739
1740 =head2 distinct
1741
1742 =over 4
1743
1744 =item Value: (0 | 1)
1745
1746 =back
1747
1748 Set to 1 to group by all columns.
1749
1750 =head2 cache
1751
1752 Set to 1 to cache search results. This prevents extra SQL queries if you
1753 revisit rows in your ResultSet:
1754
1755   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1756   
1757   while( my $artist = $resultset->next ) {
1758     ... do stuff ...
1759   }
1760
1761   $rs->first; # without cache, this would issue a query
1762
1763 By default, searches are not cached.
1764
1765 For more examples of using these attributes, see
1766 L<DBIx::Class::Manual::Cookbook>.
1767
1768 =cut
1769
1770 1;