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