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