Merge 'trunk' into 'DBIx-Class-current'
[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->update($hash);
1263     return $row;
1264   }
1265
1266   return $self->create($hash);
1267 }
1268
1269 =head2 get_cache
1270
1271 =over 4
1272
1273 =item Arguments: none
1274
1275 =item Return Value: \@cache_objects?
1276
1277 =back
1278
1279 Gets the contents of the cache for the resultset, if the cache is set.
1280
1281 =cut
1282
1283 sub get_cache {
1284   shift->{all_cache};
1285 }
1286
1287 =head2 set_cache
1288
1289 =over 4
1290
1291 =item Arguments: \@cache_objects
1292
1293 =item Return Value: \@cache_objects
1294
1295 =back
1296
1297 Sets the contents of the cache for the resultset. Expects an arrayref
1298 of objects of the same class as those produced by the resultset. Note that
1299 if the cache is set the resultset will return the cached objects rather
1300 than re-querying the database even if the cache attr is not set.
1301
1302 =cut
1303
1304 sub set_cache {
1305   my ( $self, $data ) = @_;
1306   $self->throw_exception("set_cache requires an arrayref")
1307     if defined($data) && (ref $data ne 'ARRAY');
1308   $self->{all_cache} = $data;
1309 }
1310
1311 =head2 clear_cache
1312
1313 =over 4
1314
1315 =item Arguments: none
1316
1317 =item Return Value: []
1318
1319 =back
1320
1321 Clears the cache for the resultset.
1322
1323 =cut
1324
1325 sub clear_cache {
1326   shift->set_cache(undef);
1327 }
1328
1329 =head2 related_resultset
1330
1331 =over 4
1332
1333 =item Arguments: $relationship_name
1334
1335 =item Return Value: $resultset
1336
1337 =back
1338
1339 Returns a related resultset for the supplied relationship name.
1340
1341   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1342
1343 =cut
1344
1345 sub related_resultset {
1346   my ( $self, $rel ) = @_;
1347   $self->{related_resultsets} ||= {};
1348   return $self->{related_resultsets}{$rel} ||= do {
1349       #warn "fetching related resultset for rel '$rel'";
1350       my $rel_obj = $self->result_source->relationship_info($rel);
1351       $self->throw_exception(
1352         "search_related: result source '" . $self->result_source->name .
1353         "' has no such relationship ${rel}")
1354         unless $rel_obj; #die Dumper $self->{attrs};
1355
1356       my $rs = $self->search(undef, { join => $rel });
1357       my $alias = defined $rs->{attrs}{seen_join}{$rel}
1358                     && $rs->{attrs}{seen_join}{$rel} > 1
1359                   ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
1360                   : $rel;
1361
1362       $self->result_source->schema->resultset($rel_obj->{class}
1363            )->search( undef,
1364              { %{$rs->{attrs}},
1365                alias => $alias,
1366                select => undef,
1367                as => undef }
1368            );
1369   };
1370 }
1371
1372 =head2 throw_exception
1373
1374 See L<DBIx::Class::Schema/throw_exception> for details.
1375
1376 =cut
1377
1378 sub throw_exception {
1379   my $self=shift;
1380   $self->result_source->schema->throw_exception(@_);
1381 }
1382
1383 # XXX: FIXME: Attributes docs need clearing up
1384
1385 =head1 ATTRIBUTES
1386
1387 The resultset takes various attributes that modify its behavior. Here's an
1388 overview of them:
1389
1390 =head2 order_by
1391
1392 =over 4
1393
1394 =item Value: ($order_by | \@order_by)
1395
1396 =back
1397
1398 Which column(s) to order the results by. This is currently passed
1399 through directly to SQL, so you can give e.g. C<year DESC> for a
1400 descending order on the column `year'.
1401
1402 =head2 columns
1403
1404 =over 4
1405
1406 =item Value: \@columns
1407
1408 =back
1409
1410 Shortcut to request a particular set of columns to be retrieved.  Adds
1411 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1412 from that, then auto-populates C<as> from C<select> as normal. (You may also
1413 use the C<cols> attribute, as in earlier versions of DBIC.)
1414
1415 =head2 include_columns
1416
1417 =over 4
1418
1419 =item Value: \@columns
1420
1421 =back
1422
1423 Shortcut to include additional columns in the returned results - for example
1424
1425   $schema->resultset('CD')->search(undef, {
1426     include_columns => ['artist.name'],
1427     join => ['artist']
1428   });
1429
1430 would return all CDs and include a 'name' column to the information
1431 passed to object inflation
1432
1433 =head2 select
1434
1435 =over 4
1436
1437 =item Value: \@select_columns
1438
1439 =back
1440
1441 Indicates which columns should be selected from the storage. You can use
1442 column names, or in the case of RDBMS back ends, function or stored procedure
1443 names:
1444
1445   $rs = $schema->resultset('Employee')->search(undef, {
1446     select => [
1447       'name',
1448       { count => 'employeeid' },
1449       { sum => 'salary' }
1450     ]
1451   });
1452
1453 When you use function/stored procedure names and do not supply an C<as>
1454 attribute, the column names returned are storage-dependent. E.g. MySQL would
1455 return a column named C<count(employeeid)> in the above example.
1456
1457 =head2 as
1458
1459 =over 4
1460
1461 =item Value: \@inflation_names
1462
1463 =back
1464
1465 Indicates column names for object inflation. This is used in conjunction with
1466 C<select>, usually when C<select> contains one or more function or stored
1467 procedure names:
1468
1469   $rs = $schema->resultset('Employee')->search(undef, {
1470     select => [
1471       'name',
1472       { count => 'employeeid' }
1473     ],
1474     as => ['name', 'employee_count'],
1475   });
1476
1477   my $employee = $rs->first(); # get the first Employee
1478
1479 If the object against which the search is performed already has an accessor
1480 matching a column name specified in C<as>, the value can be retrieved using
1481 the accessor as normal:
1482
1483   my $name = $employee->name();
1484
1485 If on the other hand an accessor does not exist in the object, you need to
1486 use C<get_column> instead:
1487
1488   my $employee_count = $employee->get_column('employee_count');
1489
1490 You can create your own accessors if required - see
1491 L<DBIx::Class::Manual::Cookbook> for details.
1492
1493 =head2 join
1494
1495 =over 4
1496
1497 =item Value: ($rel_name | \@rel_names | \%rel_names)
1498
1499 =back
1500
1501 Contains a list of relationships that should be joined for this query.  For
1502 example:
1503
1504   # Get CDs by Nine Inch Nails
1505   my $rs = $schema->resultset('CD')->search(
1506     { 'artist.name' => 'Nine Inch Nails' },
1507     { join => 'artist' }
1508   );
1509
1510 Can also contain a hash reference to refer to the other relation's relations.
1511 For example:
1512
1513   package MyApp::Schema::Track;
1514   use base qw/DBIx::Class/;
1515   __PACKAGE__->table('track');
1516   __PACKAGE__->add_columns(qw/trackid cd position title/);
1517   __PACKAGE__->set_primary_key('trackid');
1518   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1519   1;
1520
1521   # In your application
1522   my $rs = $schema->resultset('Artist')->search(
1523     { 'track.title' => 'Teardrop' },
1524     {
1525       join     => { cd => 'track' },
1526       order_by => 'artist.name',
1527     }
1528   );
1529
1530 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1531 similarly for a third time). For e.g.
1532
1533   my $rs = $schema->resultset('Artist')->search({
1534     'cds.title'   => 'Down to Earth',
1535     'cds_2.title' => 'Popular',
1536   }, {
1537     join => [ qw/cds cds/ ],
1538   });
1539
1540 will return a set of all artists that have both a cd with title 'Down
1541 to Earth' and a cd with title 'Popular'.
1542
1543 If you want to fetch related objects from other tables as well, see C<prefetch>
1544 below.
1545
1546 =head2 prefetch
1547
1548 =over 4
1549
1550 =item Value: ($rel_name | \@rel_names | \%rel_names)
1551
1552 =back
1553
1554 Contains one or more relationships that should be fetched along with the main
1555 query (when they are accessed afterwards they will have already been
1556 "prefetched").  This is useful for when you know you will need the related
1557 objects, because it saves at least one query:
1558
1559   my $rs = $schema->resultset('Tag')->search(
1560     undef,
1561     {
1562       prefetch => {
1563         cd => 'artist'
1564       }
1565     }
1566   );
1567
1568 The initial search results in SQL like the following:
1569
1570   SELECT tag.*, cd.*, artist.* FROM tag
1571   JOIN cd ON tag.cd = cd.cdid
1572   JOIN artist ON cd.artist = artist.artistid
1573
1574 L<DBIx::Class> has no need to go back to the database when we access the
1575 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1576 case.
1577
1578 Simple prefetches will be joined automatically, so there is no need
1579 for a C<join> attribute in the above search. If you're prefetching to
1580 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1581 specify the join as well.
1582
1583 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1584 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1585 with an accessor type of 'single' or 'filter').
1586
1587 =head2 from
1588
1589 =over 4
1590
1591 =item Value: \@from_clause
1592
1593 =back
1594
1595 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1596 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1597 clauses.
1598
1599 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1600 C<join> will usually do what you need and it is strongly recommended that you
1601 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1602
1603 In simple terms, C<from> works as follows:
1604
1605     [
1606         { <alias> => <table>, -join_type => 'inner|left|right' }
1607         [] # nested JOIN (optional)
1608         { <table.column> => <foreign_table.foreign_key> }
1609     ]
1610
1611     JOIN
1612         <alias> <table>
1613         [JOIN ...]
1614     ON <table.column> = <foreign_table.foreign_key>
1615
1616 An easy way to follow the examples below is to remember the following:
1617
1618     Anything inside "[]" is a JOIN
1619     Anything inside "{}" is a condition for the enclosing JOIN
1620
1621 The following examples utilize a "person" table in a family tree application.
1622 In order to express parent->child relationships, this table is self-joined:
1623
1624     # Person->belongs_to('father' => 'Person');
1625     # Person->belongs_to('mother' => 'Person');
1626
1627 C<from> can be used to nest joins. Here we return all children with a father,
1628 then search against all mothers of those children:
1629
1630   $rs = $schema->resultset('Person')->search(
1631       undef,
1632       {
1633           alias => 'mother', # alias columns in accordance with "from"
1634           from => [
1635               { mother => 'person' },
1636               [
1637                   [
1638                       { child => 'person' },
1639                       [
1640                           { father => 'person' },
1641                           { 'father.person_id' => 'child.father_id' }
1642                       ]
1643                   ],
1644                   { 'mother.person_id' => 'child.mother_id' }
1645               ],
1646           ]
1647       },
1648   );
1649
1650   # Equivalent SQL:
1651   # SELECT mother.* FROM person mother
1652   # JOIN (
1653   #   person child
1654   #   JOIN person father
1655   #   ON ( father.person_id = child.father_id )
1656   # )
1657   # ON ( mother.person_id = child.mother_id )
1658
1659 The type of any join can be controlled manually. To search against only people
1660 with a father in the person table, we could explicitly use C<INNER JOIN>:
1661
1662     $rs = $schema->resultset('Person')->search(
1663         undef,
1664         {
1665             alias => 'child', # alias columns in accordance with "from"
1666             from => [
1667                 { child => 'person' },
1668                 [
1669                     { father => 'person', -join_type => 'inner' },
1670                     { 'father.id' => 'child.father_id' }
1671                 ],
1672             ]
1673         },
1674     );
1675
1676     # Equivalent SQL:
1677     # SELECT child.* FROM person child
1678     # INNER JOIN person father ON child.father_id = father.id
1679
1680 =head2 page
1681
1682 =over 4
1683
1684 =item Value: $page
1685
1686 =back
1687
1688 Makes the resultset paged and specifies the page to retrieve. Effectively
1689 identical to creating a non-pages resultset and then calling ->page($page)
1690 on it.
1691
1692 =head2 rows
1693
1694 =over 4
1695
1696 =item Value: $rows
1697
1698 =back
1699
1700 Specifes the maximum number of rows for direct retrieval or the number of
1701 rows per page if the page attribute or method is used.
1702
1703 =head2 group_by
1704
1705 =over 4
1706
1707 =item Value: \@columns
1708
1709 =back
1710
1711 A arrayref of columns to group by. Can include columns of joined tables.
1712
1713   group_by => [qw/ column1 column2 ... /]
1714
1715 =head2 having
1716
1717 =over 4
1718
1719 =item Value: $condition
1720
1721 =back
1722
1723 HAVING is a select statement attribute that is applied between GROUP BY and
1724 ORDER BY. It is applied to the after the grouping calculations have been
1725 done. 
1726
1727   having => { 'count(employee)' => { '>=', 100 } }
1728
1729 =head2 distinct
1730
1731 =over 4
1732
1733 =item Value: (0 | 1)
1734
1735 =back
1736
1737 Set to 1 to group by all columns.
1738
1739 =head2 cache
1740
1741 Set to 1 to cache search results. This prevents extra SQL queries if you
1742 revisit rows in your ResultSet:
1743
1744   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1745   
1746   while( my $artist = $resultset->next ) {
1747     ... do stuff ...
1748   }
1749
1750   $rs->first; # without cache, this would issue a query
1751
1752 By default, searches are not cached.
1753
1754 For more examples of using these attributes, see
1755 L<DBIx::Class::Manual::Cookbook>.
1756
1757 =cut
1758
1759 1;