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