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