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