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