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