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