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