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