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