0b9d84fb416765bd8c5284296a278a958e6e40b2
[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 $cond = ref $_[0] eq 'HASH' ? shift : {@_};
1395
1396   my $row = $self->find($cond);
1397   if (defined $row) {
1398     $row->update($cond);
1399     return $row;
1400   }
1401
1402   return $self->create($cond);
1403 }
1404
1405 =head2 get_cache
1406
1407 =over 4
1408
1409 =item Arguments: none
1410
1411 =item Return Value: \@cache_objects?
1412
1413 =back
1414
1415 Gets the contents of the cache for the resultset, if the cache is set.
1416
1417 =cut
1418
1419 sub get_cache {
1420   shift->{all_cache};
1421 }
1422
1423 =head2 set_cache
1424
1425 =over 4
1426
1427 =item Arguments: \@cache_objects
1428
1429 =item Return Value: \@cache_objects
1430
1431 =back
1432
1433 Sets the contents of the cache for the resultset. Expects an arrayref
1434 of objects of the same class as those produced by the resultset. Note that
1435 if the cache is set the resultset will return the cached objects rather
1436 than re-querying the database even if the cache attr is not set.
1437
1438 =cut
1439
1440 sub set_cache {
1441   my ( $self, $data ) = @_;
1442   $self->throw_exception("set_cache requires an arrayref")
1443       if defined($data) && (ref $data ne 'ARRAY');
1444   $self->{all_cache} = $data;
1445 }
1446
1447 =head2 clear_cache
1448
1449 =over 4
1450
1451 =item Arguments: none
1452
1453 =item Return Value: []
1454
1455 =back
1456
1457 Clears the cache for the resultset.
1458
1459 =cut
1460
1461 sub clear_cache {
1462   shift->set_cache(undef);
1463 }
1464
1465 =head2 related_resultset
1466
1467 =over 4
1468
1469 =item Arguments: $relationship_name
1470
1471 =item Return Value: $resultset
1472
1473 =back
1474
1475 Returns a related resultset for the supplied relationship name.
1476
1477   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1478
1479 =cut
1480
1481 sub related_resultset {
1482   my ( $self, $rel ) = @_;
1483
1484   $self->{related_resultsets} ||= {};
1485   return $self->{related_resultsets}{$rel} ||= do {
1486       #warn "fetching related resultset for rel '$rel' " . $self->result_source->{name};
1487       my $rel_obj = $self->result_source->relationship_info($rel);
1488       $self->throw_exception(
1489         "search_related: result source '" . $self->result_source->name .
1490         "' has no such relationship ${rel}")
1491         unless $rel_obj; #die Dumper $self->{attrs};
1492
1493       my $rs = $self->result_source->schema->resultset($rel_obj->{class}
1494            )->search( undef,
1495              { %{$self->{attrs}},
1496                select => undef,
1497                as => undef,
1498                join => $rel,
1499                _live_join => $rel }
1500            );
1501
1502       # keep reference of the original resultset
1503       $rs->{_parent_rs} = $self->result_source;
1504       return $rs;
1505   };
1506 }
1507
1508 =head2 throw_exception
1509
1510 See L<DBIx::Class::Schema/throw_exception> for details.
1511
1512 =cut
1513
1514 sub throw_exception {
1515   my $self=shift;
1516   $self->result_source->schema->throw_exception(@_);
1517 }
1518
1519 # XXX: FIXME: Attributes docs need clearing up
1520
1521 =head1 ATTRIBUTES
1522
1523 The resultset takes various attributes that modify its behavior. Here's an
1524 overview of them:
1525
1526 =head2 order_by
1527
1528 =over 4
1529
1530 =item Value: ($order_by | \@order_by)
1531
1532 =back
1533
1534 Which column(s) to order the results by. This is currently passed
1535 through directly to SQL, so you can give e.g. C<year DESC> for a
1536 descending order on the column `year'.
1537
1538 Please note that if you have quoting enabled (see 
1539 L<DBIx::Class::Storage/quote_char>) you will need to do C<\'year DESC' > to
1540 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
1541 so you will need to manually quote things as appropriate.)
1542
1543 =head2 columns
1544
1545 =over 4
1546
1547 =item Value: \@columns
1548
1549 =back
1550
1551 Shortcut to request a particular set of columns to be retrieved.  Adds
1552 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1553 from that, then auto-populates C<as> from C<select> as normal. (You may also
1554 use the C<cols> attribute, as in earlier versions of DBIC.)
1555
1556 =head2 include_columns
1557
1558 =over 4
1559
1560 =item Value: \@columns
1561
1562 =back
1563
1564 Shortcut to include additional columns in the returned results - for example
1565
1566   $schema->resultset('CD')->search(undef, {
1567     include_columns => ['artist.name'],
1568     join => ['artist']
1569   });
1570
1571 would return all CDs and include a 'name' column to the information
1572 passed to object inflation
1573
1574 =head2 select
1575
1576 =over 4
1577
1578 =item Value: \@select_columns
1579
1580 =back
1581
1582 Indicates which columns should be selected from the storage. You can use
1583 column names, or in the case of RDBMS back ends, function or stored procedure
1584 names:
1585
1586   $rs = $schema->resultset('Employee')->search(undef, {
1587     select => [
1588       'name',
1589       { count => 'employeeid' },
1590       { sum => 'salary' }
1591     ]
1592   });
1593
1594 When you use function/stored procedure names and do not supply an C<as>
1595 attribute, the column names returned are storage-dependent. E.g. MySQL would
1596 return a column named C<count(employeeid)> in the above example.
1597
1598 =head2 +select
1599
1600 =over 4
1601
1602 Indicates additional columns to be selected from storage.  Works the same as
1603 L<select> but adds columns to the selection.
1604
1605 =back
1606
1607 =head2 +as
1608
1609 =over 4
1610
1611 Indicates additional column names for those added via L<+select>.
1612
1613 =back
1614
1615 =head2 as
1616
1617 =over 4
1618
1619 =item Value: \@inflation_names
1620
1621 =back
1622
1623 Indicates column names for object inflation. This is used in conjunction with
1624 C<select>, usually when C<select> contains one or more function or stored
1625 procedure names:
1626
1627   $rs = $schema->resultset('Employee')->search(undef, {
1628     select => [
1629       'name',
1630       { count => 'employeeid' }
1631     ],
1632     as => ['name', 'employee_count'],
1633   });
1634
1635   my $employee = $rs->first(); # get the first Employee
1636
1637 If the object against which the search is performed already has an accessor
1638 matching a column name specified in C<as>, the value can be retrieved using
1639 the accessor as normal:
1640
1641   my $name = $employee->name();
1642
1643 If on the other hand an accessor does not exist in the object, you need to
1644 use C<get_column> instead:
1645
1646   my $employee_count = $employee->get_column('employee_count');
1647
1648 You can create your own accessors if required - see
1649 L<DBIx::Class::Manual::Cookbook> for details.
1650
1651 Please note: This will NOT insert an C<AS employee_count> into the SQL statement
1652 produced, it is used for internal access only. Thus attempting to use the accessor
1653 in an C<order_by> clause or similar will fail misrably.
1654
1655 =head2 join
1656
1657 =over 4
1658
1659 =item Value: ($rel_name | \@rel_names | \%rel_names)
1660
1661 =back
1662
1663 Contains a list of relationships that should be joined for this query.  For
1664 example:
1665
1666   # Get CDs by Nine Inch Nails
1667   my $rs = $schema->resultset('CD')->search(
1668     { 'artist.name' => 'Nine Inch Nails' },
1669     { join => 'artist' }
1670   );
1671
1672 Can also contain a hash reference to refer to the other relation's relations.
1673 For example:
1674
1675   package MyApp::Schema::Track;
1676   use base qw/DBIx::Class/;
1677   __PACKAGE__->table('track');
1678   __PACKAGE__->add_columns(qw/trackid cd position title/);
1679   __PACKAGE__->set_primary_key('trackid');
1680   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1681   1;
1682
1683   # In your application
1684   my $rs = $schema->resultset('Artist')->search(
1685     { 'track.title' => 'Teardrop' },
1686     {
1687       join     => { cd => 'track' },
1688       order_by => 'artist.name',
1689     }
1690   );
1691
1692 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1693 similarly for a third time). For e.g.
1694
1695   my $rs = $schema->resultset('Artist')->search({
1696     'cds.title'   => 'Down to Earth',
1697     'cds_2.title' => 'Popular',
1698   }, {
1699     join => [ qw/cds cds/ ],
1700   });
1701
1702 will return a set of all artists that have both a cd with title 'Down
1703 to Earth' and a cd with title 'Popular'.
1704
1705 If you want to fetch related objects from other tables as well, see C<prefetch>
1706 below.
1707
1708 =head2 prefetch
1709
1710 =over 4
1711
1712 =item Value: ($rel_name | \@rel_names | \%rel_names)
1713
1714 =back
1715
1716 Contains one or more relationships that should be fetched along with the main
1717 query (when they are accessed afterwards they will have already been
1718 "prefetched").  This is useful for when you know you will need the related
1719 objects, because it saves at least one query:
1720
1721   my $rs = $schema->resultset('Tag')->search(
1722     undef,
1723     {
1724       prefetch => {
1725         cd => 'artist'
1726       }
1727     }
1728   );
1729
1730 The initial search results in SQL like the following:
1731
1732   SELECT tag.*, cd.*, artist.* FROM tag
1733   JOIN cd ON tag.cd = cd.cdid
1734   JOIN artist ON cd.artist = artist.artistid
1735
1736 L<DBIx::Class> has no need to go back to the database when we access the
1737 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1738 case.
1739
1740 Simple prefetches will be joined automatically, so there is no need
1741 for a C<join> attribute in the above search. If you're prefetching to
1742 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1743 specify the join as well.
1744
1745 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1746 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1747 with an accessor type of 'single' or 'filter').
1748
1749 =head2 page
1750
1751 =over 4
1752
1753 =item Value: $page
1754
1755 =back
1756
1757 Makes the resultset paged and specifies the page to retrieve. Effectively
1758 identical to creating a non-pages resultset and then calling ->page($page)
1759 on it. 
1760
1761 If L<rows> attribute is not specified it defualts to 10 rows per page.
1762
1763 =head2 rows
1764
1765 =over 4
1766
1767 =item Value: $rows
1768
1769 =back
1770
1771 Specifes the maximum number of rows for direct retrieval or the number of
1772 rows per page if the page attribute or method is used.
1773
1774 =head2 offset
1775
1776 =over 4
1777
1778 =item Value: $offset
1779
1780 =back
1781
1782 Specifies the (zero-based) row number for the  first row to be returned, or the
1783 of the first row of the first page if paging is used.
1784
1785 =head2 group_by
1786
1787 =over 4
1788
1789 =item Value: \@columns
1790
1791 =back
1792
1793 A arrayref of columns to group by. Can include columns of joined tables.
1794
1795   group_by => [qw/ column1 column2 ... /]
1796
1797 =head2 having
1798
1799 =over 4
1800
1801 =item Value: $condition
1802
1803 =back
1804
1805 HAVING is a select statement attribute that is applied between GROUP BY and
1806 ORDER BY. It is applied to the after the grouping calculations have been
1807 done. 
1808
1809   having => { 'count(employee)' => { '>=', 100 } }
1810
1811 =head2 distinct
1812
1813 =over 4
1814
1815 =item Value: (0 | 1)
1816
1817 =back
1818
1819 Set to 1 to group by all columns.
1820
1821 =head2 cache
1822
1823 Set to 1 to cache search results. This prevents extra SQL queries if you
1824 revisit rows in your ResultSet:
1825
1826   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1827   
1828   while( my $artist = $resultset->next ) {
1829     ... do stuff ...
1830   }
1831
1832   $rs->first; # without cache, this would issue a query
1833
1834 By default, searches are not cached.
1835
1836 For more examples of using these attributes, see
1837 L<DBIx::Class::Manual::Cookbook>.
1838
1839 =head2 from
1840
1841 =over 4
1842
1843 =item Value: \@from_clause
1844
1845 =back
1846
1847 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1848 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1849 clauses.
1850
1851 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1852
1853 C<join> will usually do what you need and it is strongly recommended that you
1854 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1855 And we really do mean "cannot", not just tried and failed. Attempting to use
1856 this because you're having problems with C<join> is like trying to use x86
1857 ASM because you've got a syntax error in your C. Trust us on this.
1858
1859 Now, if you're still really, really sure you need to use this (and if you're
1860 not 100% sure, ask the mailing list first), here's an explanation of how this
1861 works.
1862
1863 The syntax is as follows -
1864
1865   [
1866     { <alias1> => <table1> },
1867     [
1868       { <alias2> => <table2>, -join_type => 'inner|left|right' },
1869       [], # nested JOIN (optional)
1870       { <table1.column1> => <table2.column2>, ... (more conditions) },
1871     ],
1872     # More of the above [ ] may follow for additional joins
1873   ]
1874
1875   <table1> <alias1>
1876   JOIN
1877     <table2> <alias2>
1878     [JOIN ...]
1879   ON <table1.column1> = <table2.column2>
1880   <more joins may follow>
1881
1882 An easy way to follow the examples below is to remember the following:
1883
1884     Anything inside "[]" is a JOIN
1885     Anything inside "{}" is a condition for the enclosing JOIN
1886
1887 The following examples utilize a "person" table in a family tree application.
1888 In order to express parent->child relationships, this table is self-joined:
1889
1890     # Person->belongs_to('father' => 'Person');
1891     # Person->belongs_to('mother' => 'Person');
1892
1893 C<from> can be used to nest joins. Here we return all children with a father,
1894 then search against all mothers of those children:
1895
1896   $rs = $schema->resultset('Person')->search(
1897       undef,
1898       {
1899           alias => 'mother', # alias columns in accordance with "from"
1900           from => [
1901               { mother => 'person' },
1902               [
1903                   [
1904                       { child => 'person' },
1905                       [
1906                           { father => 'person' },
1907                           { 'father.person_id' => 'child.father_id' }
1908                       ]
1909                   ],
1910                   { 'mother.person_id' => 'child.mother_id' }
1911               ],
1912           ]
1913       },
1914   );
1915
1916   # Equivalent SQL:
1917   # SELECT mother.* FROM person mother
1918   # JOIN (
1919   #   person child
1920   #   JOIN person father
1921   #   ON ( father.person_id = child.father_id )
1922   # )
1923   # ON ( mother.person_id = child.mother_id )
1924
1925 The type of any join can be controlled manually. To search against only people
1926 with a father in the person table, we could explicitly use C<INNER JOIN>:
1927
1928     $rs = $schema->resultset('Person')->search(
1929         undef,
1930         {
1931             alias => 'child', # alias columns in accordance with "from"
1932             from => [
1933                 { child => 'person' },
1934                 [
1935                     { father => 'person', -join_type => 'inner' },
1936                     { 'father.id' => 'child.father_id' }
1937                 ],
1938             ]
1939         },
1940     );
1941
1942     # Equivalent SQL:
1943     # SELECT child.* FROM person child
1944     # INNER JOIN person father ON child.father_id = father.id
1945
1946 =cut
1947
1948 1;