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