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