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