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