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