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