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