Merge branch 'master' into topic/constructor_rewrite
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use base qw/DBIx::Class/;
6 use DBIx::Class::Carp;
7 use DBIx::Class::Exception;
8 use DBIx::Class::ResultSetColumn;
9 use Scalar::Util qw/blessed weaken/;
10 use Try::Tiny;
11 use Data::Compare (); # no imports!!! guard against insane architecture
12
13 # not importing first() as it will clash with our own method
14 use List::Util ();
15
16 BEGIN {
17   # De-duplication in _merge_attr() is disabled, but left in for reference
18   # (the merger is used for other things that ought not to be de-duped)
19   *__HM_DEDUP = sub () { 0 };
20 }
21
22 use namespace::clean;
23
24 use overload
25         '0+'     => "count",
26         'bool'   => "_bool",
27         fallback => 1;
28
29 __PACKAGE__->mk_group_accessors('simple' => qw/_result_class result_source/);
30
31 =head1 NAME
32
33 DBIx::Class::ResultSet - Represents a query used for fetching a set of results.
34
35 =head1 SYNOPSIS
36
37   my $users_rs   = $schema->resultset('User');
38   while( $user = $users_rs->next) {
39     print $user->username;
40   }
41
42   my $registered_users_rs   = $schema->resultset('User')->search({ registered => 1 });
43   my @cds_in_2005 = $schema->resultset('CD')->search({ year => 2005 })->all();
44
45 =head1 DESCRIPTION
46
47 A ResultSet is an object which stores a set of conditions representing
48 a query. It is the backbone of DBIx::Class (i.e. the really
49 important/useful bit).
50
51 No SQL is executed on the database when a ResultSet is created, it
52 just stores all the conditions needed to create the query.
53
54 A basic ResultSet representing the data of an entire table is returned
55 by calling C<resultset> on a L<DBIx::Class::Schema> and passing in a
56 L<Source|DBIx::Class::Manual::Glossary/Source> name.
57
58   my $users_rs = $schema->resultset('User');
59
60 A new ResultSet is returned from calling L</search> on an existing
61 ResultSet. The new one will contain all the conditions of the
62 original, plus any new conditions added in the C<search> call.
63
64 A ResultSet also incorporates an implicit iterator. L</next> and L</reset>
65 can be used to walk through all the L<DBIx::Class::Row>s the ResultSet
66 represents.
67
68 The query that the ResultSet represents is B<only> executed against
69 the database when these methods are called:
70 L</find>, L</next>, L</all>, L</first>, L</single>, L</count>.
71
72 If a resultset is used in a numeric context it returns the L</count>.
73 However, if it is used in a boolean context it is B<always> true.  So if
74 you want to check if a resultset has any results, you must use C<if $rs
75 != 0>.
76
77 =head1 CUSTOM ResultSet CLASSES THAT USE Moose
78
79 If you want to make your custom ResultSet classes with L<Moose>, use a template
80 similar to:
81
82     package MyApp::Schema::ResultSet::User;
83
84     use Moose;
85     use namespace::autoclean;
86     use MooseX::NonMoose;
87     extends 'DBIx::Class::ResultSet';
88
89     sub BUILDARGS { $_[2] }
90
91     ...your code...
92
93     __PACKAGE__->meta->make_immutable;
94
95     1;
96
97 The L<MooseX::NonMoose> is necessary so that the L<Moose> constructor does not
98 clash with the regular ResultSet constructor. Alternatively, you can use:
99
100     __PACKAGE__->meta->make_immutable(inline_constructor => 0);
101
102 The L<BUILDARGS|Moose::Manual::Construction/BUILDARGS> is necessary because the
103 signature of the ResultSet C<new> is C<< ->new($source, \%args) >>.
104
105 =head1 EXAMPLES
106
107 =head2 Chaining resultsets
108
109 Let's say you've got a query that needs to be run to return some data
110 to the user. But, you have an authorization system in place that
111 prevents certain users from seeing certain information. So, you want
112 to construct the basic query in one method, but add constraints to it in
113 another.
114
115   sub get_data {
116     my $self = shift;
117     my $request = $self->get_request; # Get a request object somehow.
118     my $schema = $self->result_source->schema;
119
120     my $cd_rs = $schema->resultset('CD')->search({
121       title => $request->param('title'),
122       year => $request->param('year'),
123     });
124
125     $cd_rs = $self->apply_security_policy( $cd_rs );
126
127     return $cd_rs->all();
128   }
129
130   sub apply_security_policy {
131     my $self = shift;
132     my ($rs) = @_;
133
134     return $rs->search({
135       subversive => 0,
136     });
137   }
138
139 =head3 Resolving conditions and attributes
140
141 When a resultset is chained from another resultset, conditions and
142 attributes with the same keys need resolving.
143
144 L</join>, L</prefetch>, L</+select>, L</+as> attributes are merged
145 into the existing ones from the original resultset.
146
147 The L</where> and L</having> attributes, and any search conditions, are
148 merged with an SQL C<AND> to the existing condition from the original
149 resultset.
150
151 All other attributes are overridden by any new ones supplied in the
152 search attributes.
153
154 =head2 Multiple queries
155
156 Since a resultset just defines a query, you can do all sorts of
157 things with it with the same object.
158
159   # Don't hit the DB yet.
160   my $cd_rs = $schema->resultset('CD')->search({
161     title => 'something',
162     year => 2009,
163   });
164
165   # Each of these hits the DB individually.
166   my $count = $cd_rs->count;
167   my $most_recent = $cd_rs->get_column('date_released')->max();
168   my @records = $cd_rs->all;
169
170 And it's not just limited to SELECT statements.
171
172   $cd_rs->delete();
173
174 This is even cooler:
175
176   $cd_rs->create({ artist => 'Fred' });
177
178 Which is the same as:
179
180   $schema->resultset('CD')->create({
181     title => 'something',
182     year => 2009,
183     artist => 'Fred'
184   });
185
186 See: L</search>, L</count>, L</get_column>, L</all>, L</create>.
187
188 =head1 METHODS
189
190 =head2 new
191
192 =over 4
193
194 =item Arguments: $source, \%$attrs
195
196 =item Return Value: $rs
197
198 =back
199
200 The resultset constructor. Takes a source object (usually a
201 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
202 L</ATTRIBUTES> below).  Does not perform any queries -- these are
203 executed as needed by the other methods.
204
205 Generally you won't need to construct a resultset manually.  You'll
206 automatically get one from e.g. a L</search> called in scalar context:
207
208   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
209
210 IMPORTANT: If called on an object, proxies to new_result instead so
211
212   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
213
214 will return a CD object, not a ResultSet.
215
216 =cut
217
218 sub new {
219   my $class = shift;
220   return $class->new_result(@_) if ref $class;
221
222   my ($source, $attrs) = @_;
223   $source = $source->resolve
224     if $source->isa('DBIx::Class::ResultSourceHandle');
225   $attrs = { %{$attrs||{}} };
226
227   if ($attrs->{page}) {
228     $attrs->{rows} ||= 10;
229   }
230
231   $attrs->{alias} ||= 'me';
232
233   my $self = bless {
234     result_source => $source,
235     cond => $attrs->{where},
236     pager => undef,
237     attrs => $attrs,
238   }, $class;
239
240   # if there is a dark selector, this means we are already in a
241   # chain and the cleanup/sanification was taken care of by
242   # _search_rs already
243   $self->_normalize_selection($attrs)
244     unless $attrs->{_dark_selector};
245
246   $self->result_class(
247     $attrs->{result_class} || $source->result_class
248   );
249
250   $self;
251 }
252
253 =head2 search
254
255 =over 4
256
257 =item Arguments: $cond, \%attrs?
258
259 =item Return Value: $resultset (scalar context) ||  @row_objs (list context)
260
261 =back
262
263   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
264   my $new_rs = $cd_rs->search({ year => 2005 });
265
266   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
267                  # year = 2005 OR year = 2004
268
269 In list context, C<< ->all() >> is called implicitly on the resultset, thus
270 returning a list of row objects instead. To avoid that, use L</search_rs>.
271
272 If you need to pass in additional attributes but no additional condition,
273 call it as C<search(undef, \%attrs)>.
274
275   # "SELECT name, artistid FROM $artist_table"
276   my @all_artists = $schema->resultset('Artist')->search(undef, {
277     columns => [qw/name artistid/],
278   });
279
280 For a list of attributes that can be passed to C<search>, see
281 L</ATTRIBUTES>. For more examples of using this function, see
282 L<Searching|DBIx::Class::Manual::Cookbook/Searching>. For a complete
283 documentation for the first argument, see L<SQL::Abstract>
284 and its extension L<DBIx::Class::SQLMaker>.
285
286 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
287
288 =head3 CAVEAT
289
290 Note that L</search> does not process/deflate any of the values passed in the
291 L<SQL::Abstract>-compatible search condition structure. This is unlike other
292 condition-bound methods L</new>, L</create> and L</find>. The user must ensure
293 manually that any value passed to this method will stringify to something the
294 RDBMS knows how to deal with. A notable example is the handling of L<DateTime>
295 objects, for more info see:
296 L<DBIx::Class::Manual::Cookbook/Formatting DateTime objects in queries>.
297
298 =cut
299
300 sub search {
301   my $self = shift;
302   my $rs = $self->search_rs( @_ );
303
304   if (wantarray) {
305     return $rs->all;
306   }
307   elsif (defined wantarray) {
308     return $rs;
309   }
310   else {
311     # we can be called by a relationship helper, which in
312     # turn may be called in void context due to some braindead
313     # overload or whatever else the user decided to be clever
314     # at this particular day. Thus limit the exception to
315     # external code calls only
316     $self->throw_exception ('->search is *not* a mutator, calling it in void context makes no sense')
317       if (caller)[0] !~ /^\QDBIx::Class::/;
318
319     return ();
320   }
321 }
322
323 =head2 search_rs
324
325 =over 4
326
327 =item Arguments: $cond, \%attrs?
328
329 =item Return Value: $resultset
330
331 =back
332
333 This method does the same exact thing as search() except it will
334 always return a resultset, even in list context.
335
336 =cut
337
338 sub search_rs {
339   my $self = shift;
340
341   # Special-case handling for (undef, undef).
342   if ( @_ == 2 && !defined $_[1] && !defined $_[0] ) {
343     @_ = ();
344   }
345
346   my $call_attrs = {};
347   if (@_ > 1) {
348     if (ref $_[-1] eq 'HASH') {
349       # copy for _normalize_selection
350       $call_attrs = { %{ pop @_ } };
351     }
352     elsif (! defined $_[-1] ) {
353       pop @_;   # search({}, undef)
354     }
355   }
356
357   # see if we can keep the cache (no $rs changes)
358   my $cache;
359   my %safe = (alias => 1, cache => 1);
360   if ( ! List::Util::first { !$safe{$_} } keys %$call_attrs and (
361     ! defined $_[0]
362       or
363     ref $_[0] eq 'HASH' && ! keys %{$_[0]}
364       or
365     ref $_[0] eq 'ARRAY' && ! @{$_[0]}
366   )) {
367     $cache = $self->get_cache;
368   }
369
370   my $rsrc = $self->result_source;
371
372   my $old_attrs = { %{$self->{attrs}} };
373   my $old_having = delete $old_attrs->{having};
374   my $old_where = delete $old_attrs->{where};
375
376   my $new_attrs = { %$old_attrs };
377
378   # take care of call attrs (only if anything is changing)
379   if (keys %$call_attrs) {
380
381     my @selector_attrs = qw/select as columns cols +select +as +columns include_columns/;
382
383     # reset the current selector list if new selectors are supplied
384     if (List::Util::first { exists $call_attrs->{$_} } qw/columns cols select as/) {
385       delete @{$old_attrs}{(@selector_attrs, '_dark_selector')};
386     }
387
388     # Normalize the new selector list (operates on the passed-in attr structure)
389     # Need to do it on every chain instead of only once on _resolved_attrs, in
390     # order to allow detection of empty vs partial 'as'
391     $call_attrs->{_dark_selector} = $old_attrs->{_dark_selector}
392       if $old_attrs->{_dark_selector};
393     $self->_normalize_selection ($call_attrs);
394
395     # start with blind overwriting merge, exclude selector attrs
396     $new_attrs = { %{$old_attrs}, %{$call_attrs} };
397     delete @{$new_attrs}{@selector_attrs};
398
399     for (@selector_attrs) {
400       $new_attrs->{$_} = $self->_merge_attr($old_attrs->{$_}, $call_attrs->{$_})
401         if ( exists $old_attrs->{$_} or exists $call_attrs->{$_} );
402     }
403
404     # older deprecated name, use only if {columns} is not there
405     if (my $c = delete $new_attrs->{cols}) {
406       if ($new_attrs->{columns}) {
407         carp "Resultset specifies both the 'columns' and the legacy 'cols' attributes - ignoring 'cols'";
408       }
409       else {
410         $new_attrs->{columns} = $c;
411       }
412     }
413
414
415     # join/prefetch use their own crazy merging heuristics
416     foreach my $key (qw/join prefetch/) {
417       $new_attrs->{$key} = $self->_merge_joinpref_attr($old_attrs->{$key}, $call_attrs->{$key})
418         if exists $call_attrs->{$key};
419     }
420
421     # stack binds together
422     $new_attrs->{bind} = [ @{ $old_attrs->{bind} || [] }, @{ $call_attrs->{bind} || [] } ];
423   }
424
425
426   # rip apart the rest of @_, parse a condition
427   my $call_cond = do {
428
429     if (ref $_[0] eq 'HASH') {
430       (keys %{$_[0]}) ? $_[0] : undef
431     }
432     elsif (@_ == 1) {
433       $_[0]
434     }
435     elsif (@_ % 2) {
436       $self->throw_exception('Odd number of arguments to search')
437     }
438     else {
439       +{ @_ }
440     }
441
442   } if @_;
443
444   if( @_ > 1 and ! $rsrc->result_class->isa('DBIx::Class::CDBICompat') ) {
445     carp_unique 'search( %condition ) is deprecated, use search( \%condition ) instead';
446   }
447
448   for ($old_where, $call_cond) {
449     if (defined $_) {
450       $new_attrs->{where} = $self->_stack_cond (
451         $_, $new_attrs->{where}
452       );
453     }
454   }
455
456   if (defined $old_having) {
457     $new_attrs->{having} = $self->_stack_cond (
458       $old_having, $new_attrs->{having}
459     )
460   }
461
462   my $rs = (ref $self)->new($rsrc, $new_attrs);
463
464   $rs->set_cache($cache) if ($cache);
465
466   return $rs;
467 }
468
469 my $dark_sel_dumper;
470 sub _normalize_selection {
471   my ($self, $attrs) = @_;
472
473   # legacy syntax
474   $attrs->{'+columns'} = $self->_merge_attr($attrs->{'+columns'}, delete $attrs->{include_columns})
475     if exists $attrs->{include_columns};
476
477   # columns are always placed first, however
478
479   # Keep the X vs +X separation until _resolved_attrs time - this allows to
480   # delay the decision on whether to use a default select list ($rsrc->columns)
481   # allowing stuff like the remove_columns helper to work
482   #
483   # select/as +select/+as pairs need special handling - the amount of select/as
484   # elements in each pair does *not* have to be equal (think multicolumn
485   # selectors like distinct(foo, bar) ). If the selector is bare (no 'as'
486   # supplied at all) - try to infer the alias, either from the -as parameter
487   # of the selector spec, or use the parameter whole if it looks like a column
488   # name (ugly legacy heuristic). If all fails - leave the selector bare (which
489   # is ok as well), but make sure no more additions to the 'as' chain take place
490   for my $pref ('', '+') {
491
492     my ($sel, $as) = map {
493       my $key = "${pref}${_}";
494
495       my $val = [ ref $attrs->{$key} eq 'ARRAY'
496         ? @{$attrs->{$key}}
497         : $attrs->{$key} || ()
498       ];
499       delete $attrs->{$key};
500       $val;
501     } qw/select as/;
502
503     if (! @$as and ! @$sel ) {
504       next;
505     }
506     elsif (@$as and ! @$sel) {
507       $self->throw_exception(
508         "Unable to handle ${pref}as specification (@$as) without a corresponding ${pref}select"
509       );
510     }
511     elsif( ! @$as ) {
512       # no as part supplied at all - try to deduce (unless explicit end of named selection is declared)
513       # if any @$as has been supplied we assume the user knows what (s)he is doing
514       # and blindly keep stacking up pieces
515       unless ($attrs->{_dark_selector}) {
516         SELECTOR:
517         for (@$sel) {
518           if ( ref $_ eq 'HASH' and exists $_->{-as} ) {
519             push @$as, $_->{-as};
520           }
521           # assume any plain no-space, no-parenthesis string to be a column spec
522           # FIXME - this is retarded but is necessary to support shit like 'count(foo)'
523           elsif ( ! ref $_ and $_ =~ /^ [^\s\(\)]+ $/x) {
524             push @$as, $_;
525           }
526           # if all else fails - raise a flag that no more aliasing will be allowed
527           else {
528             $attrs->{_dark_selector} = {
529               plus_stage => $pref,
530               string => ($dark_sel_dumper ||= do {
531                   require Data::Dumper::Concise;
532                   Data::Dumper::Concise::DumperObject()->Indent(0);
533                 })->Values([$_])->Dump
534               ,
535             };
536             last SELECTOR;
537           }
538         }
539       }
540     }
541     elsif (@$as < @$sel) {
542       $self->throw_exception(
543         "Unable to handle an ${pref}as specification (@$as) with less elements than the corresponding ${pref}select"
544       );
545     }
546     elsif ($pref and $attrs->{_dark_selector}) {
547       $self->throw_exception(
548         "Unable to process named '+select', resultset contains an unnamed selector $attrs->{_dark_selector}{string}"
549       );
550     }
551
552
553     # merge result
554     $attrs->{"${pref}select"} = $self->_merge_attr($attrs->{"${pref}select"}, $sel);
555     $attrs->{"${pref}as"} = $self->_merge_attr($attrs->{"${pref}as"}, $as);
556   }
557 }
558
559 sub _stack_cond {
560   my ($self, $left, $right) = @_;
561
562   # collapse single element top-level conditions
563   # (single pass only, unlikely to need recursion)
564   for ($left, $right) {
565     if (ref $_ eq 'ARRAY') {
566       if (@$_ == 0) {
567         $_ = undef;
568       }
569       elsif (@$_ == 1) {
570         $_ = $_->[0];
571       }
572     }
573     elsif (ref $_ eq 'HASH') {
574       my ($first, $more) = keys %$_;
575
576       # empty hash
577       if (! defined $first) {
578         $_ = undef;
579       }
580       # one element hash
581       elsif (! defined $more) {
582         if ($first eq '-and' and ref $_->{'-and'} eq 'HASH') {
583           $_ = $_->{'-and'};
584         }
585         elsif ($first eq '-or' and ref $_->{'-or'} eq 'ARRAY') {
586           $_ = $_->{'-or'};
587         }
588       }
589     }
590   }
591
592   # merge hashes with weeding out of duplicates (simple cases only)
593   if (ref $left eq 'HASH' and ref $right eq 'HASH') {
594
595     # shallow copy to destroy
596     $right = { %$right };
597     for (grep { exists $right->{$_} } keys %$left) {
598       # the use of eq_deeply here is justified - the rhs of an
599       # expression can contain a lot of twisted weird stuff
600       delete $right->{$_} if Data::Compare::Compare( $left->{$_}, $right->{$_} );
601     }
602
603     $right = undef unless keys %$right;
604   }
605
606
607   if (defined $left xor defined $right) {
608     return defined $left ? $left : $right;
609   }
610   elsif (! defined $left) {
611     return undef;
612   }
613   else {
614     return { -and => [ $left, $right ] };
615   }
616 }
617
618 =head2 search_literal
619
620 =over 4
621
622 =item Arguments: $sql_fragment, @bind_values
623
624 =item Return Value: $resultset (scalar context) || @row_objs (list context)
625
626 =back
627
628   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
629   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
630
631 Pass a literal chunk of SQL to be added to the conditional part of the
632 resultset query.
633
634 CAVEAT: C<search_literal> is provided for Class::DBI compatibility and should
635 only be used in that context. C<search_literal> is a convenience method.
636 It is equivalent to calling $schema->search(\[]), but if you want to ensure
637 columns are bound correctly, use C<search>.
638
639 Example of how to use C<search> instead of C<search_literal>
640
641   my @cds = $cd_rs->search_literal('cdid = ? AND (artist = ? OR artist = ?)', (2, 1, 2));
642   my @cds = $cd_rs->search(\[ 'cdid = ? AND (artist = ? OR artist = ?)', [ 'cdid', 2 ], [ 'artist', 1 ], [ 'artist', 2 ] ]);
643
644
645 See L<DBIx::Class::Manual::Cookbook/Searching> and
646 L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not
647 require C<search_literal>.
648
649 =cut
650
651 sub search_literal {
652   my ($self, $sql, @bind) = @_;
653   my $attr;
654   if ( @bind && ref($bind[-1]) eq 'HASH' ) {
655     $attr = pop @bind;
656   }
657   return $self->search(\[ $sql, map [ __DUMMY__ => $_ ], @bind ], ($attr || () ));
658 }
659
660 =head2 find
661
662 =over 4
663
664 =item Arguments: \%columns_values | @pk_values, \%attrs?
665
666 =item Return Value: $row_object | undef
667
668 =back
669
670 Finds and returns a single row based on supplied criteria. Takes either a
671 hashref with the same format as L</create> (including inference of foreign
672 keys from related objects), or a list of primary key values in the same
673 order as the L<primary columns|DBIx::Class::ResultSource/primary_columns>
674 declaration on the L</result_source>.
675
676 In either case an attempt is made to combine conditions already existing on
677 the resultset with the condition passed to this method.
678
679 To aid with preparing the correct query for the storage you may supply the
680 C<key> attribute, which is the name of a
681 L<unique constraint|DBIx::Class::ResultSource/add_unique_constraint> (the
682 unique constraint corresponding to the
683 L<primary columns|DBIx::Class::ResultSource/primary_columns> is always named
684 C<primary>). If the C<key> attribute has been supplied, and DBIC is unable
685 to construct a query that satisfies the named unique constraint fully (
686 non-NULL values for each column member of the constraint) an exception is
687 thrown.
688
689 If no C<key> is specified, the search is carried over all unique constraints
690 which are fully defined by the available condition.
691
692 If no such constraint is found, C<find> currently defaults to a simple
693 C<< search->(\%column_values) >> which may or may not do what you expect.
694 Note that this fallback behavior may be deprecated in further versions. If
695 you need to search with arbitrary conditions - use L</search>. If the query
696 resulting from this fallback produces more than one row, a warning to the
697 effect is issued, though only the first row is constructed and returned as
698 C<$row_object>.
699
700 In addition to C<key>, L</find> recognizes and applies standard
701 L<resultset attributes|/ATTRIBUTES> in the same way as L</search> does.
702
703 Note that if you have extra concerns about the correctness of the resulting
704 query you need to specify the C<key> attribute and supply the entire condition
705 as an argument to find (since it is not always possible to perform the
706 combination of the resultset condition with the supplied one, especially if
707 the resultset condition contains literal sql).
708
709 For example, to find a row by its primary key:
710
711   my $cd = $schema->resultset('CD')->find(5);
712
713 You can also find a row by a specific unique constraint:
714
715   my $cd = $schema->resultset('CD')->find(
716     {
717       artist => 'Massive Attack',
718       title  => 'Mezzanine',
719     },
720     { key => 'cd_artist_title' }
721   );
722
723 See also L</find_or_create> and L</update_or_create>.
724
725 =cut
726
727 sub find {
728   my $self = shift;
729   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
730
731   my $rsrc = $self->result_source;
732
733   my $constraint_name;
734   if (exists $attrs->{key}) {
735     $constraint_name = defined $attrs->{key}
736       ? $attrs->{key}
737       : $self->throw_exception("An undefined 'key' resultset attribute makes no sense")
738     ;
739   }
740
741   # Parse out the condition from input
742   my $call_cond;
743
744   if (ref $_[0] eq 'HASH') {
745     $call_cond = { %{$_[0]} };
746   }
747   else {
748     # if only values are supplied we need to default to 'primary'
749     $constraint_name = 'primary' unless defined $constraint_name;
750
751     my @c_cols = $rsrc->unique_constraint_columns($constraint_name);
752
753     $self->throw_exception(
754       "No constraint columns, maybe a malformed '$constraint_name' constraint?"
755     ) unless @c_cols;
756
757     $self->throw_exception (
758       'find() expects either a column/value hashref, or a list of values '
759     . "corresponding to the columns of the specified unique constraint '$constraint_name'"
760     ) unless @c_cols == @_;
761
762     $call_cond = {};
763     @{$call_cond}{@c_cols} = @_;
764   }
765
766   my %related;
767   for my $key (keys %$call_cond) {
768     if (
769       my $keyref = ref($call_cond->{$key})
770         and
771       my $relinfo = $rsrc->relationship_info($key)
772     ) {
773       my $val = delete $call_cond->{$key};
774
775       next if $keyref eq 'ARRAY'; # has_many for multi_create
776
777       my $rel_q = $rsrc->_resolve_condition(
778         $relinfo->{cond}, $val, $key, $key
779       );
780       die "Can't handle complex relationship conditions in find" if ref($rel_q) ne 'HASH';
781       @related{keys %$rel_q} = values %$rel_q;
782     }
783   }
784
785   # relationship conditions take precedence (?)
786   @{$call_cond}{keys %related} = values %related;
787
788   my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias};
789   my $final_cond;
790   if (defined $constraint_name) {
791     $final_cond = $self->_qualify_cond_columns (
792
793       $self->_build_unique_cond (
794         $constraint_name,
795         $call_cond,
796       ),
797
798       $alias,
799     );
800   }
801   elsif ($self->{attrs}{accessor} and $self->{attrs}{accessor} eq 'single') {
802     # This means that we got here after a merger of relationship conditions
803     # in ::Relationship::Base::search_related (the row method), and furthermore
804     # the relationship is of the 'single' type. This means that the condition
805     # provided by the relationship (already attached to $self) is sufficient,
806     # as there can be only one row in the database that would satisfy the
807     # relationship
808   }
809   else {
810     # no key was specified - fall down to heuristics mode:
811     # run through all unique queries registered on the resultset, and
812     # 'OR' all qualifying queries together
813     my (@unique_queries, %seen_column_combinations);
814     for my $c_name ($rsrc->unique_constraint_names) {
815       next if $seen_column_combinations{
816         join "\x00", sort $rsrc->unique_constraint_columns($c_name)
817       }++;
818
819       push @unique_queries, try {
820         $self->_build_unique_cond ($c_name, $call_cond, 'croak_on_nulls')
821       } || ();
822     }
823
824     $final_cond = @unique_queries
825       ? [ map { $self->_qualify_cond_columns($_, $alias) } @unique_queries ]
826       : $self->_non_unique_find_fallback ($call_cond, $attrs)
827     ;
828   }
829
830   # Run the query, passing the result_class since it should propagate for find
831   my $rs = $self->search ($final_cond, {result_class => $self->result_class, %$attrs});
832   if ($rs->_resolved_attrs->{collapse}) {
833     my $row = $rs->next;
834     carp "Query returned more than one row" if $rs->next;
835     return $row;
836   }
837   else {
838     return $rs->single;
839   }
840 }
841
842 # This is a stop-gap method as agreed during the discussion on find() cleanup:
843 # http://lists.scsys.co.uk/pipermail/dbix-class/2010-October/009535.html
844 #
845 # It is invoked when find() is called in legacy-mode with insufficiently-unique
846 # condition. It is provided for overrides until a saner way forward is devised
847 #
848 # *NOTE* This is not a public method, and it's *GUARANTEED* to disappear down
849 # the road. Please adjust your tests accordingly to catch this situation early
850 # DBIx::Class::ResultSet->can('_non_unique_find_fallback') is reasonable
851 #
852 # The method will not be removed without an adequately complete replacement
853 # for strict-mode enforcement
854 sub _non_unique_find_fallback {
855   my ($self, $cond, $attrs) = @_;
856
857   return $self->_qualify_cond_columns(
858     $cond,
859     exists $attrs->{alias}
860       ? $attrs->{alias}
861       : $self->{attrs}{alias}
862   );
863 }
864
865
866 sub _qualify_cond_columns {
867   my ($self, $cond, $alias) = @_;
868
869   my %aliased = %$cond;
870   for (keys %aliased) {
871     $aliased{"$alias.$_"} = delete $aliased{$_}
872       if $_ !~ /\./;
873   }
874
875   return \%aliased;
876 }
877
878 sub _build_unique_cond {
879   my ($self, $constraint_name, $extra_cond, $croak_on_null) = @_;
880
881   my @c_cols = $self->result_source->unique_constraint_columns($constraint_name);
882
883   # combination may fail if $self->{cond} is non-trivial
884   my ($final_cond) = try {
885     $self->_merge_with_rscond ($extra_cond)
886   } catch {
887     +{ %$extra_cond }
888   };
889
890   # trim out everything not in $columns
891   $final_cond = { map {
892     exists $final_cond->{$_}
893       ? ( $_ => $final_cond->{$_} )
894       : ()
895   } @c_cols };
896
897   if (my @missing = grep
898     { ! ($croak_on_null ? defined $final_cond->{$_} : exists $final_cond->{$_}) }
899     (@c_cols)
900   ) {
901     $self->throw_exception( sprintf ( "Unable to satisfy requested constraint '%s', no values for column(s): %s",
902       $constraint_name,
903       join (', ', map { "'$_'" } @missing),
904     ) );
905   }
906
907   if (
908     !$croak_on_null
909       and
910     !$ENV{DBIC_NULLABLE_KEY_NOWARN}
911       and
912     my @undefs = grep { ! defined $final_cond->{$_} } (keys %$final_cond)
913   ) {
914     carp_unique ( sprintf (
915       "NULL/undef values supplied for requested unique constraint '%s' (NULL "
916     . 'values in column(s): %s). This is almost certainly not what you wanted, '
917     . 'though you can set DBIC_NULLABLE_KEY_NOWARN to disable this warning.',
918       $constraint_name,
919       join (', ', map { "'$_'" } @undefs),
920     ));
921   }
922
923   return $final_cond;
924 }
925
926 =head2 search_related
927
928 =over 4
929
930 =item Arguments: $rel, $cond?, \%attrs?
931
932 =item Return Value: $new_resultset (scalar context) || @row_objs (list context)
933
934 =back
935
936   $new_rs = $cd_rs->search_related('artist', {
937     name => 'Emo-R-Us',
938   });
939
940 Searches the specified relationship, optionally specifying a condition and
941 attributes for matching records. See L</ATTRIBUTES> for more information.
942
943 In list context, C<< ->all() >> is called implicitly on the resultset, thus
944 returning a list of row objects instead. To avoid that, use L</search_related_rs>.
945
946 See also L</search_related_rs>.
947
948 =cut
949
950 sub search_related {
951   return shift->related_resultset(shift)->search(@_);
952 }
953
954 =head2 search_related_rs
955
956 This method works exactly the same as search_related, except that
957 it guarantees a resultset, even in list context.
958
959 =cut
960
961 sub search_related_rs {
962   return shift->related_resultset(shift)->search_rs(@_);
963 }
964
965 =head2 cursor
966
967 =over 4
968
969 =item Arguments: none
970
971 =item Return Value: $cursor
972
973 =back
974
975 Returns a storage-driven cursor to the given resultset. See
976 L<DBIx::Class::Cursor> for more information.
977
978 =cut
979
980 sub cursor {
981   my ($self) = @_;
982
983   my $attrs = $self->_resolved_attrs_copy;
984
985   return $self->{cursor}
986     ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
987           $attrs->{where},$attrs);
988 }
989
990 =head2 single
991
992 =over 4
993
994 =item Arguments: $cond?
995
996 =item Return Value: $row_object | undef
997
998 =back
999
1000   my $cd = $schema->resultset('CD')->single({ year => 2001 });
1001
1002 Inflates the first result without creating a cursor if the resultset has
1003 any records in it; if not returns C<undef>. Used by L</find> as a lean version
1004 of L</search>.
1005
1006 While this method can take an optional search condition (just like L</search>)
1007 being a fast-code-path it does not recognize search attributes. If you need to
1008 add extra joins or similar, call L</search> and then chain-call L</single> on the
1009 L<DBIx::Class::ResultSet> returned.
1010
1011 =over
1012
1013 =item B<Note>
1014
1015 As of 0.08100, this method enforces the assumption that the preceding
1016 query returns only one row. If more than one row is returned, you will receive
1017 a warning:
1018
1019   Query returned more than one row
1020
1021 In this case, you should be using L</next> or L</find> instead, or if you really
1022 know what you are doing, use the L</rows> attribute to explicitly limit the size
1023 of the resultset.
1024
1025 This method will also throw an exception if it is called on a resultset prefetching
1026 has_many, as such a prefetch implies fetching multiple rows from the database in
1027 order to assemble the resulting object.
1028
1029 =back
1030
1031 =cut
1032
1033 sub single {
1034   my ($self, $where) = @_;
1035   if(@_ > 2) {
1036       $self->throw_exception('single() only takes search conditions, no attributes. You want ->search( $cond, $attrs )->single()');
1037   }
1038
1039   my $attrs = $self->_resolved_attrs_copy;
1040
1041   if ($attrs->{collapse}) {
1042     $self->throw_exception(
1043       'single() can not be used on resultsets prefetching has_many. Use find( \%cond ) or next() instead'
1044     );
1045   }
1046
1047   if ($where) {
1048     if (defined $attrs->{where}) {
1049       $attrs->{where} = {
1050         '-and' =>
1051             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
1052                $where, delete $attrs->{where} ]
1053       };
1054     } else {
1055       $attrs->{where} = $where;
1056     }
1057   }
1058
1059   my @data = $self->result_source->storage->select_single(
1060     $attrs->{from}, $attrs->{select},
1061     $attrs->{where}, $attrs
1062   );
1063
1064   return @data
1065     ? ($self->_construct_objects(@data))[0]
1066     : undef
1067   ;
1068 }
1069
1070
1071 # _collapse_query
1072 #
1073 # Recursively collapse the query, accumulating values for each column.
1074
1075 sub _collapse_query {
1076   my ($self, $query, $collapsed) = @_;
1077
1078   $collapsed ||= {};
1079
1080   if (ref $query eq 'ARRAY') {
1081     foreach my $subquery (@$query) {
1082       next unless ref $subquery;  # -or
1083       $collapsed = $self->_collapse_query($subquery, $collapsed);
1084     }
1085   }
1086   elsif (ref $query eq 'HASH') {
1087     if (keys %$query and (keys %$query)[0] eq '-and') {
1088       foreach my $subquery (@{$query->{-and}}) {
1089         $collapsed = $self->_collapse_query($subquery, $collapsed);
1090       }
1091     }
1092     else {
1093       foreach my $col (keys %$query) {
1094         my $value = $query->{$col};
1095         $collapsed->{$col}{$value}++;
1096       }
1097     }
1098   }
1099
1100   return $collapsed;
1101 }
1102
1103 =head2 get_column
1104
1105 =over 4
1106
1107 =item Arguments: $cond?
1108
1109 =item Return Value: $resultsetcolumn
1110
1111 =back
1112
1113   my $max_length = $rs->get_column('length')->max;
1114
1115 Returns a L<DBIx::Class::ResultSetColumn> instance for a column of the ResultSet.
1116
1117 =cut
1118
1119 sub get_column {
1120   my ($self, $column) = @_;
1121   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
1122   return $new;
1123 }
1124
1125 =head2 search_like
1126
1127 =over 4
1128
1129 =item Arguments: $cond, \%attrs?
1130
1131 =item Return Value: $resultset (scalar context) || @row_objs (list context)
1132
1133 =back
1134
1135   # WHERE title LIKE '%blue%'
1136   $cd_rs = $rs->search_like({ title => '%blue%'});
1137
1138 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
1139 that this is simply a convenience method retained for ex Class::DBI users.
1140 You most likely want to use L</search> with specific operators.
1141
1142 For more information, see L<DBIx::Class::Manual::Cookbook>.
1143
1144 This method is deprecated and will be removed in 0.09. Use L</search()>
1145 instead. An example conversion is:
1146
1147   ->search_like({ foo => 'bar' });
1148
1149   # Becomes
1150
1151   ->search({ foo => { like => 'bar' } });
1152
1153 =cut
1154
1155 sub search_like {
1156   my $class = shift;
1157   carp_unique (
1158     'search_like() is deprecated and will be removed in DBIC version 0.09.'
1159    .' Instead use ->search({ x => { -like => "y%" } })'
1160    .' (note the outer pair of {}s - they are important!)'
1161   );
1162   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1163   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
1164   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
1165   return $class->search($query, { %$attrs });
1166 }
1167
1168 =head2 slice
1169
1170 =over 4
1171
1172 =item Arguments: $first, $last
1173
1174 =item Return Value: $resultset (scalar context) || @row_objs (list context)
1175
1176 =back
1177
1178 Returns a resultset or object list representing a subset of elements from the
1179 resultset slice is called on. Indexes are from 0, i.e., to get the first
1180 three records, call:
1181
1182   my ($one, $two, $three) = $rs->slice(0, 2);
1183
1184 =cut
1185
1186 sub slice {
1187   my ($self, $min, $max) = @_;
1188   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
1189   $attrs->{offset} = $self->{attrs}{offset} || 0;
1190   $attrs->{offset} += $min;
1191   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
1192   return $self->search(undef, $attrs);
1193   #my $slice = (ref $self)->new($self->result_source, $attrs);
1194   #return (wantarray ? $slice->all : $slice);
1195 }
1196
1197 =head2 next
1198
1199 =over 4
1200
1201 =item Arguments: none
1202
1203 =item Return Value: $result | undef
1204
1205 =back
1206
1207 Returns the next element in the resultset (C<undef> is there is none).
1208
1209 Can be used to efficiently iterate over records in the resultset:
1210
1211   my $rs = $schema->resultset('CD')->search;
1212   while (my $cd = $rs->next) {
1213     print $cd->title;
1214   }
1215
1216 Note that you need to store the resultset object, and call C<next> on it.
1217 Calling C<< resultset('Table')->next >> repeatedly will always return the
1218 first record from the resultset.
1219
1220 =cut
1221
1222 sub next {
1223   my ($self) = @_;
1224   if (my $cache = $self->get_cache) {
1225     $self->{all_cache_position} ||= 0;
1226     return $cache->[$self->{all_cache_position}++];
1227   }
1228   if ($self->{attrs}{cache}) {
1229     delete $self->{pager};
1230     $self->{all_cache_position} = 1;
1231     return ($self->all)[0];
1232   }
1233   if ($self->{stashed_objects}) {
1234     my $obj = shift(@{$self->{stashed_objects}});
1235     delete $self->{stashed_objects} unless @{$self->{stashed_objects}};
1236     return $obj;
1237   }
1238   my @row = (
1239     exists $self->{stashed_row}
1240       ? @{delete $self->{stashed_row}}
1241       : $self->cursor->next
1242   );
1243   return undef unless (@row);
1244   my ($row, @more) = $self->_construct_objects(@row);
1245   $self->{stashed_objects} = \@more if @more;
1246   return $row;
1247 }
1248
1249 # takes a single DBI-row of data and coinstructs as many objects
1250 # as the resultset attributes call for.
1251 # This can be a bit of an action at a distance - it takes as an argument
1252 # the *current* cursor-row (already taken off the $sth), but if
1253 # collapsing is requested it will keep advancing the cursor either
1254 # until the current row-object is assembled (the collapser was able to
1255 # order the result sensibly) OR until the cursor is exhausted (an
1256 # unordered collapsing resultset effectively triggers ->all)
1257
1258 # FIXME: why the *FUCK* do we pass around DBI data by copy?! Sadly needs
1259 # assessment before changing...
1260 #
1261 sub _construct_objects {
1262   my ($self, @row) = @_;
1263   my $attrs = $self->_resolved_attrs;
1264   my $keep_collapsing = $attrs->{collapse};
1265
1266   my $res_index;
1267 =begin
1268   do {
1269     my $me_pref_col = $attrs->{_row_parser}->($row_ref);
1270
1271     my $container;
1272     if ($keep_collapsing) {
1273
1274       # FIXME - we should be able to remove these 2 checks after the design validates
1275       $self->throw_exception ('Collapsing without a top-level collapse-set... can not happen')
1276         unless @{$me_ref_col->[2]};
1277       $self->throw_exception ('Top-level collapse-set contains a NULL-value... can not happen')
1278         if grep { ! defined $_ }  @{$me_pref_col->[2]};
1279
1280       my $main_ident = join "\x00", @{$me_pref_col->[2]};
1281
1282       if (! $res_index->{$main_ident}) {
1283         # this is where we bail out IFF we are ordered, and the $main_ident changes
1284
1285         $res_index->{$main_ident} = {
1286           all_me_pref => [,
1287           index => scalar keys %$res_index,
1288         };
1289       }
1290     }
1291
1292
1293
1294       $container = $res_index->{$main_ident}{container};
1295     };
1296
1297     push @$container, [ @{$me_pref_col}[0,1] ];
1298
1299
1300
1301   } while (
1302     $keep_collapsing
1303       &&
1304     do { $row_ref = [$self->cursor->next]; $self->{stashed_row} = $row_ref if @$row_ref; scalar @$row_ref }
1305   );
1306
1307   # attempt collapse all rows with same collapse identity
1308   if (@to_collapse > 1) {
1309     my @collapsed;
1310     while (@to_collapse) {
1311       $self->_merge_result(\@collapsed, shift @to_collapse);
1312     }
1313   }
1314 =cut
1315
1316   my $mepref_structs = $self->_collapse_result($attrs->{as}, \@row, $keep_collapsing)
1317     or return ();
1318
1319   my $rsrc = $self->result_source;
1320   my $res_class = $self->result_class;
1321   my $inflator = $res_class->can ('inflate_result');
1322
1323   my @objs =
1324     $res_class->$inflator ($rsrc, @$mepref_structs);
1325
1326   if (my $f = $attrs->{record_filter}) {
1327     @objs = map { $f->($_) } @objs;
1328   }
1329
1330   return @objs;
1331 }
1332
1333
1334 sub _collapse_result {
1335   my ( $self, $as_proto, $row_ref, $keep_collapsing ) = @_;
1336   my $collapse = $self->_resolved_attrs->{collapse};
1337   my $parser   = $self->result_source->_mk_row_parser( $as_proto, $collapse );
1338   my $result   = [];
1339   my $register = {};
1340   my $rel_register = {};
1341
1342   my @row = @$row_ref;
1343   do {
1344     my $row = $parser->( \@row );
1345
1346     # init register
1347     $self->_check_register( $register, $row ) unless ( keys %$register );
1348
1349     $self->_merge_result( $result, $row, $rel_register )
1350       if ( !$collapse
1351       || ( $collapse = $self->_check_register( $register, $row ) ) );
1352
1353     } while (
1354     $collapse
1355     && do { @row = $self->cursor->next; $self->{stashed_row} = \@row if @row; }
1356
1357   # run this as long as there is a next row and we are not yet done collapsing
1358     );
1359   return $result;
1360 }
1361
1362
1363
1364 # Taubenschlag
1365 sub _check_register {
1366   my ( $self, $register, $obj ) = @_;
1367   return undef unless ( ref $obj eq 'ARRAY' && ref $obj->[2] eq 'ARRAY' );
1368   my @ids = @{ $obj->[2] };
1369   while ( defined( my $id = shift @ids ) ) {
1370     return $register->{$id} if ( exists $register->{$id} && !@ids );
1371     $register->{$id} = @ids ? {} : $obj unless ( exists $register->{$id} );
1372     $register = $register->{$id};
1373   }
1374   return undef;
1375 }
1376
1377 sub _merge_result {
1378   my ( $self, $result, $row, $register ) = @_;
1379   return @$result = @$row if ( @$result == 0 );  # initialize with $row
1380
1381   my ( undef, $rels,   $ids )   = @$result;
1382   my ( undef, $new_rels, $new_ids ) = @$row;
1383
1384   my @rels = keys %{ { %{$rels||{} }, %{ $new_rels||{} } } };
1385   foreach my $rel (@rels) {
1386     $register = $register->{$rel} ||= {};
1387
1388     my $new_data = $new_rels->{$rel};
1389     my $data   = $rels->{$rel};
1390     @$data = [@$data] unless ( ref $data->[0] eq 'ARRAY' );
1391
1392     $self->_check_register( $register, $data->[0] )
1393       unless ( keys %$register );
1394
1395     if ( my $found = $self->_check_register( $register, $new_data ) ) {
1396       $self->_merge_result( $found, $new_data, $register );
1397     }
1398     else {
1399       push( @$data, $new_data );
1400     }
1401   }
1402   return 1;
1403 }
1404
1405 =begin
1406
1407 # two arguments: $as_proto is an arrayref of column names,
1408 # $row_ref is an arrayref of the data. If none of the row data
1409 # is defined we return undef (that's copied from the old
1410 # _collapse_result). Next we decide whether we need to collapse
1411 # the resultset (i.e. we prefetch something) or not. $collapse
1412 # indicates that. The do-while loop will run once if we do not need
1413 # to collapse the result and will run as long as _merge_result returns
1414 # a true value. It will return undef if the current added row does not
1415 # match the previous row. A bit of stashing and cursor magic is
1416 # required so that the cursor is not mixed up.
1417
1418 # "$rows" is a bit misleading. In the end, there should only be one
1419 # element in this arrayref. 
1420
1421 sub _collapse_result {
1422     my ( $self, $as_proto, $row_ref ) = @_;
1423     my $has_def;
1424     for (@$row_ref) {
1425         if ( defined $_ ) {
1426             $has_def++;
1427             last;
1428         }
1429     }
1430     return undef unless $has_def;
1431
1432     my $collapse = $self->_resolved_attrs->{collapse};
1433     my $rows     = [];
1434     my @row      = @$row_ref;
1435     do {
1436         my $i = 0;
1437         my $row = { map { $_ => $row[ $i++ ] } @$as_proto };
1438         $row = $self->result_source->_parse_row($row, $collapse);
1439         unless ( scalar @$rows ) {
1440             push( @$rows, $row );
1441         }
1442         $collapse = undef unless ( $self->_merge_result( $rows, $row ) );
1443       } while (
1444         $collapse
1445         && do { @row = $self->cursor->next; $self->{stashed_row} = \@row if @row; }
1446       );
1447
1448     return $rows->[0];
1449
1450 }
1451
1452 # _merge_result accepts an arrayref of rows objects (again, an arrayref of two elements)
1453 # and a row object which should be merged into the first object.
1454 # First we try to find out whether $row is already in $rows. If this is the case
1455 # we try to merge them by iteration through their relationship data. We call
1456 # _merge_result again on them, so they get merged.
1457
1458 # If we don't find the $row in $rows, we append it to $rows and return undef.
1459 # _merge_result returns 1 otherwise (i.e. $row has been found in $rows).
1460
1461 sub _merge_result {
1462     my ( $self, $rows, $row ) = @_;
1463     my ( $columns, $rels ) = @$row;
1464     my $found = undef;
1465     foreach my $seen (@$rows) {
1466         my $match = 1;
1467         foreach my $column ( keys %$columns ) {
1468             if (   defined $seen->[0]->{$column} ^ defined $columns->{$column}
1469                 or defined $columns->{$column}
1470                 && $seen->[0]->{$column} ne $columns->{$column} )
1471             {
1472
1473                 $match = 0;
1474                 last;
1475             }
1476         }
1477         if ($match) {
1478             $found = $seen;
1479             last;
1480         }
1481     }
1482     if ($found) {
1483         foreach my $rel ( keys %$rels ) {
1484             my $old_rows = $found->[1]->{$rel};
1485             $self->_merge_result(
1486                 ref $found->[1]->{$rel}->[0] eq 'HASH' ? [ $found->[1]->{$rel} ]
1487                 : $found->[1]->{$rel},
1488                 ref $rels->{$rel}->[0] eq 'HASH' ? [ $rels->{$rel}->[0], $rels->{$rel}->[1] ]
1489                 : $rels->{$rel}->[0]
1490             );
1491
1492   my $attrs = $self->_resolved_attrs;
1493   my ($keep_collapsing, $set_ident) = @{$attrs}{qw/collapse _collapse_ident/};
1494
1495   # FIXME this is temporary, need to calculate in _resolved_attrs
1496   $set_ident ||= { me => [ $self->result_source->_pri_cols ], pref => {} };
1497
1498   my @cur_row = @$row_ref;
1499   my (@to_collapse, $last_ident);
1500
1501   do {
1502     my $row_hr = { map { $as_proto->[$_] => $cur_row[$_] } (0 .. $#$as_proto) };
1503
1504     # see if we are switching to another object
1505     # this can be turned off and things will still work
1506     # since _merge_prefetch knows about _collapse_ident
1507 #    my $cur_ident = [ @{$row_hr}{@$set_ident} ];
1508     my $cur_ident = [];
1509     $last_ident ||= $cur_ident;
1510
1511 #    if ($keep_collapsing = Test::Deep::eq_deeply ($cur_ident, $last_ident)) {
1512 #      push @to_collapse, $self->result_source->_parse_row (
1513 #        $row_hr,
1514 #      );
1515 #    }
1516   } while (
1517     $keep_collapsing
1518       &&
1519     do { @cur_row = $self->cursor->next; $self->{stashed_row} = \@cur_row if @cur_row; }
1520   );
1521
1522   die Dumper \@to_collapse;
1523
1524
1525   # attempt collapse all rows with same collapse identity
1526   if (@to_collapse > 1) {
1527     my @collapsed;
1528     while (@to_collapse) {
1529       $self->_merge_result(\@collapsed, shift @to_collapse);
1530     }
1531     @to_collapse = @collapsed;
1532   }
1533
1534   # still didn't fully collapse
1535   $self->throw_exception ('Resultset collapse failed (theoretically impossible). Maybe a wrong collapse_ident...?')
1536     if (@to_collapse > 1);
1537
1538   return $to_collapse[0];
1539 }
1540
1541
1542 # two arguments: $as_proto is an arrayref of 'as' column names,
1543 # $row_ref is an arrayref of the data. The do-while loop will run
1544 # once if we do not need to collapse the result and will run as long as
1545 # _merge_result returns a true value. It will return undef if the
1546 # current added row does not match the previous row, which in turn
1547 # means we need to stash the row for the subsequent ->next call
1548 sub _collapse_result {
1549   my ( $self, $as_proto, $row_ref ) = @_;
1550
1551   my $attrs = $self->_resolved_attrs;
1552   my ($keep_collapsing, $set_ident) = @{$attrs}{qw/collapse _collapse_ident/};
1553
1554   die Dumper [$as_proto, $row_ref, $keep_collapsing, $set_ident ];
1555
1556
1557   my @cur_row = @$row_ref;
1558   my (@to_collapse, $last_ident);
1559
1560   do {
1561     my $row_hr = { map { $as_proto->[$_] => $cur_row[$_] } (0 .. $#$as_proto) };
1562
1563     # see if we are switching to another object
1564     # this can be turned off and things will still work
1565     # since _merge_prefetch knows about _collapse_ident
1566 #    my $cur_ident = [ @{$row_hr}{@$set_ident} ];
1567     my $cur_ident = [];
1568     $last_ident ||= $cur_ident;
1569
1570 #    if ($keep_collapsing = eq_deeply ($cur_ident, $last_ident)) {
1571 #      push @to_collapse, $self->result_source->_parse_row (
1572 #        $row_hr,
1573 #      );
1574 #    }
1575   } while (
1576     $keep_collapsing
1577       &&
1578     do { @cur_row = $self->cursor->next; $self->{stashed_row} = \@cur_row if @cur_row; }
1579   );
1580
1581   # attempt collapse all rows with same collapse identity
1582 }
1583 =cut
1584
1585 # Takes an arrayref of me/pref pairs and a new me/pref pair that should
1586 # be merged on a preexisting matching me (or should be pushed into $merged
1587 # as a new me/pref pair for further invocations). It should be possible to
1588 # use this function to collapse complete ->all results,  provided _collapse_result() is adjusted
1589 # to provide everything to this sub not to barf when $merged contains more than one 
1590 # arrayref)
1591 sub _merge_prefetch {
1592   my ($self, $merged, $next_row) = @_;
1593
1594   unless (@$merged) {
1595     push @$merged, $next_row;
1596     return;
1597   }
1598
1599 }
1600
1601 =head2 result_source
1602
1603 =over 4
1604
1605 =item Arguments: $result_source?
1606
1607 =item Return Value: $result_source
1608
1609 =back
1610
1611 An accessor for the primary ResultSource object from which this ResultSet
1612 is derived.
1613
1614 =head2 result_class
1615
1616 =over 4
1617
1618 =item Arguments: $result_class?
1619
1620 =item Return Value: $result_class
1621
1622 =back
1623
1624 An accessor for the class to use when creating row objects. Defaults to
1625 C<< result_source->result_class >> - which in most cases is the name of the
1626 L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class.
1627
1628 Note that changing the result_class will also remove any components
1629 that were originally loaded in the source class via
1630 L<DBIx::Class::ResultSource/load_components>. Any overloaded methods
1631 in the original source class will not run.
1632
1633 =cut
1634
1635 sub result_class {
1636   my ($self, $result_class) = @_;
1637   if ($result_class) {
1638     unless (ref $result_class) { # don't fire this for an object
1639       $self->ensure_class_loaded($result_class);
1640     }
1641     $self->_result_class($result_class);
1642     # THIS LINE WOULD BE A BUG - this accessor specifically exists to
1643     # permit the user to set result class on one result set only; it only
1644     # chains if provided to search()
1645     #$self->{attrs}{result_class} = $result_class if ref $self;
1646   }
1647   $self->_result_class;
1648 }
1649
1650 =head2 count
1651
1652 =over 4
1653
1654 =item Arguments: $cond, \%attrs??
1655
1656 =item Return Value: $count
1657
1658 =back
1659
1660 Performs an SQL C<COUNT> with the same query as the resultset was built
1661 with to find the number of elements. Passing arguments is equivalent to
1662 C<< $rs->search ($cond, \%attrs)->count >>
1663
1664 =cut
1665
1666 sub count {
1667   my $self = shift;
1668   return $self->search(@_)->count if @_ and defined $_[0];
1669   return scalar @{ $self->get_cache } if $self->get_cache;
1670
1671   my $attrs = $self->_resolved_attrs_copy;
1672
1673   # this is a little optimization - it is faster to do the limit
1674   # adjustments in software, instead of a subquery
1675   my $rows = delete $attrs->{rows};
1676   my $offset = delete $attrs->{offset};
1677
1678   my $crs;
1679   if ($self->_has_resolved_attr (qw/collapse group_by/)) {
1680     $crs = $self->_count_subq_rs ($attrs);
1681   }
1682   else {
1683     $crs = $self->_count_rs ($attrs);
1684   }
1685   my $count = $crs->next;
1686
1687   $count -= $offset if $offset;
1688   $count = $rows if $rows and $rows < $count;
1689   $count = 0 if ($count < 0);
1690
1691   return $count;
1692 }
1693
1694 =head2 count_rs
1695
1696 =over 4
1697
1698 =item Arguments: $cond, \%attrs??
1699
1700 =item Return Value: $count_rs
1701
1702 =back
1703
1704 Same as L</count> but returns a L<DBIx::Class::ResultSetColumn> object.
1705 This can be very handy for subqueries:
1706
1707   ->search( { amount => $some_rs->count_rs->as_query } )
1708
1709 As with regular resultsets the SQL query will be executed only after
1710 the resultset is accessed via L</next> or L</all>. That would return
1711 the same single value obtainable via L</count>.
1712
1713 =cut
1714
1715 sub count_rs {
1716   my $self = shift;
1717   return $self->search(@_)->count_rs if @_;
1718
1719   # this may look like a lack of abstraction (count() does about the same)
1720   # but in fact an _rs *must* use a subquery for the limits, as the
1721   # software based limiting can not be ported if this $rs is to be used
1722   # in a subquery itself (i.e. ->as_query)
1723   if ($self->_has_resolved_attr (qw/collapse group_by offset rows/)) {
1724     return $self->_count_subq_rs;
1725   }
1726   else {
1727     return $self->_count_rs;
1728   }
1729 }
1730
1731 #
1732 # returns a ResultSetColumn object tied to the count query
1733 #
1734 sub _count_rs {
1735   my ($self, $attrs) = @_;
1736
1737   my $rsrc = $self->result_source;
1738   $attrs ||= $self->_resolved_attrs;
1739
1740   my $tmp_attrs = { %$attrs };
1741   # take off any limits, record_filter is cdbi, and no point of ordering nor locking a count
1742   delete @{$tmp_attrs}{qw/rows offset order_by record_filter for/};
1743
1744   # overwrite the selector (supplied by the storage)
1745   $tmp_attrs->{select} = $rsrc->storage->_count_select ($rsrc, $attrs);
1746   $tmp_attrs->{as} = 'count';
1747   delete @{$tmp_attrs}{qw/columns/};
1748
1749   my $tmp_rs = $rsrc->resultset_class->new($rsrc, $tmp_attrs)->get_column ('count');
1750
1751   return $tmp_rs;
1752 }
1753
1754 #
1755 # same as above but uses a subquery
1756 #
1757 sub _count_subq_rs {
1758   my ($self, $attrs) = @_;
1759
1760   my $rsrc = $self->result_source;
1761   $attrs ||= $self->_resolved_attrs;
1762
1763   my $sub_attrs = { %$attrs };
1764   # extra selectors do not go in the subquery and there is no point of ordering it, nor locking it
1765   delete @{$sub_attrs}{qw/collapse columns as select _prefetch_selector_range order_by for/};
1766
1767   # if we multi-prefetch we group_by something unique, as this is what we would
1768   # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless
1769   if ( $attrs->{collapse}  ) {
1770     $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } @{
1771       $rsrc->_identifying_column_set || $self->throw_exception(
1772         'Unable to construct a unique group_by criteria properly collapsing the '
1773       . 'has_many prefetch before count()'
1774       );
1775     } ]
1776   }
1777
1778   # Calculate subquery selector
1779   if (my $g = $sub_attrs->{group_by}) {
1780
1781     my $sql_maker = $rsrc->storage->sql_maker;
1782
1783     # necessary as the group_by may refer to aliased functions
1784     my $sel_index;
1785     for my $sel (@{$attrs->{select}}) {
1786       $sel_index->{$sel->{-as}} = $sel
1787         if (ref $sel eq 'HASH' and $sel->{-as});
1788     }
1789
1790     # anything from the original select mentioned on the group-by needs to make it to the inner selector
1791     # also look for named aggregates referred in the having clause
1792     # having often contains scalarrefs - thus parse it out entirely
1793     my @parts = @$g;
1794     if ($attrs->{having}) {
1795       local $sql_maker->{having_bind};
1796       local $sql_maker->{quote_char} = $sql_maker->{quote_char};
1797       local $sql_maker->{name_sep} = $sql_maker->{name_sep};
1798       unless (defined $sql_maker->{quote_char} and length $sql_maker->{quote_char}) {
1799         $sql_maker->{quote_char} = [ "\x00", "\xFF" ];
1800         # if we don't unset it we screw up retarded but unfortunately working
1801         # 'MAX(foo.bar)' => { '>', 3 }
1802         $sql_maker->{name_sep} = '';
1803       }
1804
1805       my ($lquote, $rquote, $sep) = map { quotemeta $_ } ($sql_maker->_quote_chars, $sql_maker->name_sep);
1806
1807       my $sql = $sql_maker->_parse_rs_attrs ({ having => $attrs->{having} });
1808
1809       # search for both a proper quoted qualified string, for a naive unquoted scalarref
1810       # and if all fails for an utterly naive quoted scalar-with-function
1811       while ($sql =~ /
1812         $rquote $sep $lquote (.+?) $rquote
1813           |
1814         [\s,] \w+ \. (\w+) [\s,]
1815           |
1816         [\s,] $lquote (.+?) $rquote [\s,]
1817       /gx) {
1818         push @parts, ($1 || $2 || $3);  # one of them matched if we got here
1819       }
1820     }
1821
1822     for (@parts) {
1823       my $colpiece = $sel_index->{$_} || $_;
1824
1825       # unqualify join-based group_by's. Arcane but possible query
1826       # also horrible horrible hack to alias a column (not a func.)
1827       # (probably need to introduce SQLA syntax)
1828       if ($colpiece =~ /\./ && $colpiece !~ /^$attrs->{alias}\./) {
1829         my $as = $colpiece;
1830         $as =~ s/\./__/;
1831         $colpiece = \ sprintf ('%s AS %s', map { $sql_maker->_quote ($_) } ($colpiece, $as) );
1832       }
1833       push @{$sub_attrs->{select}}, $colpiece;
1834     }
1835   }
1836   else {
1837     my @pcols = map { "$attrs->{alias}.$_" } ($rsrc->primary_columns);
1838     $sub_attrs->{select} = @pcols ? \@pcols : [ 1 ];
1839   }
1840
1841   return $rsrc->resultset_class
1842                ->new ($rsrc, $sub_attrs)
1843                 ->as_subselect_rs
1844                  ->search ({}, { columns => { count => $rsrc->storage->_count_select ($rsrc, $attrs) } })
1845                   ->get_column ('count');
1846 }
1847
1848 sub _bool {
1849   return 1;
1850 }
1851
1852 =head2 count_literal
1853
1854 =over 4
1855
1856 =item Arguments: $sql_fragment, @bind_values
1857
1858 =item Return Value: $count
1859
1860 =back
1861
1862 Counts the results in a literal query. Equivalent to calling L</search_literal>
1863 with the passed arguments, then L</count>.
1864
1865 =cut
1866
1867 sub count_literal { shift->search_literal(@_)->count; }
1868
1869 =head2 all
1870
1871 =over 4
1872
1873 =item Arguments: none
1874
1875 =item Return Value: @objects
1876
1877 =back
1878
1879 Returns all elements in the resultset.
1880
1881 =cut
1882
1883 sub all {
1884   my $self = shift;
1885   if(@_) {
1886       $self->throw_exception("all() doesn't take any arguments, you probably wanted ->search(...)->all()");
1887   }
1888
1889   if (my $c = $self->get_cache) {
1890     return @$c;
1891   }
1892
1893   my @objects;
1894
1895   if ($self->_resolved_attrs->{collapse}) {
1896     # Using $self->cursor->all is really just an optimisation.
1897     # If we're collapsing has_many prefetches it probably makes
1898     # very little difference, and this is cleaner than hacking
1899     # _construct_objects to survive the approach
1900     $self->cursor->reset;
1901     my @row = $self->cursor->next;
1902     while (@row) {
1903       push(@objects, $self->_construct_objects(@row));
1904       @row = (exists $self->{stashed_row}
1905                ? @{delete $self->{stashed_row}}
1906                : $self->cursor->next);
1907     }
1908   } else {
1909     @objects = map { $self->_construct_objects(@$_) } $self->cursor->all;
1910   }
1911
1912   $self->set_cache(\@objects) if $self->{attrs}{cache};
1913
1914   return @objects;
1915 }
1916
1917 =head2 reset
1918
1919 =over 4
1920
1921 =item Arguments: none
1922
1923 =item Return Value: $self
1924
1925 =back
1926
1927 Resets the resultset's cursor, so you can iterate through the elements again.
1928 Implicitly resets the storage cursor, so a subsequent L</next> will trigger
1929 another query.
1930
1931 =cut
1932
1933 sub reset {
1934   my ($self) = @_;
1935   delete $self->{_attrs} if exists $self->{_attrs};
1936   $self->{all_cache_position} = 0;
1937   $self->cursor->reset;
1938   return $self;
1939 }
1940
1941 =head2 first
1942
1943 =over 4
1944
1945 =item Arguments: none
1946
1947 =item Return Value: $object | undef
1948
1949 =back
1950
1951 Resets the resultset and returns an object for the first result (or C<undef>
1952 if the resultset is empty).
1953
1954 =cut
1955
1956 sub first {
1957   return $_[0]->reset->next;
1958 }
1959
1960
1961 # _rs_update_delete
1962 #
1963 # Determines whether and what type of subquery is required for the $rs operation.
1964 # If grouping is necessary either supplies its own, or verifies the current one
1965 # After all is done delegates to the proper storage method.
1966
1967 sub _rs_update_delete {
1968   my ($self, $op, $values) = @_;
1969
1970   my $cond = $self->{cond};
1971   my $rsrc = $self->result_source;
1972   my $storage = $rsrc->schema->storage;
1973
1974   my $attrs = { %{$self->_resolved_attrs} };
1975
1976   # "needs" is a strong word here - if the subquery is part of an IN clause - no point of
1977   # even adding the group_by. It will really be used only when composing a poor-man's
1978   # multicolumn-IN equivalent OR set
1979   my $needs_group_by_subq = defined $attrs->{group_by};
1980
1981   # simplify the joinmap and maybe decide if a grouping (and thus subquery) is necessary
1982   my $relation_classifications;
1983   if (ref($attrs->{from}) eq 'ARRAY') {
1984     $attrs->{from} = $storage->_prune_unused_joins ($attrs->{from}, $attrs->{select}, $cond, $attrs);
1985
1986     $relation_classifications = $storage->_resolve_aliastypes_from_select_args (
1987       [ @{$attrs->{from}}[1 .. $#{$attrs->{from}}] ],
1988       $attrs->{select},
1989       $cond,
1990       $attrs
1991     ) unless $needs_group_by_subq;  # we already know we need a group, no point of resolving them
1992   }
1993   else {
1994     $needs_group_by_subq ||= 1; # if {from} is unparseable assume the worst
1995   }
1996
1997   $needs_group_by_subq ||= exists $relation_classifications->{multiplying};
1998
1999   # if no subquery - life is easy-ish
2000   unless (
2001     $needs_group_by_subq
2002       or
2003     keys %$relation_classifications # if any joins at all - need to wrap a subq
2004       or
2005     $self->_has_resolved_attr(qw/rows offset/) # limits call for a subq
2006   ) {
2007     # Most databases do not allow aliasing of tables in UPDATE/DELETE. Thus
2008     # a condition containing 'me' or other table prefixes will not work
2009     # at all. What this code tries to do (badly) is to generate a condition
2010     # with the qualifiers removed, by exploiting the quote mechanism of sqla
2011     #
2012     # this is atrocious and should be replaced by normal sqla introspection
2013     # one sunny day
2014     my ($sql, @bind) = do {
2015       my $sqla = $rsrc->storage->sql_maker;
2016       local $sqla->{_dequalify_idents} = 1;
2017       $sqla->_recurse_where($self->{cond});
2018     } if $self->{cond};
2019
2020     return $rsrc->storage->$op(
2021       $rsrc,
2022       $op eq 'update' ? $values : (),
2023       $self->{cond} ? \[$sql, @bind] : (),
2024     );
2025   }
2026
2027   # we got this far - means it is time to wrap a subquery
2028   my $idcols = $rsrc->_identifying_column_set || $self->throw_exception(
2029     sprintf(
2030       "Unable to perform complex resultset %s() without an identifying set of columns on source '%s'",
2031       $op,
2032       $rsrc->source_name,
2033     )
2034   );
2035   my $existing_group_by = delete $attrs->{group_by};
2036
2037   # make a new $rs selecting only the PKs (that's all we really need for the subq)
2038   delete $attrs->{$_} for qw/collapse _collapse_order_by select _prefetch_selector_range as/;
2039   $attrs->{columns} = [ map { "$attrs->{alias}.$_" } @$idcols ];
2040   $attrs->{group_by} = \ '';  # FIXME - this is an evil hack, it causes the optimiser to kick in and throw away the LEFT joins
2041   my $subrs = (ref $self)->new($rsrc, $attrs);
2042
2043   if (@$idcols == 1) {
2044     return $storage->$op (
2045       $rsrc,
2046       $op eq 'update' ? $values : (),
2047       { $idcols->[0] => { -in => $subrs->as_query } },
2048     );
2049   }
2050   elsif ($storage->_use_multicolumn_in) {
2051     # This is hideously ugly, but SQLA does not understand multicol IN expressions
2052     my $sql_maker = $storage->sql_maker;
2053     my ($sql, @bind) = @${$subrs->as_query};
2054     $sql = sprintf ('(%s) IN %s', # the as_query already comes with a set of parenthesis
2055       join (', ', map { $sql_maker->_quote ($_) } @$idcols),
2056       $sql,
2057     );
2058
2059     return $storage->$op (
2060       $rsrc,
2061       $op eq 'update' ? $values : (),
2062       \[$sql, @bind],
2063     );
2064   }
2065   else {
2066     # if all else fails - get all primary keys and operate over a ORed set
2067     # wrap in a transaction for consistency
2068     # this is where the group_by starts to matter
2069     my $subq_group_by;
2070     if ($needs_group_by_subq) {
2071       $subq_group_by = $attrs->{columns};
2072
2073       # make sure if there is a supplied group_by it matches the columns compiled above
2074       # perfectly. Anything else can not be sanely executed on most databases so croak
2075       # right then and there
2076       if ($existing_group_by) {
2077         my @current_group_by = map
2078           { $_ =~ /\./ ? $_ : "$attrs->{alias}.$_" }
2079           @$existing_group_by
2080         ;
2081
2082         if (
2083           join ("\x00", sort @current_group_by)
2084             ne
2085           join ("\x00", sort @$subq_group_by )
2086         ) {
2087           $self->throw_exception (
2088             "You have just attempted a $op operation on a resultset which does group_by"
2089             . ' on columns other than the primary keys, while DBIC internally needs to retrieve'
2090             . ' the primary keys in a subselect. All sane RDBMS engines do not support this'
2091             . ' kind of queries. Please retry the operation with a modified group_by or'
2092             . ' without using one at all.'
2093           );
2094         }
2095       }
2096     }
2097
2098     my $guard = $storage->txn_scope_guard;
2099
2100     my @op_condition;
2101     for my $row ($subrs->search({}, { group_by => $subq_group_by })->cursor->all) {
2102       push @op_condition, { map
2103         { $idcols->[$_] => $row->[$_] }
2104         (0 .. $#$idcols)
2105       };
2106     }
2107
2108     my $res = $storage->$op (
2109       $rsrc,
2110       $op eq 'update' ? $values : (),
2111       \@op_condition,
2112     );
2113
2114     $guard->commit;
2115
2116     return $res;
2117   }
2118 }
2119
2120 =head2 update
2121
2122 =over 4
2123
2124 =item Arguments: \%values
2125
2126 =item Return Value: $storage_rv
2127
2128 =back
2129
2130 Sets the specified columns in the resultset to the supplied values in a
2131 single query. Note that this will not run any accessor/set_column/update
2132 triggers, nor will it update any row object instances derived from this
2133 resultset (this includes the contents of the L<resultset cache|/set_cache>
2134 if any). See L</update_all> if you need to execute any on-update
2135 triggers or cascades defined either by you or a
2136 L<result component|DBIx::Class::Manual::Component/WHAT IS A COMPONENT>.
2137
2138 The return value is a pass through of what the underlying
2139 storage backend returned, and may vary. See L<DBI/execute> for the most
2140 common case.
2141
2142 =head3 CAVEAT
2143
2144 Note that L</update> does not process/deflate any of the values passed in.
2145 This is unlike the corresponding L<DBIx::Class::Row/update>. The user must
2146 ensure manually that any value passed to this method will stringify to
2147 something the RDBMS knows how to deal with. A notable example is the
2148 handling of L<DateTime> objects, for more info see:
2149 L<DBIx::Class::Manual::Cookbook/Formatting DateTime objects in queries>.
2150
2151 =cut
2152
2153 sub update {
2154   my ($self, $values) = @_;
2155   $self->throw_exception('Values for update must be a hash')
2156     unless ref $values eq 'HASH';
2157
2158   return $self->_rs_update_delete ('update', $values);
2159 }
2160
2161 =head2 update_all
2162
2163 =over 4
2164
2165 =item Arguments: \%values
2166
2167 =item Return Value: 1
2168
2169 =back
2170
2171 Fetches all objects and updates them one at a time via
2172 L<DBIx::Class::Row/update>. Note that C<update_all> will run DBIC defined
2173 triggers, while L</update> will not.
2174
2175 =cut
2176
2177 sub update_all {
2178   my ($self, $values) = @_;
2179   $self->throw_exception('Values for update_all must be a hash')
2180     unless ref $values eq 'HASH';
2181
2182   my $guard = $self->result_source->schema->txn_scope_guard;
2183   $_->update({%$values}) for $self->all;  # shallow copy - update will mangle it
2184   $guard->commit;
2185   return 1;
2186 }
2187
2188 =head2 delete
2189
2190 =over 4
2191
2192 =item Arguments: none
2193
2194 =item Return Value: $storage_rv
2195
2196 =back
2197
2198 Deletes the rows matching this resultset in a single query. Note that this
2199 will not run any delete triggers, nor will it alter the
2200 L<in_storage|DBIx::Class::Row/in_storage> status of any row object instances
2201 derived from this resultset (this includes the contents of the
2202 L<resultset cache|/set_cache> if any). See L</delete_all> if you need to
2203 execute any on-delete triggers or cascades defined either by you or a
2204 L<result component|DBIx::Class::Manual::Component/WHAT IS A COMPONENT>.
2205
2206 The return value is a pass through of what the underlying storage backend
2207 returned, and may vary. See L<DBI/execute> for the most common case.
2208
2209 =cut
2210
2211 sub delete {
2212   my $self = shift;
2213   $self->throw_exception('delete does not accept any arguments')
2214     if @_;
2215
2216   return $self->_rs_update_delete ('delete');
2217 }
2218
2219 =head2 delete_all
2220
2221 =over 4
2222
2223 =item Arguments: none
2224
2225 =item Return Value: 1
2226
2227 =back
2228
2229 Fetches all objects and deletes them one at a time via
2230 L<DBIx::Class::Row/delete>. Note that C<delete_all> will run DBIC defined
2231 triggers, while L</delete> will not.
2232
2233 =cut
2234
2235 sub delete_all {
2236   my $self = shift;
2237   $self->throw_exception('delete_all does not accept any arguments')
2238     if @_;
2239
2240   my $guard = $self->result_source->schema->txn_scope_guard;
2241   $_->delete for $self->all;
2242   $guard->commit;
2243   return 1;
2244 }
2245
2246 =head2 populate
2247
2248 =over 4
2249
2250 =item Arguments: \@data;
2251
2252 =back
2253
2254 Accepts either an arrayref of hashrefs or alternatively an arrayref of arrayrefs.
2255 For the arrayref of hashrefs style each hashref should be a structure suitable
2256 for submitting to a $resultset->create(...) method.
2257
2258 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
2259 to insert the data, as this is a faster method.
2260
2261 Otherwise, each set of data is inserted into the database using
2262 L<DBIx::Class::ResultSet/create>, and the resulting objects are
2263 accumulated into an array. The array itself, or an array reference
2264 is returned depending on scalar or list context.
2265
2266 Example:  Assuming an Artist Class that has many CDs Classes relating:
2267
2268   my $Artist_rs = $schema->resultset("Artist");
2269
2270   ## Void Context Example
2271   $Artist_rs->populate([
2272      { artistid => 4, name => 'Manufactured Crap', cds => [
2273         { title => 'My First CD', year => 2006 },
2274         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
2275       ],
2276      },
2277      { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
2278         { title => 'My parents sold me to a record company', year => 2005 },
2279         { title => 'Why Am I So Ugly?', year => 2006 },
2280         { title => 'I Got Surgery and am now Popular', year => 2007 }
2281       ],
2282      },
2283   ]);
2284
2285   ## Array Context Example
2286   my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
2287     { name => "Artist One"},
2288     { name => "Artist Two"},
2289     { name => "Artist Three", cds=> [
2290     { title => "First CD", year => 2007},
2291     { title => "Second CD", year => 2008},
2292   ]}
2293   ]);
2294
2295   print $ArtistOne->name; ## response is 'Artist One'
2296   print $ArtistThree->cds->count ## reponse is '2'
2297
2298 For the arrayref of arrayrefs style,  the first element should be a list of the
2299 fieldsnames to which the remaining elements are rows being inserted.  For
2300 example:
2301
2302   $Arstist_rs->populate([
2303     [qw/artistid name/],
2304     [100, 'A Formally Unknown Singer'],
2305     [101, 'A singer that jumped the shark two albums ago'],
2306     [102, 'An actually cool singer'],
2307   ]);
2308
2309 Please note an important effect on your data when choosing between void and
2310 wantarray context. Since void context goes straight to C<insert_bulk> in
2311 L<DBIx::Class::Storage::DBI> this will skip any component that is overriding
2312 C<insert>.  So if you are using something like L<DBIx-Class-UUIDColumns> to
2313 create primary keys for you, you will find that your PKs are empty.  In this
2314 case you will have to use the wantarray context in order to create those
2315 values.
2316
2317 =cut
2318
2319 sub populate {
2320   my $self = shift;
2321
2322   # cruft placed in standalone method
2323   my $data = $self->_normalize_populate_args(@_);
2324
2325   return unless @$data;
2326
2327   if(defined wantarray) {
2328     my @created;
2329     foreach my $item (@$data) {
2330       push(@created, $self->create($item));
2331     }
2332     return wantarray ? @created : \@created;
2333   }
2334   else {
2335     my $first = $data->[0];
2336
2337     # if a column is a registered relationship, and is a non-blessed hash/array, consider
2338     # it relationship data
2339     my (@rels, @columns);
2340     my $rsrc = $self->result_source;
2341     my $rels = { map { $_ => $rsrc->relationship_info($_) } $rsrc->relationships };
2342     for (keys %$first) {
2343       my $ref = ref $first->{$_};
2344       $rels->{$_} && ($ref eq 'ARRAY' or $ref eq 'HASH')
2345         ? push @rels, $_
2346         : push @columns, $_
2347       ;
2348     }
2349
2350     my @pks = $rsrc->primary_columns;
2351
2352     ## do the belongs_to relationships
2353     foreach my $index (0..$#$data) {
2354
2355       # delegate to create() for any dataset without primary keys with specified relationships
2356       if (grep { !defined $data->[$index]->{$_} } @pks ) {
2357         for my $r (@rels) {
2358           if (grep { ref $data->[$index]{$r} eq $_ } qw/HASH ARRAY/) {  # a related set must be a HASH or AoH
2359             my @ret = $self->populate($data);
2360             return;
2361           }
2362         }
2363       }
2364
2365       foreach my $rel (@rels) {
2366         next unless ref $data->[$index]->{$rel} eq "HASH";
2367         my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
2368         my ($reverse_relname, $reverse_relinfo) = %{$rsrc->reverse_relationship_info($rel)};
2369         my $related = $result->result_source->_resolve_condition(
2370           $reverse_relinfo->{cond},
2371           $self,
2372           $result,
2373           $rel,
2374         );
2375
2376         delete $data->[$index]->{$rel};
2377         $data->[$index] = {%{$data->[$index]}, %$related};
2378
2379         push @columns, keys %$related if $index == 0;
2380       }
2381     }
2382
2383     ## inherit the data locked in the conditions of the resultset
2384     my ($rs_data) = $self->_merge_with_rscond({});
2385     delete @{$rs_data}{@columns};
2386     my @inherit_cols = keys %$rs_data;
2387     my @inherit_data = values %$rs_data;
2388
2389     ## do bulk insert on current row
2390     $rsrc->storage->insert_bulk(
2391       $rsrc,
2392       [@columns, @inherit_cols],
2393       [ map { [ @$_{@columns}, @inherit_data ] } @$data ],
2394     );
2395
2396     ## do the has_many relationships
2397     foreach my $item (@$data) {
2398
2399       my $main_row;
2400
2401       foreach my $rel (@rels) {
2402         next unless ref $item->{$rel} eq "ARRAY" && @{ $item->{$rel} };
2403
2404         $main_row ||= $self->new_result({map { $_ => $item->{$_} } @pks});
2405
2406         my $child = $main_row->$rel;
2407
2408         my $related = $child->result_source->_resolve_condition(
2409           $rels->{$rel}{cond},
2410           $child,
2411           $main_row,
2412           $rel,
2413         );
2414
2415         my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
2416         my @populate = map { {%$_, %$related} } @rows_to_add;
2417
2418         $child->populate( \@populate );
2419       }
2420     }
2421   }
2422 }
2423
2424
2425 # populate() argumnets went over several incarnations
2426 # What we ultimately support is AoH
2427 sub _normalize_populate_args {
2428   my ($self, $arg) = @_;
2429
2430   if (ref $arg eq 'ARRAY') {
2431     if (!@$arg) {
2432       return [];
2433     }
2434     elsif (ref $arg->[0] eq 'HASH') {
2435       return $arg;
2436     }
2437     elsif (ref $arg->[0] eq 'ARRAY') {
2438       my @ret;
2439       my @colnames = @{$arg->[0]};
2440       foreach my $values (@{$arg}[1 .. $#$arg]) {
2441         push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
2442       }
2443       return \@ret;
2444     }
2445   }
2446
2447   $self->throw_exception('Populate expects an arrayref of hashrefs or arrayref of arrayrefs');
2448 }
2449
2450 =head2 pager
2451
2452 =over 4
2453
2454 =item Arguments: none
2455
2456 =item Return Value: $pager
2457
2458 =back
2459
2460 Return Value a L<Data::Page> object for the current resultset. Only makes
2461 sense for queries with a C<page> attribute.
2462
2463 To get the full count of entries for a paged resultset, call
2464 C<total_entries> on the L<Data::Page> object.
2465
2466 =cut
2467
2468 sub pager {
2469   my ($self) = @_;
2470
2471   return $self->{pager} if $self->{pager};
2472
2473   my $attrs = $self->{attrs};
2474   if (!defined $attrs->{page}) {
2475     $self->throw_exception("Can't create pager for non-paged rs");
2476   }
2477   elsif ($attrs->{page} <= 0) {
2478     $self->throw_exception('Invalid page number (page-numbers are 1-based)');
2479   }
2480   $attrs->{rows} ||= 10;
2481
2482   # throw away the paging flags and re-run the count (possibly
2483   # with a subselect) to get the real total count
2484   my $count_attrs = { %$attrs };
2485   delete $count_attrs->{$_} for qw/rows offset page pager/;
2486
2487   my $total_rs = (ref $self)->new($self->result_source, $count_attrs);
2488
2489   require DBIx::Class::ResultSet::Pager;
2490   return $self->{pager} = DBIx::Class::ResultSet::Pager->new(
2491     sub { $total_rs->count },  #lazy-get the total
2492     $attrs->{rows},
2493     $self->{attrs}{page},
2494   );
2495 }
2496
2497 =head2 page
2498
2499 =over 4
2500
2501 =item Arguments: $page_number
2502
2503 =item Return Value: $rs
2504
2505 =back
2506
2507 Returns a resultset for the $page_number page of the resultset on which page
2508 is called, where each page contains a number of rows equal to the 'rows'
2509 attribute set on the resultset (10 by default).
2510
2511 =cut
2512
2513 sub page {
2514   my ($self, $page) = @_;
2515   return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
2516 }
2517
2518 =head2 new_result
2519
2520 =over 4
2521
2522 =item Arguments: \%vals
2523
2524 =item Return Value: $rowobject
2525
2526 =back
2527
2528 Creates a new row object in the resultset's result class and returns
2529 it. The row is not inserted into the database at this point, call
2530 L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
2531 will tell you whether the row object has been inserted or not.
2532
2533 Passes the hashref of input on to L<DBIx::Class::Row/new>.
2534
2535 =cut
2536
2537 sub new_result {
2538   my ($self, $values) = @_;
2539   $self->throw_exception( "new_result needs a hash" )
2540     unless (ref $values eq 'HASH');
2541
2542   my ($merged_cond, $cols_from_relations) = $self->_merge_with_rscond($values);
2543
2544   my %new = (
2545     %$merged_cond,
2546     @$cols_from_relations
2547       ? (-cols_from_relations => $cols_from_relations)
2548       : (),
2549     -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
2550   );
2551
2552   return $self->result_class->new(\%new);
2553 }
2554
2555 # _merge_with_rscond
2556 #
2557 # Takes a simple hash of K/V data and returns its copy merged with the
2558 # condition already present on the resultset. Additionally returns an
2559 # arrayref of value/condition names, which were inferred from related
2560 # objects (this is needed for in-memory related objects)
2561 sub _merge_with_rscond {
2562   my ($self, $data) = @_;
2563
2564   my (%new_data, @cols_from_relations);
2565
2566   my $alias = $self->{attrs}{alias};
2567
2568   if (! defined $self->{cond}) {
2569     # just massage $data below
2570   }
2571   elsif ($self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
2572     %new_data = %{ $self->{attrs}{related_objects} || {} };  # nothing might have been inserted yet
2573     @cols_from_relations = keys %new_data;
2574   }
2575   elsif (ref $self->{cond} ne 'HASH') {
2576     $self->throw_exception(
2577       "Can't abstract implicit construct, resultset condition not a hash"
2578     );
2579   }
2580   else {
2581     # precendence must be given to passed values over values inherited from
2582     # the cond, so the order here is important.
2583     my $collapsed_cond = $self->_collapse_cond($self->{cond});
2584     my %implied = %{$self->_remove_alias($collapsed_cond, $alias)};
2585
2586     while ( my($col, $value) = each %implied ) {
2587       my $vref = ref $value;
2588       if (
2589         $vref eq 'HASH'
2590           and
2591         keys(%$value) == 1
2592           and
2593         (keys %$value)[0] eq '='
2594       ) {
2595         $new_data{$col} = $value->{'='};
2596       }
2597       elsif( !$vref or $vref eq 'SCALAR' or blessed($value) ) {
2598         $new_data{$col} = $value;
2599       }
2600     }
2601   }
2602
2603   %new_data = (
2604     %new_data,
2605     %{ $self->_remove_alias($data, $alias) },
2606   );
2607
2608   return (\%new_data, \@cols_from_relations);
2609 }
2610
2611 # _has_resolved_attr
2612 #
2613 # determines if the resultset defines at least one
2614 # of the attributes supplied
2615 #
2616 # used to determine if a subquery is neccessary
2617 #
2618 # supports some virtual attributes:
2619 #   -join
2620 #     This will scan for any joins being present on the resultset.
2621 #     It is not a mere key-search but a deep inspection of {from}
2622 #
2623
2624 sub _has_resolved_attr {
2625   my ($self, @attr_names) = @_;
2626
2627   my $attrs = $self->_resolved_attrs;
2628
2629   my %extra_checks;
2630
2631   for my $n (@attr_names) {
2632     if (grep { $n eq $_ } (qw/-join/) ) {
2633       $extra_checks{$n}++;
2634       next;
2635     }
2636
2637     my $attr =  $attrs->{$n};
2638
2639     next if not defined $attr;
2640
2641     if (ref $attr eq 'HASH') {
2642       return 1 if keys %$attr;
2643     }
2644     elsif (ref $attr eq 'ARRAY') {
2645       return 1 if @$attr;
2646     }
2647     else {
2648       return 1 if $attr;
2649     }
2650   }
2651
2652   # a resolved join is expressed as a multi-level from
2653   return 1 if (
2654     $extra_checks{-join}
2655       and
2656     ref $attrs->{from} eq 'ARRAY'
2657       and
2658     @{$attrs->{from}} > 1
2659   );
2660
2661   return 0;
2662 }
2663
2664 # _collapse_cond
2665 #
2666 # Recursively collapse the condition.
2667
2668 sub _collapse_cond {
2669   my ($self, $cond, $collapsed) = @_;
2670
2671   $collapsed ||= {};
2672
2673   if (ref $cond eq 'ARRAY') {
2674     foreach my $subcond (@$cond) {
2675       next unless ref $subcond;  # -or
2676       $collapsed = $self->_collapse_cond($subcond, $collapsed);
2677     }
2678   }
2679   elsif (ref $cond eq 'HASH') {
2680     if (keys %$cond and (keys %$cond)[0] eq '-and') {
2681       foreach my $subcond (@{$cond->{-and}}) {
2682         $collapsed = $self->_collapse_cond($subcond, $collapsed);
2683       }
2684     }
2685     else {
2686       foreach my $col (keys %$cond) {
2687         my $value = $cond->{$col};
2688         $collapsed->{$col} = $value;
2689       }
2690     }
2691   }
2692
2693   return $collapsed;
2694 }
2695
2696 # _remove_alias
2697 #
2698 # Remove the specified alias from the specified query hash. A copy is made so
2699 # the original query is not modified.
2700
2701 sub _remove_alias {
2702   my ($self, $query, $alias) = @_;
2703
2704   my %orig = %{ $query || {} };
2705   my %unaliased;
2706
2707   foreach my $key (keys %orig) {
2708     if ($key !~ /\./) {
2709       $unaliased{$key} = $orig{$key};
2710       next;
2711     }
2712     $unaliased{$1} = $orig{$key}
2713       if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
2714   }
2715
2716   return \%unaliased;
2717 }
2718
2719 =head2 as_query
2720
2721 =over 4
2722
2723 =item Arguments: none
2724
2725 =item Return Value: \[ $sql, @bind ]
2726
2727 =back
2728
2729 Returns the SQL query and bind vars associated with the invocant.
2730
2731 This is generally used as the RHS for a subquery.
2732
2733 =cut
2734
2735 sub as_query {
2736   my $self = shift;
2737
2738   my $attrs = $self->_resolved_attrs_copy;
2739
2740   # For future use:
2741   #
2742   # in list ctx:
2743   # my ($sql, \@bind, \%dbi_bind_attrs) = _select_args_to_query (...)
2744   # $sql also has no wrapping parenthesis in list ctx
2745   #
2746   my $sqlbind = $self->result_source->storage
2747     ->_select_args_to_query ($attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs);
2748
2749   return $sqlbind;
2750 }
2751
2752 =head2 find_or_new
2753
2754 =over 4
2755
2756 =item Arguments: \%vals, \%attrs?
2757
2758 =item Return Value: $rowobject
2759
2760 =back
2761
2762   my $artist = $schema->resultset('Artist')->find_or_new(
2763     { artist => 'fred' }, { key => 'artists' });
2764
2765   $cd->cd_to_producer->find_or_new({ producer => $producer },
2766                                    { key => 'primary });
2767
2768 Find an existing record from this resultset using L</find>. if none exists,
2769 instantiate a new result object and return it. The object will not be saved
2770 into your storage until you call L<DBIx::Class::Row/insert> on it.
2771
2772 You most likely want this method when looking for existing rows using a unique
2773 constraint that is not the primary key, or looking for related rows.
2774
2775 If you want objects to be saved immediately, use L</find_or_create> instead.
2776
2777 B<Note>: Make sure to read the documentation of L</find> and understand the
2778 significance of the C<key> attribute, as its lack may skew your search, and
2779 subsequently result in spurious new objects.
2780
2781 B<Note>: Take care when using C<find_or_new> with a table having
2782 columns with default values that you intend to be automatically
2783 supplied by the database (e.g. an auto_increment primary key column).
2784 In normal usage, the value of such columns should NOT be included at
2785 all in the call to C<find_or_new>, even when set to C<undef>.
2786
2787 =cut
2788
2789 sub find_or_new {
2790   my $self     = shift;
2791   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
2792   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
2793   if (keys %$hash and my $row = $self->find($hash, $attrs) ) {
2794     return $row;
2795   }
2796   return $self->new_result($hash);
2797 }
2798
2799 =head2 create
2800
2801 =over 4
2802
2803 =item Arguments: \%vals
2804
2805 =item Return Value: a L<DBIx::Class::Row> $object
2806
2807 =back
2808
2809 Attempt to create a single new row or a row with multiple related rows
2810 in the table represented by the resultset (and related tables). This
2811 will not check for duplicate rows before inserting, use
2812 L</find_or_create> to do that.
2813
2814 To create one row for this resultset, pass a hashref of key/value
2815 pairs representing the columns of the table and the values you wish to
2816 store. If the appropriate relationships are set up, foreign key fields
2817 can also be passed an object representing the foreign row, and the
2818 value will be set to its primary key.
2819
2820 To create related objects, pass a hashref of related-object column values
2821 B<keyed on the relationship name>. If the relationship is of type C<multi>
2822 (L<DBIx::Class::Relationship/has_many>) - pass an arrayref of hashrefs.
2823 The process will correctly identify columns holding foreign keys, and will
2824 transparently populate them from the keys of the corresponding relation.
2825 This can be applied recursively, and will work correctly for a structure
2826 with an arbitrary depth and width, as long as the relationships actually
2827 exists and the correct column data has been supplied.
2828
2829
2830 Instead of hashrefs of plain related data (key/value pairs), you may
2831 also pass new or inserted objects. New objects (not inserted yet, see
2832 L</new>), will be inserted into their appropriate tables.
2833
2834 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
2835
2836 Example of creating a new row.
2837
2838   $person_rs->create({
2839     name=>"Some Person",
2840     email=>"somebody@someplace.com"
2841   });
2842
2843 Example of creating a new row and also creating rows in a related C<has_many>
2844 or C<has_one> resultset.  Note Arrayref.
2845
2846   $artist_rs->create(
2847      { artistid => 4, name => 'Manufactured Crap', cds => [
2848         { title => 'My First CD', year => 2006 },
2849         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
2850       ],
2851      },
2852   );
2853
2854 Example of creating a new row and also creating a row in a related
2855 C<belongs_to> resultset. Note Hashref.
2856
2857   $cd_rs->create({
2858     title=>"Music for Silly Walks",
2859     year=>2000,
2860     artist => {
2861       name=>"Silly Musician",
2862     }
2863   });
2864
2865 =over
2866
2867 =item WARNING
2868
2869 When subclassing ResultSet never attempt to override this method. Since
2870 it is a simple shortcut for C<< $self->new_result($attrs)->insert >>, a
2871 lot of the internals simply never call it, so your override will be
2872 bypassed more often than not. Override either L<new|DBIx::Class::Row/new>
2873 or L<insert|DBIx::Class::Row/insert> depending on how early in the
2874 L</create> process you need to intervene.
2875
2876 =back
2877
2878 =cut
2879
2880 sub create {
2881   my ($self, $attrs) = @_;
2882   $self->throw_exception( "create needs a hashref" )
2883     unless ref $attrs eq 'HASH';
2884   return $self->new_result($attrs)->insert;
2885 }
2886
2887 =head2 find_or_create
2888
2889 =over 4
2890
2891 =item Arguments: \%vals, \%attrs?
2892
2893 =item Return Value: $rowobject
2894
2895 =back
2896
2897   $cd->cd_to_producer->find_or_create({ producer => $producer },
2898                                       { key => 'primary' });
2899
2900 Tries to find a record based on its primary key or unique constraints; if none
2901 is found, creates one and returns that instead.
2902
2903   my $cd = $schema->resultset('CD')->find_or_create({
2904     cdid   => 5,
2905     artist => 'Massive Attack',
2906     title  => 'Mezzanine',
2907     year   => 2005,
2908   });
2909
2910 Also takes an optional C<key> attribute, to search by a specific key or unique
2911 constraint. For example:
2912
2913   my $cd = $schema->resultset('CD')->find_or_create(
2914     {
2915       artist => 'Massive Attack',
2916       title  => 'Mezzanine',
2917     },
2918     { key => 'cd_artist_title' }
2919   );
2920
2921 B<Note>: Make sure to read the documentation of L</find> and understand the
2922 significance of the C<key> attribute, as its lack may skew your search, and
2923 subsequently result in spurious row creation.
2924
2925 B<Note>: Because find_or_create() reads from the database and then
2926 possibly inserts based on the result, this method is subject to a race
2927 condition. Another process could create a record in the table after
2928 the find has completed and before the create has started. To avoid
2929 this problem, use find_or_create() inside a transaction.
2930
2931 B<Note>: Take care when using C<find_or_create> with a table having
2932 columns with default values that you intend to be automatically
2933 supplied by the database (e.g. an auto_increment primary key column).
2934 In normal usage, the value of such columns should NOT be included at
2935 all in the call to C<find_or_create>, even when set to C<undef>.
2936
2937 See also L</find> and L</update_or_create>. For information on how to declare
2938 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
2939
2940 If you need to know if an existing row was found or a new one created use
2941 L</find_or_new> and L<DBIx::Class::Row/in_storage> instead. Don't forget
2942 to call L<DBIx::Class::Row/insert> to save the newly created row to the
2943 database!
2944
2945   my $cd = $schema->resultset('CD')->find_or_new({
2946     cdid   => 5,
2947     artist => 'Massive Attack',
2948     title  => 'Mezzanine',
2949     year   => 2005,
2950   });
2951
2952   if( $cd->in_storage ) {
2953       # do some stuff
2954       $cd->insert;
2955   }
2956
2957 =cut
2958
2959 sub find_or_create {
2960   my $self     = shift;
2961   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
2962   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
2963   if (keys %$hash and my $row = $self->find($hash, $attrs) ) {
2964     return $row;
2965   }
2966   return $self->create($hash);
2967 }
2968
2969 =head2 update_or_create
2970
2971 =over 4
2972
2973 =item Arguments: \%col_values, { key => $unique_constraint }?
2974
2975 =item Return Value: $row_object
2976
2977 =back
2978
2979   $resultset->update_or_create({ col => $val, ... });
2980
2981 Like L</find_or_create>, but if a row is found it is immediately updated via
2982 C<< $found_row->update (\%col_values) >>.
2983
2984
2985 Takes an optional C<key> attribute to search on a specific unique constraint.
2986 For example:
2987
2988   # In your application
2989   my $cd = $schema->resultset('CD')->update_or_create(
2990     {
2991       artist => 'Massive Attack',
2992       title  => 'Mezzanine',
2993       year   => 1998,
2994     },
2995     { key => 'cd_artist_title' }
2996   );
2997
2998   $cd->cd_to_producer->update_or_create({
2999     producer => $producer,
3000     name => 'harry',
3001   }, {
3002     key => 'primary',
3003   });
3004
3005 B<Note>: Make sure to read the documentation of L</find> and understand the
3006 significance of the C<key> attribute, as its lack may skew your search, and
3007 subsequently result in spurious row creation.
3008
3009 B<Note>: Take care when using C<update_or_create> with a table having
3010 columns with default values that you intend to be automatically
3011 supplied by the database (e.g. an auto_increment primary key column).
3012 In normal usage, the value of such columns should NOT be included at
3013 all in the call to C<update_or_create>, even when set to C<undef>.
3014
3015 See also L</find> and L</find_or_create>. For information on how to declare
3016 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
3017
3018 If you need to know if an existing row was updated or a new one created use
3019 L</update_or_new> and L<DBIx::Class::Row/in_storage> instead. Don't forget
3020 to call L<DBIx::Class::Row/insert> to save the newly created row to the
3021 database!
3022
3023   my $cd = $schema->resultset('CD')->update_or_new(
3024     {
3025       artist => 'Massive Attack',
3026       title  => 'Mezzanine',
3027       year   => 1998,
3028     },
3029     { key => 'cd_artist_title' }
3030   );
3031
3032   if( $cd->in_storage ) {
3033       # do some stuff
3034       $cd->insert;
3035   }
3036
3037 =cut
3038
3039 sub update_or_create {
3040   my $self = shift;
3041   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
3042   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
3043
3044   my $row = $self->find($cond, $attrs);
3045   if (defined $row) {
3046     $row->update($cond);
3047     return $row;
3048   }
3049
3050   return $self->create($cond);
3051 }
3052
3053 =head2 update_or_new
3054
3055 =over 4
3056
3057 =item Arguments: \%col_values, { key => $unique_constraint }?
3058
3059 =item Return Value: $rowobject
3060
3061 =back
3062
3063   $resultset->update_or_new({ col => $val, ... });
3064
3065 Like L</find_or_new> but if a row is found it is immediately updated via
3066 C<< $found_row->update (\%col_values) >>.
3067
3068 For example:
3069
3070   # In your application
3071   my $cd = $schema->resultset('CD')->update_or_new(
3072     {
3073       artist => 'Massive Attack',
3074       title  => 'Mezzanine',
3075       year   => 1998,
3076     },
3077     { key => 'cd_artist_title' }
3078   );
3079
3080   if ($cd->in_storage) {
3081       # the cd was updated
3082   }
3083   else {
3084       # the cd is not yet in the database, let's insert it
3085       $cd->insert;
3086   }
3087
3088 B<Note>: Make sure to read the documentation of L</find> and understand the
3089 significance of the C<key> attribute, as its lack may skew your search, and
3090 subsequently result in spurious new objects.
3091
3092 B<Note>: Take care when using C<update_or_new> with a table having
3093 columns with default values that you intend to be automatically
3094 supplied by the database (e.g. an auto_increment primary key column).
3095 In normal usage, the value of such columns should NOT be included at
3096 all in the call to C<update_or_new>, even when set to C<undef>.
3097
3098 See also L</find>, L</find_or_create> and L</find_or_new>.
3099
3100 =cut
3101
3102 sub update_or_new {
3103     my $self  = shift;
3104     my $attrs = ( @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {} );
3105     my $cond  = ref $_[0] eq 'HASH' ? shift : {@_};
3106
3107     my $row = $self->find( $cond, $attrs );
3108     if ( defined $row ) {
3109         $row->update($cond);
3110         return $row;
3111     }
3112
3113     return $self->new_result($cond);
3114 }
3115
3116 =head2 get_cache
3117
3118 =over 4
3119
3120 =item Arguments: none
3121
3122 =item Return Value: \@cache_objects | undef
3123
3124 =back
3125
3126 Gets the contents of the cache for the resultset, if the cache is set.
3127
3128 The cache is populated either by using the L</prefetch> attribute to
3129 L</search> or by calling L</set_cache>.
3130
3131 =cut
3132
3133 sub get_cache {
3134   shift->{all_cache};
3135 }
3136
3137 =head2 set_cache
3138
3139 =over 4
3140
3141 =item Arguments: \@cache_objects
3142
3143 =item Return Value: \@cache_objects
3144
3145 =back
3146
3147 Sets the contents of the cache for the resultset. Expects an arrayref
3148 of objects of the same class as those produced by the resultset. Note that
3149 if the cache is set the resultset will return the cached objects rather
3150 than re-querying the database even if the cache attr is not set.
3151
3152 The contents of the cache can also be populated by using the
3153 L</prefetch> attribute to L</search>.
3154
3155 =cut
3156
3157 sub set_cache {
3158   my ( $self, $data ) = @_;
3159   $self->throw_exception("set_cache requires an arrayref")
3160       if defined($data) && (ref $data ne 'ARRAY');
3161   $self->{all_cache} = $data;
3162 }
3163
3164 =head2 clear_cache
3165
3166 =over 4
3167
3168 =item Arguments: none
3169
3170 =item Return Value: undef
3171
3172 =back
3173
3174 Clears the cache for the resultset.
3175
3176 =cut
3177
3178 sub clear_cache {
3179   shift->set_cache(undef);
3180 }
3181
3182 =head2 is_paged
3183
3184 =over 4
3185
3186 =item Arguments: none
3187
3188 =item Return Value: true, if the resultset has been paginated
3189
3190 =back
3191
3192 =cut
3193
3194 sub is_paged {
3195   my ($self) = @_;
3196   return !!$self->{attrs}{page};
3197 }
3198
3199 =head2 is_ordered
3200
3201 =over 4
3202
3203 =item Arguments: none
3204
3205 =item Return Value: true, if the resultset has been ordered with C<order_by>.
3206
3207 =back
3208
3209 =cut
3210
3211 sub is_ordered {
3212   my ($self) = @_;
3213   return scalar $self->result_source->storage->_extract_order_criteria($self->{attrs}{order_by});
3214 }
3215
3216 =head2 related_resultset
3217
3218 =over 4
3219
3220 =item Arguments: $relationship_name
3221
3222 =item Return Value: $resultset
3223
3224 =back
3225
3226 Returns a related resultset for the supplied relationship name.
3227
3228   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
3229
3230 =cut
3231
3232 sub related_resultset {
3233   my ($self, $rel) = @_;
3234
3235   $self->{related_resultsets} ||= {};
3236   return $self->{related_resultsets}{$rel} ||= do {
3237     my $rsrc = $self->result_source;
3238     my $rel_info = $rsrc->relationship_info($rel);
3239
3240     $self->throw_exception(
3241       "search_related: result source '" . $rsrc->source_name .
3242         "' has no such relationship $rel")
3243       unless $rel_info;
3244
3245     my $attrs = $self->_chain_relationship($rel);
3246
3247     my $join_count = $attrs->{seen_join}{$rel};
3248
3249     my $alias = $self->result_source->storage
3250         ->relname_to_table_alias($rel, $join_count);
3251
3252     # since this is search_related, and we already slid the select window inwards
3253     # (the select/as attrs were deleted in the beginning), we need to flip all
3254     # left joins to inner, so we get the expected results
3255     # read the comment on top of the actual function to see what this does
3256     $attrs->{from} = $rsrc->schema->storage->_inner_join_to_node ($attrs->{from}, $alias);
3257
3258
3259     #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
3260     delete @{$attrs}{qw(result_class alias)};
3261
3262     my $new_cache;
3263
3264     if (my $cache = $self->get_cache) {
3265       if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
3266         $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
3267                         @$cache ];
3268       }
3269     }
3270
3271     my $rel_source = $rsrc->related_source($rel);
3272
3273     my $new = do {
3274
3275       # The reason we do this now instead of passing the alias to the
3276       # search_rs below is that if you wrap/overload resultset on the
3277       # source you need to know what alias it's -going- to have for things
3278       # to work sanely (e.g. RestrictWithObject wants to be able to add
3279       # extra query restrictions, and these may need to be $alias.)
3280
3281       my $rel_attrs = $rel_source->resultset_attributes;
3282       local $rel_attrs->{alias} = $alias;
3283
3284       $rel_source->resultset
3285                  ->search_rs(
3286                      undef, {
3287                        %$attrs,
3288                        where => $attrs->{where},
3289                    });
3290     };
3291     $new->set_cache($new_cache) if $new_cache;
3292     $new;
3293   };
3294 }
3295
3296 =head2 current_source_alias
3297
3298 =over 4
3299
3300 =item Arguments: none
3301
3302 =item Return Value: $source_alias
3303
3304 =back
3305
3306 Returns the current table alias for the result source this resultset is built
3307 on, that will be used in the SQL query. Usually it is C<me>.
3308
3309 Currently the source alias that refers to the result set returned by a
3310 L</search>/L</find> family method depends on how you got to the resultset: it's
3311 C<me> by default, but eg. L</search_related> aliases it to the related result
3312 source name (and keeps C<me> referring to the original result set). The long
3313 term goal is to make L<DBIx::Class> always alias the current resultset as C<me>
3314 (and make this method unnecessary).
3315
3316 Thus it's currently necessary to use this method in predefined queries (see
3317 L<DBIx::Class::Manual::Cookbook/Predefined searches>) when referring to the
3318 source alias of the current result set:
3319
3320   # in a result set class
3321   sub modified_by {
3322     my ($self, $user) = @_;
3323
3324     my $me = $self->current_source_alias;
3325
3326     return $self->search({
3327       "$me.modified" => $user->id,
3328     });
3329   }
3330
3331 =cut
3332
3333 sub current_source_alias {
3334   my ($self) = @_;
3335
3336   return ($self->{attrs} || {})->{alias} || 'me';
3337 }
3338
3339 =head2 as_subselect_rs
3340
3341 =over 4
3342
3343 =item Arguments: none
3344
3345 =item Return Value: $resultset
3346
3347 =back
3348
3349 Act as a barrier to SQL symbols.  The resultset provided will be made into a
3350 "virtual view" by including it as a subquery within the from clause.  From this
3351 point on, any joined tables are inaccessible to ->search on the resultset (as if
3352 it were simply where-filtered without joins).  For example:
3353
3354  my $rs = $schema->resultset('Bar')->search({'x.name' => 'abc'},{ join => 'x' });
3355
3356  # 'x' now pollutes the query namespace
3357
3358  # So the following works as expected
3359  my $ok_rs = $rs->search({'x.other' => 1});
3360
3361  # But this doesn't: instead of finding a 'Bar' related to two x rows (abc and
3362  # def) we look for one row with contradictory terms and join in another table
3363  # (aliased 'x_2') which we never use
3364  my $broken_rs = $rs->search({'x.name' => 'def'});
3365
3366  my $rs2 = $rs->as_subselect_rs;
3367
3368  # doesn't work - 'x' is no longer accessible in $rs2, having been sealed away
3369  my $not_joined_rs = $rs2->search({'x.other' => 1});
3370
3371  # works as expected: finds a 'table' row related to two x rows (abc and def)
3372  my $correctly_joined_rs = $rs2->search({'x.name' => 'def'});
3373
3374 Another example of when one might use this would be to select a subset of
3375 columns in a group by clause:
3376
3377  my $rs = $schema->resultset('Bar')->search(undef, {
3378    group_by => [qw{ id foo_id baz_id }],
3379  })->as_subselect_rs->search(undef, {
3380    columns => [qw{ id foo_id }]
3381  });
3382
3383 In the above example normally columns would have to be equal to the group by,
3384 but because we isolated the group by into a subselect the above works.
3385
3386 =cut
3387
3388 sub as_subselect_rs {
3389   my $self = shift;
3390
3391   my $attrs = $self->_resolved_attrs;
3392
3393   my $fresh_rs = (ref $self)->new (
3394     $self->result_source
3395   );
3396
3397   # these pieces will be locked in the subquery
3398   delete $fresh_rs->{cond};
3399   delete @{$fresh_rs->{attrs}}{qw/where bind/};
3400
3401   return $fresh_rs->search( {}, {
3402     from => [{
3403       $attrs->{alias} => $self->as_query,
3404       -alias  => $attrs->{alias},
3405       -rsrc   => $self->result_source,
3406     }],
3407     alias => $attrs->{alias},
3408   });
3409 }
3410
3411 # This code is called by search_related, and makes sure there
3412 # is clear separation between the joins before, during, and
3413 # after the relationship. This information is needed later
3414 # in order to properly resolve prefetch aliases (any alias
3415 # with a relation_chain_depth less than the depth of the
3416 # current prefetch is not considered)
3417 #
3418 # The increments happen twice per join. An even number means a
3419 # relationship specified via a search_related, whereas an odd
3420 # number indicates a join/prefetch added via attributes
3421 #
3422 # Also this code will wrap the current resultset (the one we
3423 # chain to) in a subselect IFF it contains limiting attributes
3424 sub _chain_relationship {
3425   my ($self, $rel) = @_;
3426   my $source = $self->result_source;
3427   my $attrs = { %{$self->{attrs}||{}} };
3428
3429   # we need to take the prefetch the attrs into account before we
3430   # ->_resolve_join as otherwise they get lost - captainL
3431   my $join = $self->_merge_joinpref_attr( $attrs->{join}, $attrs->{prefetch} );
3432
3433   delete @{$attrs}{qw/join prefetch collapse group_by distinct select as columns +select +as +columns/};
3434
3435   my $seen = { %{ (delete $attrs->{seen_join}) || {} } };
3436
3437   my $from;
3438   my @force_subq_attrs = qw/offset rows group_by having/;
3439
3440   if (
3441     ($attrs->{from} && ref $attrs->{from} ne 'ARRAY')
3442       ||
3443     $self->_has_resolved_attr (@force_subq_attrs)
3444   ) {
3445     # Nuke the prefetch (if any) before the new $rs attrs
3446     # are resolved (prefetch is useless - we are wrapping
3447     # a subquery anyway).
3448     my $rs_copy = $self->search;
3449     $rs_copy->{attrs}{join} = $self->_merge_joinpref_attr (
3450       $rs_copy->{attrs}{join},
3451       delete $rs_copy->{attrs}{prefetch},
3452     );
3453
3454     $from = [{
3455       -rsrc   => $source,
3456       -alias  => $attrs->{alias},
3457       $attrs->{alias} => $rs_copy->as_query,
3458     }];
3459     delete @{$attrs}{@force_subq_attrs, qw/where bind/};
3460     $seen->{-relation_chain_depth} = 0;
3461   }
3462   elsif ($attrs->{from}) {  #shallow copy suffices
3463     $from = [ @{$attrs->{from}} ];
3464   }
3465   else {
3466     $from = [{
3467       -rsrc  => $source,
3468       -alias => $attrs->{alias},
3469       $attrs->{alias} => $source->from,
3470     }];
3471   }
3472
3473   my $jpath = ($seen->{-relation_chain_depth})
3474     ? $from->[-1][0]{-join_path}
3475     : [];
3476
3477   my @requested_joins = $source->_resolve_join(
3478     $join,
3479     $attrs->{alias},
3480     $seen,
3481     $jpath,
3482   );
3483
3484   push @$from, @requested_joins;
3485
3486   $seen->{-relation_chain_depth}++;
3487
3488   # if $self already had a join/prefetch specified on it, the requested
3489   # $rel might very well be already included. What we do in this case
3490   # is effectively a no-op (except that we bump up the chain_depth on
3491   # the join in question so we could tell it *is* the search_related)
3492   my $already_joined;
3493
3494   # we consider the last one thus reverse
3495   for my $j (reverse @requested_joins) {
3496     my ($last_j) = keys %{$j->[0]{-join_path}[-1]};
3497     if ($rel eq $last_j) {
3498       $j->[0]{-relation_chain_depth}++;
3499       $already_joined++;
3500       last;
3501     }
3502   }
3503
3504   unless ($already_joined) {
3505     push @$from, $source->_resolve_join(
3506       $rel,
3507       $attrs->{alias},
3508       $seen,
3509       $jpath,
3510     );
3511   }
3512
3513   $seen->{-relation_chain_depth}++;
3514
3515   return {%$attrs, from => $from, seen_join => $seen};
3516 }
3517
3518 # too many times we have to do $attrs = { %{$self->_resolved_attrs} }
3519 sub _resolved_attrs_copy {
3520   my $self = shift;
3521   return { %{$self->_resolved_attrs (@_)} };
3522 }
3523
3524 sub _resolved_attrs {
3525   my $self = shift;
3526   return $self->{_attrs} if $self->{_attrs};
3527
3528   my $attrs  = { %{ $self->{attrs} || {} } };
3529   my $source = $self->result_source;
3530   my $alias  = $attrs->{alias};
3531
3532   # default selection list
3533   $attrs->{columns} = [ $source->columns ]
3534     unless List::Util::first { exists $attrs->{$_} } qw/columns cols select as/;
3535
3536   # merge selectors together
3537   for (qw/columns select as/) {
3538     $attrs->{$_} = $self->_merge_attr($attrs->{$_}, delete $attrs->{"+$_"})
3539       if $attrs->{$_} or $attrs->{"+$_"};
3540   }
3541
3542   # disassemble columns
3543   my (@sel, @as);
3544   if (my $cols = delete $attrs->{columns}) {
3545     for my $c (ref $cols eq 'ARRAY' ? @$cols : $cols) {
3546       if (ref $c eq 'HASH') {
3547         for my $as (keys %$c) {
3548           push @sel, $c->{$as};
3549           push @as, $as;
3550         }
3551       }
3552       else {
3553         push @sel, $c;
3554         push @as, $c;
3555       }
3556     }
3557   }
3558
3559   # when trying to weed off duplicates later do not go past this point -
3560   # everything added from here on is unbalanced "anyone's guess" stuff
3561   my $dedup_stop_idx = $#as;
3562
3563   push @as, @{ ref $attrs->{as} eq 'ARRAY' ? $attrs->{as} : [ $attrs->{as} ] }
3564     if $attrs->{as};
3565   push @sel, @{ ref $attrs->{select} eq 'ARRAY' ? $attrs->{select} : [ $attrs->{select} ] }
3566     if $attrs->{select};
3567
3568   # assume all unqualified selectors to apply to the current alias (legacy stuff)
3569   for (@sel) {
3570     $_ = (ref $_ or $_ =~ /\./) ? $_ : "$alias.$_";
3571   }
3572
3573   # disqualify all $alias.col as-bits (collapser mandated)
3574   for (@as) {
3575     $_ = ($_ =~ /^\Q$alias.\E(.+)$/) ? $1 : $_;
3576   }
3577
3578   # de-duplicate the result (remove *identical* select/as pairs)
3579   # and also die on duplicate {as} pointing to different {select}s
3580   # not using a c-style for as the condition is prone to shrinkage
3581   my $seen;
3582   my $i = 0;
3583   while ($i <= $dedup_stop_idx) {
3584     if ($seen->{"$sel[$i] \x00\x00 $as[$i]"}++) {
3585       splice @sel, $i, 1;
3586       splice @as, $i, 1;
3587       $dedup_stop_idx--;
3588     }
3589     elsif ($seen->{$as[$i]}++) {
3590       $self->throw_exception(
3591         "inflate_result() alias '$as[$i]' specified twice with different SQL-side {select}-ors"
3592       );
3593     }
3594     else {
3595       $i++;
3596     }
3597   }
3598
3599   $attrs->{select} = \@sel;
3600   $attrs->{as} = \@as;
3601
3602   $attrs->{from} ||= [{
3603     -rsrc   => $source,
3604     -alias  => $self->{attrs}{alias},
3605     $self->{attrs}{alias} => $source->from,
3606   }];
3607
3608   if ( $attrs->{join} || $attrs->{prefetch} ) {
3609
3610     $self->throw_exception ('join/prefetch can not be used with a custom {from}')
3611       if ref $attrs->{from} ne 'ARRAY';
3612
3613     my $join = (delete $attrs->{join}) || {};
3614
3615     if ( defined $attrs->{prefetch} ) {
3616       $join = $self->_merge_joinpref_attr( $join, $attrs->{prefetch} );
3617     }
3618
3619     $attrs->{from} =    # have to copy here to avoid corrupting the original
3620       [
3621         @{ $attrs->{from} },
3622         $source->_resolve_join(
3623           $join,
3624           $alias,
3625           { %{ $attrs->{seen_join} || {} } },
3626           ( $attrs->{seen_join} && keys %{$attrs->{seen_join}})
3627             ? $attrs->{from}[-1][0]{-join_path}
3628             : []
3629           ,
3630         )
3631       ];
3632   }
3633
3634   if ( defined $attrs->{order_by} ) {
3635     $attrs->{order_by} = (
3636       ref( $attrs->{order_by} ) eq 'ARRAY'
3637       ? [ @{ $attrs->{order_by} } ]
3638       : [ $attrs->{order_by} || () ]
3639     );
3640   }
3641
3642   if ($attrs->{group_by} and ref $attrs->{group_by} ne 'ARRAY') {
3643     $attrs->{group_by} = [ $attrs->{group_by} ];
3644   }
3645
3646   # generate the distinct induced group_by early, as prefetch will be carried via a
3647   # subquery (since a group_by is present)
3648   if (delete $attrs->{distinct}) {
3649     if ($attrs->{group_by}) {
3650       carp_unique ("Useless use of distinct on a grouped resultset ('distinct' is ignored when a 'group_by' is present)");
3651     }
3652     else {
3653       # distinct affects only the main selection part, not what prefetch may
3654       # add below.
3655       $attrs->{group_by} = $source->storage->_group_over_selection (
3656         $attrs->{from},
3657         $attrs->{select},
3658         $attrs->{order_by},
3659       );
3660     }
3661   }
3662
3663   # generate selections based on the prefetch helper
3664   my $prefetch;
3665   $prefetch = $self->_merge_joinpref_attr( {}, delete $attrs->{prefetch} )
3666     if defined $attrs->{prefetch};
3667
3668   if ($prefetch) {
3669
3670     $self->throw_exception("Unable to prefetch, resultset contains an unnamed selector $attrs->{_dark_selector}{string}")
3671       if $attrs->{_dark_selector};
3672
3673     $attrs->{collapse} = 1;
3674
3675     # this is a separate structure (we don't look in {from} directly)
3676     # as the resolver needs to shift things off the lists to work
3677     # properly (identical-prefetches on different branches)
3678     my $join_map = {};
3679     if (ref $attrs->{from} eq 'ARRAY') {
3680
3681       my $start_depth = $attrs->{seen_join}{-relation_chain_depth} || 0;
3682
3683       for my $j ( @{$attrs->{from}}[1 .. $#{$attrs->{from}} ] ) {
3684         next unless $j->[0]{-alias};
3685         next unless $j->[0]{-join_path};
3686         next if ($j->[0]{-relation_chain_depth} || 0) < $start_depth;
3687
3688         my @jpath = map { keys %$_ } @{$j->[0]{-join_path}};
3689
3690         my $p = $join_map;
3691         $p = $p->{$_} ||= {} for @jpath[ ($start_depth/2) .. $#jpath]; #only even depths are actual jpath boundaries
3692         push @{$p->{-join_aliases} }, $j->[0]{-alias};
3693       }
3694     }
3695
3696     my @prefetch = $source->_resolve_prefetch( $prefetch, $alias, $join_map );
3697
3698     # we need to somehow mark which columns came from prefetch
3699     if (@prefetch) {
3700       my $sel_end = $#{$attrs->{select}};
3701       $attrs->{_prefetch_selector_range} = [ $sel_end + 1, $sel_end + @prefetch ];
3702     }
3703
3704     push @{ $attrs->{select} }, (map { $_->[0] } @prefetch);
3705     push @{ $attrs->{as} }, (map { $_->[1] } @prefetch);
3706   }
3707
3708   # run through the resulting joinstructure (starting from our current slot)
3709   # and unset collapse if proven unnesessary
3710   if ($attrs->{collapse} && ref $attrs->{from} eq 'ARRAY') {
3711
3712     if (@{$attrs->{from}} > 1) {
3713
3714       # find where our table-spec starts and consider only things after us
3715       my @fromlist = @{$attrs->{from}};
3716       while (@fromlist) {
3717         my $t = shift @fromlist;
3718         $t = $t->[0] if ref $t eq 'ARRAY';  #me vs join from-spec mismatch
3719         last if ($t->{-alias} && $t->{-alias} eq $alias);
3720       }
3721
3722       for (@fromlist) {
3723         $attrs->{collapse} = ! $_->[0]{-is_single}
3724           and last;
3725       }
3726     }
3727     else {
3728       # no joins - no collapse
3729       $attrs->{collapse} = 0;
3730     }
3731   }
3732
3733
3734   # if both page and offset are specified, produce a combined offset
3735   # even though it doesn't make much sense, this is what pre 081xx has
3736   # been doing
3737   if (my $page = delete $attrs->{page}) {
3738     $attrs->{offset} =
3739       ($attrs->{rows} * ($page - 1))
3740             +
3741       ($attrs->{offset} || 0)
3742     ;
3743   }
3744
3745   return $self->{_attrs} = $attrs;
3746 }
3747
3748 sub _rollout_attr {
3749   my ($self, $attr) = @_;
3750
3751   if (ref $attr eq 'HASH') {
3752     return $self->_rollout_hash($attr);
3753   } elsif (ref $attr eq 'ARRAY') {
3754     return $self->_rollout_array($attr);
3755   } else {
3756     return [$attr];
3757   }
3758 }
3759
3760 sub _rollout_array {
3761   my ($self, $attr) = @_;
3762
3763   my @rolled_array;
3764   foreach my $element (@{$attr}) {
3765     if (ref $element eq 'HASH') {
3766       push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
3767     } elsif (ref $element eq 'ARRAY') {
3768       #  XXX - should probably recurse here
3769       push( @rolled_array, @{$self->_rollout_array($element)} );
3770     } else {
3771       push( @rolled_array, $element );
3772     }
3773   }
3774   return \@rolled_array;
3775 }
3776
3777 sub _rollout_hash {
3778   my ($self, $attr) = @_;
3779
3780   my @rolled_array;
3781   foreach my $key (keys %{$attr}) {
3782     push( @rolled_array, { $key => $attr->{$key} } );
3783   }
3784   return \@rolled_array;
3785 }
3786
3787 sub _calculate_score {
3788   my ($self, $a, $b) = @_;
3789
3790   if (defined $a xor defined $b) {
3791     return 0;
3792   }
3793   elsif (not defined $a) {
3794     return 1;
3795   }
3796
3797   if (ref $b eq 'HASH') {
3798     my ($b_key) = keys %{$b};
3799     if (ref $a eq 'HASH') {
3800       my ($a_key) = keys %{$a};
3801       if ($a_key eq $b_key) {
3802         return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
3803       } else {
3804         return 0;
3805       }
3806     } else {
3807       return ($a eq $b_key) ? 1 : 0;
3808     }
3809   } else {
3810     if (ref $a eq 'HASH') {
3811       my ($a_key) = keys %{$a};
3812       return ($b eq $a_key) ? 1 : 0;
3813     } else {
3814       return ($b eq $a) ? 1 : 0;
3815     }
3816   }
3817 }
3818
3819 sub _merge_joinpref_attr {
3820   my ($self, $orig, $import) = @_;
3821
3822   return $import unless defined($orig);
3823   return $orig unless defined($import);
3824
3825   $orig = $self->_rollout_attr($orig);
3826   $import = $self->_rollout_attr($import);
3827
3828   my $seen_keys;
3829   foreach my $import_element ( @{$import} ) {
3830     # find best candidate from $orig to merge $b_element into
3831     my $best_candidate = { position => undef, score => 0 }; my $position = 0;
3832     foreach my $orig_element ( @{$orig} ) {
3833       my $score = $self->_calculate_score( $orig_element, $import_element );
3834       if ($score > $best_candidate->{score}) {
3835         $best_candidate->{position} = $position;
3836         $best_candidate->{score} = $score;
3837       }
3838       $position++;
3839     }
3840     my ($import_key) = ( ref $import_element eq 'HASH' ) ? keys %{$import_element} : ($import_element);
3841     $import_key = '' if not defined $import_key;
3842
3843     if ($best_candidate->{score} == 0 || exists $seen_keys->{$import_key}) {
3844       push( @{$orig}, $import_element );
3845     } else {
3846       my $orig_best = $orig->[$best_candidate->{position}];
3847       # merge orig_best and b_element together and replace original with merged
3848       if (ref $orig_best ne 'HASH') {
3849         $orig->[$best_candidate->{position}] = $import_element;
3850       } elsif (ref $import_element eq 'HASH') {
3851         my ($key) = keys %{$orig_best};
3852         $orig->[$best_candidate->{position}] = { $key => $self->_merge_joinpref_attr($orig_best->{$key}, $import_element->{$key}) };
3853       }
3854     }
3855     $seen_keys->{$import_key} = 1; # don't merge the same key twice
3856   }
3857
3858   return $orig;
3859 }
3860
3861 {
3862   my $hm;
3863
3864   sub _merge_attr {
3865     $hm ||= do {
3866       require Hash::Merge;
3867       my $hm = Hash::Merge->new;
3868
3869       $hm->specify_behavior({
3870         SCALAR => {
3871           SCALAR => sub {
3872             my ($defl, $defr) = map { defined $_ } (@_[0,1]);
3873
3874             if ($defl xor $defr) {
3875               return [ $defl ? $_[0] : $_[1] ];
3876             }
3877             elsif (! $defl) {
3878               return [];
3879             }
3880             elsif (__HM_DEDUP and $_[0] eq $_[1]) {
3881               return [ $_[0] ];
3882             }
3883             else {
3884               return [$_[0], $_[1]];
3885             }
3886           },
3887           ARRAY => sub {
3888             return $_[1] if !defined $_[0];
3889             return $_[1] if __HM_DEDUP and List::Util::first { $_ eq $_[0] } @{$_[1]};
3890             return [$_[0], @{$_[1]}]
3891           },
3892           HASH  => sub {
3893             return [] if !defined $_[0] and !keys %{$_[1]};
3894             return [ $_[1] ] if !defined $_[0];
3895             return [ $_[0] ] if !keys %{$_[1]};
3896             return [$_[0], $_[1]]
3897           },
3898         },
3899         ARRAY => {
3900           SCALAR => sub {
3901             return $_[0] if !defined $_[1];
3902             return $_[0] if __HM_DEDUP and List::Util::first { $_ eq $_[1] } @{$_[0]};
3903             return [@{$_[0]}, $_[1]]
3904           },
3905           ARRAY => sub {
3906             my @ret = @{$_[0]} or return $_[1];
3907             return [ @ret, @{$_[1]} ] unless __HM_DEDUP;
3908             my %idx = map { $_ => 1 } @ret;
3909             push @ret, grep { ! defined $idx{$_} } (@{$_[1]});
3910             \@ret;
3911           },
3912           HASH => sub {
3913             return [ $_[1] ] if ! @{$_[0]};
3914             return $_[0] if !keys %{$_[1]};
3915             return $_[0] if __HM_DEDUP and List::Util::first { $_ eq $_[1] } @{$_[0]};
3916             return [ @{$_[0]}, $_[1] ];
3917           },
3918         },
3919         HASH => {
3920           SCALAR => sub {
3921             return [] if !keys %{$_[0]} and !defined $_[1];
3922             return [ $_[0] ] if !defined $_[1];
3923             return [ $_[1] ] if !keys %{$_[0]};
3924             return [$_[0], $_[1]]
3925           },
3926           ARRAY => sub {
3927             return [] if !keys %{$_[0]} and !@{$_[1]};
3928             return [ $_[0] ] if !@{$_[1]};
3929             return $_[1] if !keys %{$_[0]};
3930             return $_[1] if __HM_DEDUP and List::Util::first { $_ eq $_[0] } @{$_[1]};
3931             return [ $_[0], @{$_[1]} ];
3932           },
3933           HASH => sub {
3934             return [] if !keys %{$_[0]} and !keys %{$_[1]};
3935             return [ $_[0] ] if !keys %{$_[1]};
3936             return [ $_[1] ] if !keys %{$_[0]};
3937             return [ $_[0] ] if $_[0] eq $_[1];
3938             return [ $_[0], $_[1] ];
3939           },
3940         }
3941       } => 'DBIC_RS_ATTR_MERGER');
3942       $hm;
3943     };
3944
3945     return $hm->merge ($_[1], $_[2]);
3946   }
3947 }
3948
3949 sub STORABLE_freeze {
3950   my ($self, $cloning) = @_;
3951   my $to_serialize = { %$self };
3952
3953   # A cursor in progress can't be serialized (and would make little sense anyway)
3954   delete $to_serialize->{cursor};
3955
3956   # nor is it sensical to store a not-yet-fired-count pager
3957   if ($to_serialize->{pager} and ref $to_serialize->{pager}{total_entries} eq 'CODE') {
3958     delete $to_serialize->{pager};
3959   }
3960
3961   Storable::nfreeze($to_serialize);
3962 }
3963
3964 # need this hook for symmetry
3965 sub STORABLE_thaw {
3966   my ($self, $cloning, $serialized) = @_;
3967
3968   %$self = %{ Storable::thaw($serialized) };
3969
3970   $self;
3971 }
3972
3973
3974 =head2 throw_exception
3975
3976 See L<DBIx::Class::Schema/throw_exception> for details.
3977
3978 =cut
3979
3980 sub throw_exception {
3981   my $self=shift;
3982
3983   if (ref $self and my $rsrc = $self->result_source) {
3984     $rsrc->throw_exception(@_)
3985   }
3986   else {
3987     DBIx::Class::Exception->throw(@_);
3988   }
3989 }
3990
3991 # XXX: FIXME: Attributes docs need clearing up
3992
3993 =head1 ATTRIBUTES
3994
3995 Attributes are used to refine a ResultSet in various ways when
3996 searching for data. They can be passed to any method which takes an
3997 C<\%attrs> argument. See L</search>, L</search_rs>, L</find>,
3998 L</count>.
3999
4000 These are in no particular order:
4001
4002 =head2 order_by
4003
4004 =over 4
4005
4006 =item Value: ( $order_by | \@order_by | \%order_by )
4007
4008 =back
4009
4010 Which column(s) to order the results by.
4011
4012 [The full list of suitable values is documented in
4013 L<SQL::Abstract/"ORDER BY CLAUSES">; the following is a summary of
4014 common options.]
4015
4016 If a single column name, or an arrayref of names is supplied, the
4017 argument is passed through directly to SQL. The hashref syntax allows
4018 for connection-agnostic specification of ordering direction:
4019
4020  For descending order:
4021
4022   order_by => { -desc => [qw/col1 col2 col3/] }
4023
4024  For explicit ascending order:
4025
4026   order_by => { -asc => 'col' }
4027
4028 The old scalarref syntax (i.e. order_by => \'year DESC') is still
4029 supported, although you are strongly encouraged to use the hashref
4030 syntax as outlined above.
4031
4032 =head2 columns
4033
4034 =over 4
4035
4036 =item Value: \@columns
4037
4038 =back
4039
4040 Shortcut to request a particular set of columns to be retrieved. Each
4041 column spec may be a string (a table column name), or a hash (in which
4042 case the key is the C<as> value, and the value is used as the C<select>
4043 expression). Adds C<me.> onto the start of any column without a C<.> in
4044 it and sets C<select> from that, then auto-populates C<as> from
4045 C<select> as normal. (You may also use the C<cols> attribute, as in
4046 earlier versions of DBIC.)
4047
4048 Essentially C<columns> does the same as L</select> and L</as>.
4049
4050     columns => [ 'foo', { bar => 'baz' } ]
4051
4052 is the same as
4053
4054     select => [qw/foo baz/],
4055     as => [qw/foo bar/]
4056
4057 =head2 +columns
4058
4059 =over 4
4060
4061 =item Value: \@columns
4062
4063 =back
4064
4065 Indicates additional columns to be selected from storage. Works the same
4066 as L</columns> but adds columns to the selection. (You may also use the
4067 C<include_columns> attribute, as in earlier versions of DBIC). For
4068 example:-
4069
4070   $schema->resultset('CD')->search(undef, {
4071     '+columns' => ['artist.name'],
4072     join => ['artist']
4073   });
4074
4075 would return all CDs and include a 'name' column to the information
4076 passed to object inflation. Note that the 'artist' is the name of the
4077 column (or relationship) accessor, and 'name' is the name of the column
4078 accessor in the related table.
4079
4080 B<NOTE:> You need to explicitly quote '+columns' when defining the attribute.
4081 Not doing so causes Perl to incorrectly interpret +columns as a bareword with a
4082 unary plus operator before it.
4083
4084 =head2 include_columns
4085
4086 =over 4
4087
4088 =item Value: \@columns
4089
4090 =back
4091
4092 Deprecated.  Acts as a synonym for L</+columns> for backward compatibility.
4093
4094 =head2 select
4095
4096 =over 4
4097
4098 =item Value: \@select_columns
4099
4100 =back
4101
4102 Indicates which columns should be selected from the storage. You can use
4103 column names, or in the case of RDBMS back ends, function or stored procedure
4104 names:
4105
4106   $rs = $schema->resultset('Employee')->search(undef, {
4107     select => [
4108       'name',
4109       { count => 'employeeid' },
4110       { max => { length => 'name' }, -as => 'longest_name' }
4111     ]
4112   });
4113
4114   # Equivalent SQL
4115   SELECT name, COUNT( employeeid ), MAX( LENGTH( name ) ) AS longest_name FROM employee
4116
4117 B<NOTE:> You will almost always need a corresponding L</as> attribute when you
4118 use L</select>, to instruct DBIx::Class how to store the result of the column.
4119 Also note that the L</as> attribute has nothing to do with the SQL-side 'AS'
4120 identifier aliasing. You can however alias a function, so you can use it in
4121 e.g. an C<ORDER BY> clause. This is done via the C<-as> B<select function
4122 attribute> supplied as shown in the example above.
4123
4124 B<NOTE:> You need to explicitly quote '+select'/'+as' when defining the attributes.
4125 Not doing so causes Perl to incorrectly interpret them as a bareword with a
4126 unary plus operator before it.
4127
4128 =head2 +select
4129
4130 =over 4
4131
4132 Indicates additional columns to be selected from storage.  Works the same as
4133 L</select> but adds columns to the default selection, instead of specifying
4134 an explicit list.
4135
4136 =back
4137
4138 =head2 +as
4139
4140 =over 4
4141
4142 Indicates additional column names for those added via L</+select>. See L</as>.
4143
4144 =back
4145
4146 =head2 as
4147
4148 =over 4
4149
4150 =item Value: \@inflation_names
4151
4152 =back
4153
4154 Indicates column names for object inflation. That is L</as> indicates the
4155 slot name in which the column value will be stored within the
4156 L<Row|DBIx::Class::Row> object. The value will then be accessible via this
4157 identifier by the C<get_column> method (or via the object accessor B<if one
4158 with the same name already exists>) as shown below. The L</as> attribute has
4159 B<nothing to do> with the SQL-side C<AS>. See L</select> for details.
4160
4161   $rs = $schema->resultset('Employee')->search(undef, {
4162     select => [
4163       'name',
4164       { count => 'employeeid' },
4165       { max => { length => 'name' }, -as => 'longest_name' }
4166     ],
4167     as => [qw/
4168       name
4169       employee_count
4170       max_name_length
4171     /],
4172   });
4173
4174 If the object against which the search is performed already has an accessor
4175 matching a column name specified in C<as>, the value can be retrieved using
4176 the accessor as normal:
4177
4178   my $name = $employee->name();
4179
4180 If on the other hand an accessor does not exist in the object, you need to
4181 use C<get_column> instead:
4182
4183   my $employee_count = $employee->get_column('employee_count');
4184
4185 You can create your own accessors if required - see
4186 L<DBIx::Class::Manual::Cookbook> for details.
4187
4188 =head2 join
4189
4190 =over 4
4191
4192 =item Value: ($rel_name | \@rel_names | \%rel_names)
4193
4194 =back
4195
4196 Contains a list of relationships that should be joined for this query.  For
4197 example:
4198
4199   # Get CDs by Nine Inch Nails
4200   my $rs = $schema->resultset('CD')->search(
4201     { 'artist.name' => 'Nine Inch Nails' },
4202     { join => 'artist' }
4203   );
4204
4205 Can also contain a hash reference to refer to the other relation's relations.
4206 For example:
4207
4208   package MyApp::Schema::Track;
4209   use base qw/DBIx::Class/;
4210   __PACKAGE__->table('track');
4211   __PACKAGE__->add_columns(qw/trackid cd position title/);
4212   __PACKAGE__->set_primary_key('trackid');
4213   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
4214   1;
4215
4216   # In your application
4217   my $rs = $schema->resultset('Artist')->search(
4218     { 'track.title' => 'Teardrop' },
4219     {
4220       join     => { cd => 'track' },
4221       order_by => 'artist.name',
4222     }
4223   );
4224
4225 You need to use the relationship (not the table) name in  conditions,
4226 because they are aliased as such. The current table is aliased as "me", so
4227 you need to use me.column_name in order to avoid ambiguity. For example:
4228
4229   # Get CDs from 1984 with a 'Foo' track
4230   my $rs = $schema->resultset('CD')->search(
4231     {
4232       'me.year' => 1984,
4233       'tracks.name' => 'Foo'
4234     },
4235     { join => 'tracks' }
4236   );
4237
4238 If the same join is supplied twice, it will be aliased to <rel>_2 (and
4239 similarly for a third time). For e.g.
4240
4241   my $rs = $schema->resultset('Artist')->search({
4242     'cds.title'   => 'Down to Earth',
4243     'cds_2.title' => 'Popular',
4244   }, {
4245     join => [ qw/cds cds/ ],
4246   });
4247
4248 will return a set of all artists that have both a cd with title 'Down
4249 to Earth' and a cd with title 'Popular'.
4250
4251 If you want to fetch related objects from other tables as well, see C<prefetch>
4252 below.
4253
4254 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
4255
4256 =head2 prefetch
4257
4258 =over 4
4259
4260 =item Value: ($rel_name | \@rel_names | \%rel_names)
4261
4262 =back
4263
4264 Contains one or more relationships that should be fetched along with
4265 the main query (when they are accessed afterwards the data will
4266 already be available, without extra queries to the database).  This is
4267 useful for when you know you will need the related objects, because it
4268 saves at least one query:
4269
4270   my $rs = $schema->resultset('Tag')->search(
4271     undef,
4272     {
4273       prefetch => {
4274         cd => 'artist'
4275       }
4276     }
4277   );
4278
4279 The initial search results in SQL like the following:
4280
4281   SELECT tag.*, cd.*, artist.* FROM tag
4282   JOIN cd ON tag.cd = cd.cdid
4283   JOIN artist ON cd.artist = artist.artistid
4284
4285 L<DBIx::Class> has no need to go back to the database when we access the
4286 C<cd> or C<artist> relationships, which saves us two SQL statements in this
4287 case.
4288
4289 Simple prefetches will be joined automatically, so there is no need
4290 for a C<join> attribute in the above search.
4291
4292 L</prefetch> can be used with the any of the relationship types and
4293 multiple prefetches can be specified together. Below is a more complex
4294 example that prefetches a CD's artist, its liner notes (if present),
4295 the cover image, the tracks on that cd, and the guests on those
4296 tracks.
4297
4298  # Assuming:
4299  My::Schema::CD->belongs_to( artist      => 'My::Schema::Artist'     );
4300  My::Schema::CD->might_have( liner_note  => 'My::Schema::LinerNotes' );
4301  My::Schema::CD->has_one(    cover_image => 'My::Schema::Artwork'    );
4302  My::Schema::CD->has_many(   tracks      => 'My::Schema::Track'      );
4303
4304  My::Schema::Artist->belongs_to( record_label => 'My::Schema::RecordLabel' );
4305
4306  My::Schema::Track->has_many( guests => 'My::Schema::Guest' );
4307
4308
4309  my $rs = $schema->resultset('CD')->search(
4310    undef,
4311    {
4312      prefetch => [
4313        { artist => 'record_label'},  # belongs_to => belongs_to
4314        'liner_note',                 # might_have
4315        'cover_image',                # has_one
4316        { tracks => 'guests' },       # has_many => has_many
4317      ]
4318    }
4319  );
4320
4321 This will produce SQL like the following:
4322
4323  SELECT cd.*, artist.*, record_label.*, liner_note.*, cover_image.*,
4324         tracks.*, guests.*
4325    FROM cd me
4326    JOIN artist artist
4327      ON artist.artistid = me.artistid
4328    JOIN record_label record_label
4329      ON record_label.labelid = artist.labelid
4330    LEFT JOIN track tracks
4331      ON tracks.cdid = me.cdid
4332    LEFT JOIN guest guests
4333      ON guests.trackid = track.trackid
4334    LEFT JOIN liner_notes liner_note
4335      ON liner_note.cdid = me.cdid
4336    JOIN cd_artwork cover_image
4337      ON cover_image.cdid = me.cdid
4338  ORDER BY tracks.cd
4339
4340 Now the C<artist>, C<record_label>, C<liner_note>, C<cover_image>,
4341 C<tracks>, and C<guests> of the CD will all be available through the
4342 relationship accessors without the need for additional queries to the
4343 database.
4344
4345 However, there is one caveat to be observed: it can be dangerous to
4346 prefetch more than one L<has_many|DBIx::Class::Relationship/has_many>
4347 relationship on a given level. e.g.:
4348
4349  my $rs = $schema->resultset('CD')->search(
4350    undef,
4351    {
4352      prefetch => [
4353        'tracks',                         # has_many
4354        { cd_to_producer => 'producer' }, # has_many => belongs_to (i.e. m2m)
4355      ]
4356    }
4357  );
4358
4359 In fact, C<DBIx::Class> will emit the following warning:
4360
4361  Prefetching multiple has_many rels tracks and cd_to_producer at top
4362  level will explode the number of row objects retrievable via ->next
4363  or ->all. Use at your own risk.
4364
4365 The collapser currently can't identify duplicate tuples for multiple
4366 L<has_many|DBIx::Class::Relationship/has_many> relationships and as a
4367 result the second L<has_many|DBIx::Class::Relationship/has_many>
4368 relation could contain redundant objects.
4369
4370 =head3 Using L</prefetch> with L</join>
4371
4372 L</prefetch> implies a L</join> with the equivalent argument, and is
4373 properly merged with any existing L</join> specification. So the
4374 following:
4375
4376   my $rs = $schema->resultset('CD')->search(
4377    {'record_label.name' => 'Music Product Ltd.'},
4378    {
4379      join     => {artist => 'record_label'},
4380      prefetch => 'artist',
4381    }
4382  );
4383
4384 ... will work, searching on the record label's name, but only
4385 prefetching the C<artist>.
4386
4387 =head3 Using L</prefetch> with L</select> / L</+select> / L</as> / L</+as>
4388
4389 L</prefetch> implies a L</+select>/L</+as> with the fields of the
4390 prefetched relations.  So given:
4391
4392   my $rs = $schema->resultset('CD')->search(
4393    undef,
4394    {
4395      select   => ['cd.title'],
4396      as       => ['cd_title'],
4397      prefetch => 'artist',
4398    }
4399  );
4400
4401 The L</select> becomes: C<'cd.title', 'artist.*'> and the L</as>
4402 becomes: C<'cd_title', 'artist.*'>.
4403
4404 =head3 CAVEATS
4405
4406 Prefetch does a lot of deep magic. As such, it may not behave exactly
4407 as you might expect.
4408
4409 =over 4
4410
4411 =item *
4412
4413 Prefetch uses the L</cache> to populate the prefetched relationships. This
4414 may or may not be what you want.
4415
4416 =item *
4417
4418 If you specify a condition on a prefetched relationship, ONLY those
4419 rows that match the prefetched condition will be fetched into that relationship.
4420 This means that adding prefetch to a search() B<may alter> what is returned by
4421 traversing a relationship. So, if you have C<< Artist->has_many(CDs) >> and you do
4422
4423   my $artist_rs = $schema->resultset('Artist')->search({
4424       'cds.year' => 2008,
4425   }, {
4426       join => 'cds',
4427   });
4428
4429   my $count = $artist_rs->first->cds->count;
4430
4431   my $artist_rs_prefetch = $artist_rs->search( {}, { prefetch => 'cds' } );
4432
4433   my $prefetch_count = $artist_rs_prefetch->first->cds->count;
4434
4435   cmp_ok( $count, '==', $prefetch_count, "Counts should be the same" );
4436
4437 that cmp_ok() may or may not pass depending on the datasets involved. This
4438 behavior may or may not survive the 0.09 transition.
4439
4440 =back
4441
4442 =head2 page
4443
4444 =over 4
4445
4446 =item Value: $page
4447
4448 =back
4449
4450 Makes the resultset paged and specifies the page to retrieve. Effectively
4451 identical to creating a non-pages resultset and then calling ->page($page)
4452 on it.
4453
4454 If L</rows> attribute is not specified it defaults to 10 rows per page.
4455
4456 When you have a paged resultset, L</count> will only return the number
4457 of rows in the page. To get the total, use the L</pager> and call
4458 C<total_entries> on it.
4459
4460 =head2 rows
4461
4462 =over 4
4463
4464 =item Value: $rows
4465
4466 =back
4467
4468 Specifies the maximum number of rows for direct retrieval or the number of
4469 rows per page if the page attribute or method is used.
4470
4471 =head2 offset
4472
4473 =over 4
4474
4475 =item Value: $offset
4476
4477 =back
4478
4479 Specifies the (zero-based) row number for the  first row to be returned, or the
4480 of the first row of the first page if paging is used.
4481
4482 =head2 software_limit
4483
4484 =over 4
4485
4486 =item Value: (0 | 1)
4487
4488 =back
4489
4490 When combined with L</rows> and/or L</offset> the generated SQL will not
4491 include any limit dialect stanzas. Instead the entire result will be selected
4492 as if no limits were specified, and DBIC will perform the limit locally, by
4493 artificially advancing and finishing the resulting L</cursor>.
4494
4495 This is the recommended way of performing resultset limiting when no sane RDBMS
4496 implementation is available (e.g.
4497 L<Sybase ASE|DBIx::Class::Storage::DBI::Sybase::ASE> using the
4498 L<Generic Sub Query|DBIx::Class::SQLMaker::LimitDialects/GenericSubQ> hack)
4499
4500 =head2 group_by
4501
4502 =over 4
4503
4504 =item Value: \@columns
4505
4506 =back
4507
4508 A arrayref of columns to group by. Can include columns of joined tables.
4509
4510   group_by => [qw/ column1 column2 ... /]
4511
4512 =head2 having
4513
4514 =over 4
4515
4516 =item Value: $condition
4517
4518 =back
4519
4520 HAVING is a select statement attribute that is applied between GROUP BY and
4521 ORDER BY. It is applied to the after the grouping calculations have been
4522 done.
4523
4524   having => { 'count_employee' => { '>=', 100 } }
4525
4526 or with an in-place function in which case literal SQL is required:
4527
4528   having => \[ 'count(employee) >= ?', [ count => 100 ] ]
4529
4530 =head2 distinct
4531
4532 =over 4
4533
4534 =item Value: (0 | 1)
4535
4536 =back
4537
4538 Set to 1 to group by all columns. If the resultset already has a group_by
4539 attribute, this setting is ignored and an appropriate warning is issued.
4540
4541 =head2 where
4542
4543 =over 4
4544
4545 Adds to the WHERE clause.
4546
4547   # only return rows WHERE deleted IS NULL for all searches
4548   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
4549
4550 Can be overridden by passing C<< { where => undef } >> as an attribute
4551 to a resultset.
4552
4553 For more complicated where clauses see L<SQL::Abstract/WHERE CLAUSES>.
4554
4555 =back
4556
4557 =head2 cache
4558
4559 Set to 1 to cache search results. This prevents extra SQL queries if you
4560 revisit rows in your ResultSet:
4561
4562   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
4563
4564   while( my $artist = $resultset->next ) {
4565     ... do stuff ...
4566   }
4567
4568   $rs->first; # without cache, this would issue a query
4569
4570 By default, searches are not cached.
4571
4572 For more examples of using these attributes, see
4573 L<DBIx::Class::Manual::Cookbook>.
4574
4575 =head2 for
4576
4577 =over 4
4578
4579 =item Value: ( 'update' | 'shared' )
4580
4581 =back
4582
4583 Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT
4584 ... FOR SHARED.
4585
4586 =cut
4587
4588 1;