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