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