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