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