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