Merge 'trunk' into 'cdbicompat_integration'
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use overload
6         '0+'     => "count",
7         'bool'   => "_bool",
8         fallback => 1;
9 use Carp::Clan qw/^DBIx::Class/;
10 use Data::Page;
11 use Storable;
12 use DBIx::Class::ResultSetColumn;
13 use DBIx::Class::ResultSourceHandle;
14 use base qw/DBIx::Class/;
15
16 __PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/);
17
18 =head1 NAME
19
20 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
21
22 =head1 SYNOPSIS
23
24   my $rs   = $schema->resultset('User')->search(registered => 1);
25   my @rows = $schema->resultset('CD')->search(year => 2005);
26
27 =head1 DESCRIPTION
28
29 The resultset is also known as an iterator. It is responsible for handling
30 queries that may return an arbitrary number of rows, e.g. via L</search>
31 or a C<has_many> relationship.
32
33 In the examples below, the following table classes are used:
34
35   package MyApp::Schema::Artist;
36   use base qw/DBIx::Class/;
37   __PACKAGE__->load_components(qw/Core/);
38   __PACKAGE__->table('artist');
39   __PACKAGE__->add_columns(qw/artistid name/);
40   __PACKAGE__->set_primary_key('artistid');
41   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
42   1;
43
44   package MyApp::Schema::CD;
45   use base qw/DBIx::Class/;
46   __PACKAGE__->load_components(qw/Core/);
47   __PACKAGE__->table('cd');
48   __PACKAGE__->add_columns(qw/cdid artist title year/);
49   __PACKAGE__->set_primary_key('cdid');
50   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
51   1;
52
53 =head1 OVERLOADING
54
55 If a resultset is used as a number it returns the C<count()>.  However, if it is used as a boolean it is always true.  So if you want to check if a result set has any results use C<if $rs != 0>.  C<if $rs> will always be true.
56
57 =head1 METHODS
58
59 =head2 new
60
61 =over 4
62
63 =item Arguments: $source, \%$attrs
64
65 =item Return Value: $rs
66
67 =back
68
69 The resultset constructor. Takes a source object (usually a
70 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
71 L</ATTRIBUTES> below).  Does not perform any queries -- these are
72 executed as needed by the other methods.
73
74 Generally you won't need to construct a resultset manually.  You'll
75 automatically get one from e.g. a L</search> called in scalar context:
76
77   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
78
79 IMPORTANT: If called on an object, proxies to new_result instead so
80
81   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
82
83 will return a CD object, not a ResultSet.
84
85 =cut
86
87 sub new {
88   my $class = shift;
89   return $class->new_result(@_) if ref $class;
90
91   my ($source, $attrs) = @_;
92   $source = $source->handle 
93     unless $source->isa('DBIx::Class::ResultSourceHandle');
94   $attrs = { %{$attrs||{}} };
95
96   if ($attrs->{page}) {
97     $attrs->{rows} ||= 10;
98   }
99
100   $attrs->{alias} ||= 'me';
101
102   # Creation of {} and bless separated to mitigate RH perl bug
103   # see https://bugzilla.redhat.com/show_bug.cgi?id=196836
104   my $self = {
105     _source_handle => $source,
106     result_class => $attrs->{result_class} || $source->resolve->result_class,
107     cond => $attrs->{where},
108     count => undef,
109     pager => undef,
110     attrs => $attrs
111   };
112
113   bless $self, $class;
114
115   return $self;
116 }
117
118 =head2 search
119
120 =over 4
121
122 =item Arguments: $cond, \%attrs?
123
124 =item Return Value: $resultset (scalar context), @row_objs (list context)
125
126 =back
127
128   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
129   my $new_rs = $cd_rs->search({ year => 2005 });
130
131   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
132                  # year = 2005 OR year = 2004
133
134 If you need to pass in additional attributes but no additional condition,
135 call it as C<search(undef, \%attrs)>.
136
137   # "SELECT name, artistid FROM $artist_table"
138   my @all_artists = $schema->resultset('Artist')->search(undef, {
139     columns => [qw/name artistid/],
140   });
141
142 For a list of attributes that can be passed to C<search>, see
143 L</ATTRIBUTES>. For more examples of using this function, see
144 L<Searching|DBIx::Class::Manual::Cookbook/Searching>. For a complete
145 documentation for the first argument, see L<SQL::Abstract>.
146
147 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
148
149 =cut
150
151 sub search {
152   my $self = shift;
153   my $rs = $self->search_rs( @_ );
154   return (wantarray ? $rs->all : $rs);
155 }
156
157 =head2 search_rs
158
159 =over 4
160
161 =item Arguments: $cond, \%attrs?
162
163 =item Return Value: $resultset
164
165 =back
166
167 This method does the same exact thing as search() except it will
168 always return a resultset, even in list context.
169
170 =cut
171
172 sub search_rs {
173   my $self = shift;
174
175   my $rows;
176
177   unless (@_) {                 # no search, effectively just a clone
178     $rows = $self->get_cache;
179   }
180
181   my $attrs = {};
182   $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
183   my $our_attrs = { %{$self->{attrs}} };
184   my $having = delete $our_attrs->{having};
185   my $where = delete $our_attrs->{where};
186
187   my $new_attrs = { %{$our_attrs}, %{$attrs} };
188
189   # merge new attrs into inherited
190   foreach my $key (qw/join prefetch/) {
191     next unless exists $attrs->{$key};
192     $new_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
193   }
194
195   my $cond = (@_
196     ? (
197         (@_ == 1 || ref $_[0] eq "HASH")
198           ? (
199               (ref $_[0] eq 'HASH')
200                 ? (
201                     (keys %{ $_[0] }  > 0)
202                       ? shift
203                       : undef
204                    )
205                 :  shift
206              )
207           : (
208               (@_ % 2)
209                 ? $self->throw_exception("Odd number of arguments to search")
210                 : {@_}
211              )
212       )
213     : undef
214   );
215
216   if (defined $where) {
217     $new_attrs->{where} = (
218       defined $new_attrs->{where}
219         ? { '-and' => [
220               map {
221                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
222               } $where, $new_attrs->{where}
223             ]
224           }
225         : $where);
226   }
227
228   if (defined $cond) {
229     $new_attrs->{where} = (
230       defined $new_attrs->{where}
231         ? { '-and' => [
232               map {
233                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
234               } $cond, $new_attrs->{where}
235             ]
236           }
237         : $cond);
238   }
239
240   if (defined $having) {
241     $new_attrs->{having} = (
242       defined $new_attrs->{having}
243         ? { '-and' => [
244               map {
245                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
246               } $having, $new_attrs->{having}
247             ]
248           }
249         : $having);
250   }
251
252   my $rs = (ref $self)->new($self->result_source, $new_attrs);
253   if ($rows) {
254     $rs->set_cache($rows);
255   }
256   return $rs;
257 }
258
259 =head2 search_literal
260
261 =over 4
262
263 =item Arguments: $sql_fragment, @bind_values
264
265 =item Return Value: $resultset (scalar context), @row_objs (list context)
266
267 =back
268
269   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
270   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
271
272 Pass a literal chunk of SQL to be added to the conditional part of the
273 resultset query.
274
275 CAVEAT: C<search_literal> is provided for Class::DBI compatibility and should
276 only be used in that context. There are known problems using C<search_literal>
277 in chained queries; it can result in bind values in the wrong order.  See
278 L<DBIx::Class::Manual::Cookbook/Searching> and
279 L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not
280 require C<search_literal>.
281
282 =cut
283
284 sub search_literal {
285   my ($self, $cond, @vals) = @_;
286   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
287   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
288   return $self->search(\$cond, $attrs);
289 }
290
291 =head2 find
292
293 =over 4
294
295 =item Arguments: @values | \%cols, \%attrs?
296
297 =item Return Value: $row_object
298
299 =back
300
301 Finds a row based on its primary key or unique constraint. For example, to find
302 a row by its primary key:
303
304   my $cd = $schema->resultset('CD')->find(5);
305
306 You can also find a row by a specific unique constraint using the C<key>
307 attribute. For example:
308
309   my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', {
310     key => 'cd_artist_title'
311   });
312
313 Additionally, you can specify the columns explicitly by name:
314
315   my $cd = $schema->resultset('CD')->find(
316     {
317       artist => 'Massive Attack',
318       title  => 'Mezzanine',
319     },
320     { key => 'cd_artist_title' }
321   );
322
323 If the C<key> is specified as C<primary>, it searches only on the primary key.
324
325 If no C<key> is specified, it searches on all unique constraints defined on the
326 source, including the primary key.
327
328 If your table does not have a primary key, you B<must> provide a value for the
329 C<key> attribute matching one of the unique constraints on the source.
330
331 See also L</find_or_create> and L</update_or_create>. For information on how to
332 declare unique constraints, see
333 L<DBIx::Class::ResultSource/add_unique_constraint>.
334
335 =cut
336
337 sub find {
338   my $self = shift;
339   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
340
341   # Default to the primary key, but allow a specific key
342   my @cols = exists $attrs->{key}
343     ? $self->result_source->unique_constraint_columns($attrs->{key})
344     : $self->result_source->primary_columns;
345   $self->throw_exception(
346     "Can't find unless a primary key is defined or unique constraint is specified"
347   ) unless @cols;
348
349   # Parse out a hashref from input
350   my $input_query;
351   if (ref $_[0] eq 'HASH') {
352     $input_query = { %{$_[0]} };
353   }
354   elsif (@_ == @cols) {
355     $input_query = {};
356     @{$input_query}{@cols} = @_;
357   }
358   else {
359     # Compatibility: Allow e.g. find(id => $value)
360     carp "Find by key => value deprecated; please use a hashref instead";
361     $input_query = {@_};
362   }
363
364   my (%related, $info);
365
366   KEY: foreach my $key (keys %$input_query) {
367     if (ref($input_query->{$key})
368         && ($info = $self->result_source->relationship_info($key))) {
369       my $val = delete $input_query->{$key};
370       next KEY if (ref($val) eq 'ARRAY'); # has_many for multi_create
371       my $rel_q = $self->result_source->resolve_condition(
372                     $info->{cond}, $val, $key
373                   );
374       die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY';
375       @related{keys %$rel_q} = values %$rel_q;
376     }
377   }
378   if (my @keys = keys %related) {
379     @{$input_query}{@keys} = values %related;
380   }
381
382   my @unique_queries = $self->_unique_queries($input_query, $attrs);
383
384   # Build the final query: Default to the disjunction of the unique queries,
385   # but allow the input query in case the ResultSet defines the query or the
386   # user is abusing find
387   my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias};
388   my $query = @unique_queries
389     ? [ map { $self->_add_alias($_, $alias) } @unique_queries ]
390     : $self->_add_alias($input_query, $alias);
391
392   # Run the query
393   if (keys %$attrs) {
394     my $rs = $self->search($query, $attrs);
395     return keys %{$rs->_resolved_attrs->{collapse}} ? $rs->next : $rs->single;
396   }
397   else {
398     return keys %{$self->_resolved_attrs->{collapse}}
399       ? $self->search($query)->next
400       : $self->single($query);
401   }
402 }
403
404 # _add_alias
405 #
406 # Add the specified alias to the specified query hash. A copy is made so the
407 # original query is not modified.
408
409 sub _add_alias {
410   my ($self, $query, $alias) = @_;
411
412   my %aliased = %$query;
413   foreach my $col (grep { ! m/\./ } keys %aliased) {
414     $aliased{"$alias.$col"} = delete $aliased{$col};
415   }
416
417   return \%aliased;
418 }
419
420 # _unique_queries
421 #
422 # Build a list of queries which satisfy unique constraints.
423
424 sub _unique_queries {
425   my ($self, $query, $attrs) = @_;
426
427   my @constraint_names = exists $attrs->{key}
428     ? ($attrs->{key})
429     : $self->result_source->unique_constraint_names;
430
431   my $where = $self->_collapse_cond($self->{attrs}{where} || {});
432   my $num_where = scalar keys %$where;
433
434   my @unique_queries;
435   foreach my $name (@constraint_names) {
436     my @unique_cols = $self->result_source->unique_constraint_columns($name);
437     my $unique_query = $self->_build_unique_query($query, \@unique_cols);
438
439     my $num_cols = scalar @unique_cols;
440     my $num_query = scalar keys %$unique_query;
441
442     my $total = $num_query + $num_where;
443     if ($num_query && ($num_query == $num_cols || $total == $num_cols)) {
444       # The query is either unique on its own or is unique in combination with
445       # the existing where clause
446       push @unique_queries, $unique_query;
447     }
448   }
449
450   return @unique_queries;
451 }
452
453 # _build_unique_query
454 #
455 # Constrain the specified query hash based on the specified column names.
456
457 sub _build_unique_query {
458   my ($self, $query, $unique_cols) = @_;
459
460   return {
461     map  { $_ => $query->{$_} }
462     grep { exists $query->{$_} }
463       @$unique_cols
464   };
465 }
466
467 =head2 search_related
468
469 =over 4
470
471 =item Arguments: $rel, $cond, \%attrs?
472
473 =item Return Value: $new_resultset
474
475 =back
476
477   $new_rs = $cd_rs->search_related('artist', {
478     name => 'Emo-R-Us',
479   });
480
481 Searches the specified relationship, optionally specifying a condition and
482 attributes for matching records. See L</ATTRIBUTES> for more information.
483
484 =cut
485
486 sub search_related {
487   return shift->related_resultset(shift)->search(@_);
488 }
489
490 =head2 cursor
491
492 =over 4
493
494 =item Arguments: none
495
496 =item Return Value: $cursor
497
498 =back
499
500 Returns a storage-driven cursor to the given resultset. See
501 L<DBIx::Class::Cursor> for more information.
502
503 =cut
504
505 sub cursor {
506   my ($self) = @_;
507
508   my $attrs = { %{$self->_resolved_attrs} };
509   return $self->{cursor}
510     ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
511           $attrs->{where},$attrs);
512 }
513
514 =head2 single
515
516 =over 4
517
518 =item Arguments: $cond?
519
520 =item Return Value: $row_object?
521
522 =back
523
524   my $cd = $schema->resultset('CD')->single({ year => 2001 });
525
526 Inflates the first result without creating a cursor if the resultset has
527 any records in it; if not returns nothing. Used by L</find> as an optimisation.
528
529 Can optionally take an additional condition *only* - this is a fast-code-path
530 method; if you need to add extra joins or similar call ->search and then
531 ->single without a condition on the $rs returned from that.
532
533 =cut
534
535 sub single {
536   my ($self, $where) = @_;
537   my $attrs = { %{$self->_resolved_attrs} };
538   if ($where) {
539     if (defined $attrs->{where}) {
540       $attrs->{where} = {
541         '-and' =>
542             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
543                $where, delete $attrs->{where} ]
544       };
545     } else {
546       $attrs->{where} = $where;
547     }
548   }
549
550 #  XXX: Disabled since it doesn't infer uniqueness in all cases
551 #  unless ($self->_is_unique_query($attrs->{where})) {
552 #    carp "Query not guaranteed to return a single row"
553 #      . "; please declare your unique constraints or use search instead";
554 #  }
555
556   my @data = $self->result_source->storage->select_single(
557     $attrs->{from}, $attrs->{select},
558     $attrs->{where}, $attrs
559   );
560
561   return (@data ? ($self->_construct_object(@data))[0] : undef);
562 }
563
564 # _is_unique_query
565 #
566 # Try to determine if the specified query is guaranteed to be unique, based on
567 # the declared unique constraints.
568
569 sub _is_unique_query {
570   my ($self, $query) = @_;
571
572   my $collapsed = $self->_collapse_query($query);
573   my $alias = $self->{attrs}{alias};
574
575   foreach my $name ($self->result_source->unique_constraint_names) {
576     my @unique_cols = map {
577       "$alias.$_"
578     } $self->result_source->unique_constraint_columns($name);
579
580     # Count the values for each unique column
581     my %seen = map { $_ => 0 } @unique_cols;
582
583     foreach my $key (keys %$collapsed) {
584       my $aliased = $key =~ /\./ ? $key : "$alias.$key";
585       next unless exists $seen{$aliased};  # Additional constraints are okay
586       $seen{$aliased} = scalar keys %{ $collapsed->{$key} };
587     }
588
589     # If we get 0 or more than 1 value for a column, it's not necessarily unique
590     return 1 unless grep { $_ != 1 } values %seen;
591   }
592
593   return 0;
594 }
595
596 # _collapse_query
597 #
598 # Recursively collapse the query, accumulating values for each column.
599
600 sub _collapse_query {
601   my ($self, $query, $collapsed) = @_;
602
603   $collapsed ||= {};
604
605   if (ref $query eq 'ARRAY') {
606     foreach my $subquery (@$query) {
607       next unless ref $subquery;  # -or
608 #      warn "ARRAY: " . Dumper $subquery;
609       $collapsed = $self->_collapse_query($subquery, $collapsed);
610     }
611   }
612   elsif (ref $query eq 'HASH') {
613     if (keys %$query and (keys %$query)[0] eq '-and') {
614       foreach my $subquery (@{$query->{-and}}) {
615 #        warn "HASH: " . Dumper $subquery;
616         $collapsed = $self->_collapse_query($subquery, $collapsed);
617       }
618     }
619     else {
620 #      warn "LEAF: " . Dumper $query;
621       foreach my $col (keys %$query) {
622         my $value = $query->{$col};
623         $collapsed->{$col}{$value}++;
624       }
625     }
626   }
627
628   return $collapsed;
629 }
630
631 =head2 get_column
632
633 =over 4
634
635 =item Arguments: $cond?
636
637 =item Return Value: $resultsetcolumn
638
639 =back
640
641   my $max_length = $rs->get_column('length')->max;
642
643 Returns a L<DBIx::Class::ResultSetColumn> instance for a column of the ResultSet.
644
645 =cut
646
647 sub get_column {
648   my ($self, $column) = @_;
649   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
650   return $new;
651 }
652
653 =head2 search_like
654
655 =over 4
656
657 =item Arguments: $cond, \%attrs?
658
659 =item Return Value: $resultset (scalar context), @row_objs (list context)
660
661 =back
662
663   # WHERE title LIKE '%blue%'
664   $cd_rs = $rs->search_like({ title => '%blue%'});
665
666 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
667 that this is simply a convenience method. You most likely want to use
668 L</search> with specific operators.
669
670 For more information, see L<DBIx::Class::Manual::Cookbook>.
671
672 =cut
673
674 sub search_like {
675   my $class = shift;
676   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
677   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
678   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
679   return $class->search($query, { %$attrs });
680 }
681
682 =head2 slice
683
684 =over 4
685
686 =item Arguments: $first, $last
687
688 =item Return Value: $resultset (scalar context), @row_objs (list context)
689
690 =back
691
692 Returns a resultset or object list representing a subset of elements from the
693 resultset slice is called on. Indexes are from 0, i.e., to get the first
694 three records, call:
695
696   my ($one, $two, $three) = $rs->slice(0, 2);
697
698 =cut
699
700 sub slice {
701   my ($self, $min, $max) = @_;
702   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
703   $attrs->{offset} = $self->{attrs}{offset} || 0;
704   $attrs->{offset} += $min;
705   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
706   return $self->search(undef(), $attrs);
707   #my $slice = (ref $self)->new($self->result_source, $attrs);
708   #return (wantarray ? $slice->all : $slice);
709 }
710
711 =head2 next
712
713 =over 4
714
715 =item Arguments: none
716
717 =item Return Value: $result?
718
719 =back
720
721 Returns the next element in the resultset (C<undef> is there is none).
722
723 Can be used to efficiently iterate over records in the resultset:
724
725   my $rs = $schema->resultset('CD')->search;
726   while (my $cd = $rs->next) {
727     print $cd->title;
728   }
729
730 Note that you need to store the resultset object, and call C<next> on it.
731 Calling C<< resultset('Table')->next >> repeatedly will always return the
732 first record from the resultset.
733
734 =cut
735
736 sub next {
737   my ($self) = @_;
738   if (my $cache = $self->get_cache) {
739     $self->{all_cache_position} ||= 0;
740     return $cache->[$self->{all_cache_position}++];
741   }
742   if ($self->{attrs}{cache}) {
743     $self->{all_cache_position} = 1;
744     return ($self->all)[0];
745   }
746   if ($self->{stashed_objects}) {
747     my $obj = shift(@{$self->{stashed_objects}});
748     delete $self->{stashed_objects} unless @{$self->{stashed_objects}};
749     return $obj;
750   }
751   my @row = (
752     exists $self->{stashed_row}
753       ? @{delete $self->{stashed_row}}
754       : $self->cursor->next
755   );
756   return undef unless (@row);
757   my ($row, @more) = $self->_construct_object(@row);
758   $self->{stashed_objects} = \@more if @more;
759   return $row;
760 }
761
762 sub _construct_object {
763   my ($self, @row) = @_;
764   my $info = $self->_collapse_result($self->{_attrs}{as}, \@row);
765   my @new = $self->result_class->inflate_result($self->result_source, @$info);
766   @new = $self->{_attrs}{record_filter}->(@new)
767     if exists $self->{_attrs}{record_filter};
768   return @new;
769 }
770
771 sub _collapse_result {
772   my ($self, $as_proto, $row) = @_;
773
774   my @copy = @$row;
775
776   # 'foo'         => [ undef, 'foo' ]
777   # 'foo.bar'     => [ 'foo', 'bar' ]
778   # 'foo.bar.baz' => [ 'foo.bar', 'baz' ]
779
780   my @construct_as = map { [ (/^(?:(.*)\.)?([^.]+)$/) ] } @$as_proto;
781
782   my %collapse = %{$self->{_attrs}{collapse}||{}};
783
784   my @pri_index;
785
786   # if we're doing collapsing (has_many prefetch) we need to grab records
787   # until the PK changes, so fill @pri_index. if not, we leave it empty so
788   # we know we don't have to bother.
789
790   # the reason for not using the collapse stuff directly is because if you
791   # had for e.g. two artists in a row with no cds, the collapse info for
792   # both would be NULL (undef) so you'd lose the second artist
793
794   # store just the index so we can check the array positions from the row
795   # without having to contruct the full hash
796
797   if (keys %collapse) {
798     my %pri = map { ($_ => 1) } $self->result_source->primary_columns;
799     foreach my $i (0 .. $#construct_as) {
800       next if defined($construct_as[$i][0]); # only self table
801       if (delete $pri{$construct_as[$i][1]}) {
802         push(@pri_index, $i);
803       }
804       last unless keys %pri; # short circuit (Johnny Five Is Alive!)
805     }
806   }
807
808   # no need to do an if, it'll be empty if @pri_index is empty anyway
809
810   my %pri_vals = map { ($_ => $copy[$_]) } @pri_index;
811
812   my @const_rows;
813
814   do { # no need to check anything at the front, we always want the first row
815
816     my %const;
817   
818     foreach my $this_as (@construct_as) {
819       $const{$this_as->[0]||''}{$this_as->[1]} = shift(@copy);
820     }
821
822     push(@const_rows, \%const);
823
824   } until ( # no pri_index => no collapse => drop straight out
825       !@pri_index
826     or
827       do { # get another row, stash it, drop out if different PK
828
829         @copy = $self->cursor->next;
830         $self->{stashed_row} = \@copy;
831
832         # last thing in do block, counts as true if anything doesn't match
833
834         # check xor defined first for NULL vs. NOT NULL then if one is
835         # defined the other must be so check string equality
836
837         grep {
838           (defined $pri_vals{$_} ^ defined $copy[$_])
839           || (defined $pri_vals{$_} && ($pri_vals{$_} ne $copy[$_]))
840         } @pri_index;
841       }
842   );
843
844   my $alias = $self->{attrs}{alias};
845   my $info = [];
846
847   my %collapse_pos;
848
849   my @const_keys;
850
851   foreach my $const (@const_rows) {
852     scalar @const_keys or do {
853       @const_keys = sort { length($a) <=> length($b) } keys %$const;
854     };
855     foreach my $key (@const_keys) {
856       if (length $key) {
857         my $target = $info;
858         my @parts = split(/\./, $key);
859         my $cur = '';
860         my $data = $const->{$key};
861         foreach my $p (@parts) {
862           $target = $target->[1]->{$p} ||= [];
863           $cur .= ".${p}";
864           if ($cur eq ".${key}" && (my @ckey = @{$collapse{$cur}||[]})) { 
865             # collapsing at this point and on final part
866             my $pos = $collapse_pos{$cur};
867             CK: foreach my $ck (@ckey) {
868               if (!defined $pos->{$ck} || $pos->{$ck} ne $data->{$ck}) {
869                 $collapse_pos{$cur} = $data;
870                 delete @collapse_pos{ # clear all positioning for sub-entries
871                   grep { m/^\Q${cur}.\E/ } keys %collapse_pos
872                 };
873                 push(@$target, []);
874                 last CK;
875               }
876             }
877           }
878           if (exists $collapse{$cur}) {
879             $target = $target->[-1];
880           }
881         }
882         $target->[0] = $data;
883       } else {
884         $info->[0] = $const->{$key};
885       }
886     }
887   }
888
889   return $info;
890 }
891
892 =head2 result_source
893
894 =over 4
895
896 =item Arguments: $result_source?
897
898 =item Return Value: $result_source
899
900 =back
901
902 An accessor for the primary ResultSource object from which this ResultSet
903 is derived.
904
905 =head2 result_class
906
907 =over 4
908
909 =item Arguments: $result_class?
910
911 =item Return Value: $result_class
912
913 =back
914
915 An accessor for the class to use when creating row objects. Defaults to 
916 C<< result_source->result_class >> - which in most cases is the name of the 
917 L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class.
918
919 =cut
920
921
922 =head2 count
923
924 =over 4
925
926 =item Arguments: $cond, \%attrs??
927
928 =item Return Value: $count
929
930 =back
931
932 Performs an SQL C<COUNT> with the same query as the resultset was built
933 with to find the number of elements. If passed arguments, does a search
934 on the resultset and counts the results of that.
935
936 Note: When using C<count> with C<group_by>, L<DBIx::Class> emulates C<GROUP BY>
937 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
938 not support C<DISTINCT> with multiple columns. If you are using such a
939 database, you should only use columns from the main table in your C<group_by>
940 clause.
941
942 =cut
943
944 sub count {
945   my $self = shift;
946   return $self->search(@_)->count if @_ and defined $_[0];
947   return scalar @{ $self->get_cache } if $self->get_cache;
948   my $count = $self->_count;
949   return 0 unless $count;
950
951   # need to take offset from resolved attrs
952
953   $count -= $self->{_attrs}{offset} if $self->{_attrs}{offset};
954   $count = $self->{attrs}{rows} if
955     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
956   $count = 0 if ($count < 0);
957   return $count;
958 }
959
960 sub _count { # Separated out so pager can get the full count
961   my $self = shift;
962   my $select = { count => '*' };
963
964   my $attrs = { %{$self->_resolved_attrs} };
965   if (my $group_by = delete $attrs->{group_by}) {
966     delete $attrs->{having};
967     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
968     # todo: try CONCAT for multi-column pk
969     my @pk = $self->result_source->primary_columns;
970     if (@pk == 1) {
971       my $alias = $attrs->{alias};
972       foreach my $column (@distinct) {
973         if ($column =~ qr/^(?:\Q${alias}.\E)?$pk[0]$/) {
974           @distinct = ($column);
975           last;
976         }
977       }
978     }
979
980     $select = { count => { distinct => \@distinct } };
981   }
982
983   $attrs->{select} = $select;
984   $attrs->{as} = [qw/count/];
985
986   # offset, order by and page are not needed to count. record_filter is cdbi
987   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
988
989   my $tmp_rs = (ref $self)->new($self->result_source, $attrs);
990   my ($count) = $tmp_rs->cursor->next;
991   return $count;
992 }
993
994 sub _bool {
995   return 1;
996 }
997
998 =head2 count_literal
999
1000 =over 4
1001
1002 =item Arguments: $sql_fragment, @bind_values
1003
1004 =item Return Value: $count
1005
1006 =back
1007
1008 Counts the results in a literal query. Equivalent to calling L</search_literal>
1009 with the passed arguments, then L</count>.
1010
1011 =cut
1012
1013 sub count_literal { shift->search_literal(@_)->count; }
1014
1015 =head2 all
1016
1017 =over 4
1018
1019 =item Arguments: none
1020
1021 =item Return Value: @objects
1022
1023 =back
1024
1025 Returns all elements in the resultset. Called implicitly if the resultset
1026 is returned in list context.
1027
1028 =cut
1029
1030 sub all {
1031   my ($self) = @_;
1032   return @{ $self->get_cache } if $self->get_cache;
1033
1034   my @obj;
1035
1036   # TODO: don't call resolve here
1037   if (keys %{$self->_resolved_attrs->{collapse}}) {
1038 #  if ($self->{attrs}{prefetch}) {
1039       # Using $self->cursor->all is really just an optimisation.
1040       # If we're collapsing has_many prefetches it probably makes
1041       # very little difference, and this is cleaner than hacking
1042       # _construct_object to survive the approach
1043     my @row = $self->cursor->next;
1044     while (@row) {
1045       push(@obj, $self->_construct_object(@row));
1046       @row = (exists $self->{stashed_row}
1047                ? @{delete $self->{stashed_row}}
1048                : $self->cursor->next);
1049     }
1050   } else {
1051     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
1052   }
1053
1054   $self->set_cache(\@obj) if $self->{attrs}{cache};
1055   return @obj;
1056 }
1057
1058 =head2 reset
1059
1060 =over 4
1061
1062 =item Arguments: none
1063
1064 =item Return Value: $self
1065
1066 =back
1067
1068 Resets the resultset's cursor, so you can iterate through the elements again.
1069
1070 =cut
1071
1072 sub reset {
1073   my ($self) = @_;
1074   delete $self->{_attrs} if exists $self->{_attrs};
1075   $self->{all_cache_position} = 0;
1076   $self->cursor->reset;
1077   return $self;
1078 }
1079
1080 =head2 first
1081
1082 =over 4
1083
1084 =item Arguments: none
1085
1086 =item Return Value: $object?
1087
1088 =back
1089
1090 Resets the resultset and returns an object for the first result (if the
1091 resultset returns anything).
1092
1093 =cut
1094
1095 sub first {
1096   return $_[0]->reset->next;
1097 }
1098
1099 # _cond_for_update_delete
1100 #
1101 # update/delete require the condition to be modified to handle
1102 # the differing SQL syntax available.  This transforms the $self->{cond}
1103 # appropriately, returning the new condition.
1104
1105 sub _cond_for_update_delete {
1106   my ($self, $full_cond) = @_;
1107   my $cond = {};
1108
1109   $full_cond ||= $self->{cond};
1110   # No-op. No condition, we're updating/deleting everything
1111   return $cond unless ref $full_cond;
1112
1113   if (ref $full_cond eq 'ARRAY') {
1114     $cond = [
1115       map {
1116         my %hash;
1117         foreach my $key (keys %{$_}) {
1118           $key =~ /([^.]+)$/;
1119           $hash{$1} = $_->{$key};
1120         }
1121         \%hash;
1122       } @{$full_cond}
1123     ];
1124   }
1125   elsif (ref $full_cond eq 'HASH') {
1126     if ((keys %{$full_cond})[0] eq '-and') {
1127       $cond->{-and} = [];
1128
1129       my @cond = @{$full_cond->{-and}};
1130       for (my $i = 0; $i < @cond; $i++) {
1131         my $entry = $cond[$i];
1132
1133         my $hash;
1134         if (ref $entry eq 'HASH') {
1135           $hash = $self->_cond_for_update_delete($entry);
1136         }
1137         else {
1138           $entry =~ /([^.]+)$/;
1139           $hash->{$1} = $cond[++$i];
1140         }
1141
1142         push @{$cond->{-and}}, $hash;
1143       }
1144     }
1145     else {
1146       foreach my $key (keys %{$full_cond}) {
1147         $key =~ /([^.]+)$/;
1148         $cond->{$1} = $full_cond->{$key};
1149       }
1150     }
1151   }
1152   else {
1153     $self->throw_exception(
1154       "Can't update/delete on resultset with condition unless hash or array"
1155     );
1156   }
1157
1158   return $cond;
1159 }
1160
1161
1162 =head2 update
1163
1164 =over 4
1165
1166 =item Arguments: \%values
1167
1168 =item Return Value: $storage_rv
1169
1170 =back
1171
1172 Sets the specified columns in the resultset to the supplied values in a
1173 single query. Return value will be true if the update succeeded or false
1174 if no records were updated; exact type of success value is storage-dependent.
1175
1176 =cut
1177
1178 sub update {
1179   my ($self, $values) = @_;
1180   $self->throw_exception("Values for update must be a hash")
1181     unless ref $values eq 'HASH';
1182
1183   my $cond = $self->_cond_for_update_delete;
1184    
1185   return $self->result_source->storage->update(
1186     $self->result_source, $values, $cond
1187   );
1188 }
1189
1190 =head2 update_all
1191
1192 =over 4
1193
1194 =item Arguments: \%values
1195
1196 =item Return Value: 1
1197
1198 =back
1199
1200 Fetches all objects and updates them one at a time. Note that C<update_all>
1201 will run DBIC cascade triggers, while L</update> will not.
1202
1203 =cut
1204
1205 sub update_all {
1206   my ($self, $values) = @_;
1207   $self->throw_exception("Values for update must be a hash")
1208     unless ref $values eq 'HASH';
1209   foreach my $obj ($self->all) {
1210     $obj->set_columns($values)->update;
1211   }
1212   return 1;
1213 }
1214
1215 =head2 delete
1216
1217 =over 4
1218
1219 =item Arguments: none
1220
1221 =item Return Value: 1
1222
1223 =back
1224
1225 Deletes the contents of the resultset from its result source. Note that this
1226 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1227 to run. See also L<DBIx::Class::Row/delete>.
1228
1229 =cut
1230
1231 sub delete {
1232   my ($self) = @_;
1233
1234   my $cond = $self->_cond_for_update_delete;
1235
1236   $self->result_source->storage->delete($self->result_source, $cond);
1237   return 1;
1238 }
1239
1240 =head2 delete_all
1241
1242 =over 4
1243
1244 =item Arguments: none
1245
1246 =item Return Value: 1
1247
1248 =back
1249
1250 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1251 will run DBIC cascade triggers, while L</delete> will not.
1252
1253 =cut
1254
1255 sub delete_all {
1256   my ($self) = @_;
1257   $_->delete for $self->all;
1258   return 1;
1259 }
1260
1261 =head2 populate
1262
1263 =over 4
1264
1265 =item Arguments: \@data;
1266
1267 =back
1268
1269 Pass an arrayref of hashrefs. Each hashref should be a structure suitable for
1270 submitting to a $resultset->create(...) method.
1271
1272 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
1273 to insert the data, as this is a faster method.  
1274
1275 Otherwise, each set of data is inserted into the database using
1276 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
1277 objects is returned.
1278
1279 Example:  Assuming an Artist Class that has many CDs Classes relating:
1280
1281   my $Artist_rs = $schema->resultset("Artist");
1282   
1283   ## Void Context Example 
1284   $Artist_rs->populate([
1285      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1286         { title => 'My First CD', year => 2006 },
1287         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1288       ],
1289      },
1290      { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
1291         { title => 'My parents sold me to a record company' ,year => 2005 },
1292         { title => 'Why Am I So Ugly?', year => 2006 },
1293         { title => 'I Got Surgery and am now Popular', year => 2007 }
1294       ],
1295      },
1296   ]);
1297   
1298   ## Array Context Example
1299   my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
1300     { name => "Artist One"},
1301     { name => "Artist Two"},
1302     { name => "Artist Three", cds=> [
1303     { title => "First CD", year => 2007},
1304     { title => "Second CD", year => 2008},
1305   ]}
1306   ]);
1307   
1308   print $ArtistOne->name; ## response is 'Artist One'
1309   print $ArtistThree->cds->count ## reponse is '2'
1310   
1311 Please note an important effect on your data when choosing between void and
1312 wantarray context. Since void context goes straight to C<insert_bulk> in 
1313 L<DBIx::Class::Storage::DBI> this will skip any component that is overriding
1314 c<insert>.  So if you are using something like L<DBIx-Class-UUIDColumns> to 
1315 create primary keys for you, you will find that your PKs are empty.  In this 
1316 case you will have to use the wantarray context in order to create those 
1317 values.
1318
1319 =cut
1320
1321 sub populate {
1322   my ($self, $data) = @_;
1323   
1324   if(defined wantarray) {
1325     my @created;
1326     foreach my $item (@$data) {
1327       push(@created, $self->create($item));
1328     }
1329     return @created;
1330   } else {
1331     my ($first, @rest) = @$data;
1332
1333     my @names = grep {!ref $first->{$_}} keys %$first;
1334     my @rels = grep { $self->result_source->has_relationship($_) } keys %$first;
1335     my @pks = $self->result_source->primary_columns;  
1336
1337     ## do the belongs_to relationships  
1338     foreach my $index (0..$#$data) {
1339       if( grep { !defined $data->[$index]->{$_} } @pks ) {
1340         my @ret = $self->populate($data);
1341         return;
1342       }
1343     
1344       foreach my $rel (@rels) {
1345         next unless $data->[$index]->{$rel} && ref $data->[$index]->{$rel} eq "HASH";
1346         my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
1347         my ($reverse) = keys %{$self->result_source->reverse_relationship_info($rel)};
1348         my $related = $result->result_source->resolve_condition(
1349           $result->result_source->relationship_info($reverse)->{cond},
1350           $self,        
1351           $result,        
1352         );
1353
1354         delete $data->[$index]->{$rel};
1355         $data->[$index] = {%{$data->[$index]}, %$related};
1356       
1357         push @names, keys %$related if $index == 0;
1358       }
1359     }
1360
1361     ## do bulk insert on current row
1362     my @values = map { [ @$_{@names} ] } @$data;
1363
1364     $self->result_source->storage->insert_bulk(
1365       $self->result_source, 
1366       \@names, 
1367       \@values,
1368     );
1369
1370     ## do the has_many relationships
1371     foreach my $item (@$data) {
1372
1373       foreach my $rel (@rels) {
1374         next unless $item->{$rel} && ref $item->{$rel} eq "ARRAY";
1375
1376         my $parent = $self->find(map {{$_=>$item->{$_}} } @pks) 
1377      || $self->throw_exception('Cannot find the relating object.');
1378      
1379         my $child = $parent->$rel;
1380     
1381         my $related = $child->result_source->resolve_condition(
1382           $parent->result_source->relationship_info($rel)->{cond},
1383           $child,
1384           $parent,
1385         );
1386
1387         my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
1388         my @populate = map { {%$_, %$related} } @rows_to_add;
1389
1390         $child->populate( \@populate );
1391       }
1392     }
1393   }
1394 }
1395
1396 =head2 pager
1397
1398 =over 4
1399
1400 =item Arguments: none
1401
1402 =item Return Value: $pager
1403
1404 =back
1405
1406 Return Value a L<Data::Page> object for the current resultset. Only makes
1407 sense for queries with a C<page> attribute.
1408
1409 =cut
1410
1411 sub pager {
1412   my ($self) = @_;
1413   my $attrs = $self->{attrs};
1414   $self->throw_exception("Can't create pager for non-paged rs")
1415     unless $self->{attrs}{page};
1416   $attrs->{rows} ||= 10;
1417   return $self->{pager} ||= Data::Page->new(
1418     $self->_count, $attrs->{rows}, $self->{attrs}{page});
1419 }
1420
1421 =head2 page
1422
1423 =over 4
1424
1425 =item Arguments: $page_number
1426
1427 =item Return Value: $rs
1428
1429 =back
1430
1431 Returns a resultset for the $page_number page of the resultset on which page
1432 is called, where each page contains a number of rows equal to the 'rows'
1433 attribute set on the resultset (10 by default).
1434
1435 =cut
1436
1437 sub page {
1438   my ($self, $page) = @_;
1439   return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
1440 }
1441
1442 =head2 new_result
1443
1444 =over 4
1445
1446 =item Arguments: \%vals
1447
1448 =item Return Value: $object
1449
1450 =back
1451
1452 Creates a new row object in the resultset's result class and returns
1453 it. The row is not inserted into the database at this point, call
1454 L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
1455 will tell you whether the row object has been inserted or not.
1456
1457 Passes the hashref of input on to L<DBIx::Class::Row/new>.
1458
1459 =cut
1460
1461 sub new_result {
1462   my ($self, $values) = @_;
1463   $self->throw_exception( "new_result needs a hash" )
1464     unless (ref $values eq 'HASH');
1465   $self->throw_exception(
1466     "Can't abstract implicit construct, condition not a hash"
1467   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1468
1469   my $alias = $self->{attrs}{alias};
1470   my $collapsed_cond = $self->{cond} ? $self->_collapse_cond($self->{cond}) : {};
1471
1472   # precendence must be given to passed values over values inherited from the cond, 
1473   # so the order here is important.
1474   my %new = (
1475     %{ $self->_remove_alias($collapsed_cond, $alias) },
1476     %{ $self->_remove_alias($values, $alias) },
1477     -source_handle => $self->_source_handle,
1478     -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
1479   );
1480
1481   return $self->result_class->new(\%new);
1482 }
1483
1484 # _collapse_cond
1485 #
1486 # Recursively collapse the condition.
1487
1488 sub _collapse_cond {
1489   my ($self, $cond, $collapsed) = @_;
1490
1491   $collapsed ||= {};
1492
1493   if (ref $cond eq 'ARRAY') {
1494     foreach my $subcond (@$cond) {
1495       next unless ref $subcond;  # -or
1496 #      warn "ARRAY: " . Dumper $subcond;
1497       $collapsed = $self->_collapse_cond($subcond, $collapsed);
1498     }
1499   }
1500   elsif (ref $cond eq 'HASH') {
1501     if (keys %$cond and (keys %$cond)[0] eq '-and') {
1502       foreach my $subcond (@{$cond->{-and}}) {
1503 #        warn "HASH: " . Dumper $subcond;
1504         $collapsed = $self->_collapse_cond($subcond, $collapsed);
1505       }
1506     }
1507     else {
1508 #      warn "LEAF: " . Dumper $cond;
1509       foreach my $col (keys %$cond) {
1510         my $value = $cond->{$col};
1511         $collapsed->{$col} = $value;
1512       }
1513     }
1514   }
1515
1516   return $collapsed;
1517 }
1518
1519 # _remove_alias
1520 #
1521 # Remove the specified alias from the specified query hash. A copy is made so
1522 # the original query is not modified.
1523
1524 sub _remove_alias {
1525   my ($self, $query, $alias) = @_;
1526
1527   my %orig = %{ $query || {} };
1528   my %unaliased;
1529
1530   foreach my $key (keys %orig) {
1531     if ($key !~ /\./) {
1532       $unaliased{$key} = $orig{$key};
1533       next;
1534     }
1535     $unaliased{$1} = $orig{$key}
1536       if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
1537   }
1538
1539   return \%unaliased;
1540 }
1541
1542 =head2 find_or_new
1543
1544 =over 4
1545
1546 =item Arguments: \%vals, \%attrs?
1547
1548 =item Return Value: $object
1549
1550 =back
1551
1552 Find an existing record from this resultset. If none exists, instantiate a new
1553 result object and return it. The object will not be saved into your storage
1554 until you call L<DBIx::Class::Row/insert> on it.
1555
1556 If you want objects to be saved immediately, use L</find_or_create> instead.
1557
1558 =cut
1559
1560 sub find_or_new {
1561   my $self     = shift;
1562   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1563   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1564   my $exists   = $self->find($hash, $attrs);
1565   return defined $exists ? $exists : $self->new_result($hash);
1566 }
1567
1568 =head2 create
1569
1570 =over 4
1571
1572 =item Arguments: \%vals
1573
1574 =item Return Value: a L<DBIx::Class::Row> $object
1575
1576 =back
1577
1578 Attempt to create a single new row or a row with multiple related rows
1579 in the table represented by the resultset (and related tables). This
1580 will not check for duplicate rows before inserting, use
1581 L</find_or_create> to do that.
1582
1583 To create one row for this resultset, pass a hashref of key/value
1584 pairs representing the columns of the table and the values you wish to
1585 store. If the appropriate relationships are set up, foreign key fields
1586 can also be passed an object representing the foreign row, and the
1587 value will be set to it's primary key.
1588
1589 To create related objects, pass a hashref for the value if the related
1590 item is a foreign key relationship (L<DBIx::Class::Relationship/belongs_to>),
1591 and use the name of the relationship as the key. (NOT the name of the field,
1592 necessarily). For C<has_many> and C<has_one> relationships, pass an arrayref
1593 of hashrefs containing the data for each of the rows to create in the foreign
1594 tables, again using the relationship name as the key.
1595
1596 Instead of hashrefs of plain related data (key/value pairs), you may
1597 also pass new or inserted objects. New objects (not inserted yet, see
1598 L</new>), will be inserted into their appropriate tables.
1599
1600 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1601
1602 Example of creating a new row.
1603
1604   $person_rs->create({
1605     name=>"Some Person",
1606         email=>"somebody@someplace.com"
1607   });
1608   
1609 Example of creating a new row and also creating rows in a related C<has_many>
1610 or C<has_one> resultset.  Note Arrayref.
1611
1612   $artist_rs->create(
1613      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1614         { title => 'My First CD', year => 2006 },
1615         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1616       ],
1617      },
1618   );
1619
1620 Example of creating a new row and also creating a row in a related
1621 C<belongs_to>resultset. Note Hashref.
1622
1623   $cd_rs->create({
1624     title=>"Music for Silly Walks",
1625         year=>2000,
1626         artist => {
1627           name=>"Silly Musician",
1628         }
1629   });
1630
1631 =cut
1632
1633 sub create {
1634   my ($self, $attrs) = @_;
1635   $self->throw_exception( "create needs a hashref" )
1636     unless ref $attrs eq 'HASH';
1637   return $self->new_result($attrs)->insert;
1638 }
1639
1640 =head2 find_or_create
1641
1642 =over 4
1643
1644 =item Arguments: \%vals, \%attrs?
1645
1646 =item Return Value: $object
1647
1648 =back
1649
1650   $class->find_or_create({ key => $val, ... });
1651
1652 Tries to find a record based on its primary key or unique constraint; if none
1653 is found, creates one and returns that instead.
1654
1655   my $cd = $schema->resultset('CD')->find_or_create({
1656     cdid   => 5,
1657     artist => 'Massive Attack',
1658     title  => 'Mezzanine',
1659     year   => 2005,
1660   });
1661
1662 Also takes an optional C<key> attribute, to search by a specific key or unique
1663 constraint. For example:
1664
1665   my $cd = $schema->resultset('CD')->find_or_create(
1666     {
1667       artist => 'Massive Attack',
1668       title  => 'Mezzanine',
1669     },
1670     { key => 'cd_artist_title' }
1671   );
1672
1673 See also L</find> and L</update_or_create>. For information on how to declare
1674 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1675
1676 =cut
1677
1678 sub find_or_create {
1679   my $self     = shift;
1680   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1681   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1682   my $exists   = $self->find($hash, $attrs);
1683   return defined $exists ? $exists : $self->create($hash);
1684 }
1685
1686 =head2 update_or_create
1687
1688 =over 4
1689
1690 =item Arguments: \%col_values, { key => $unique_constraint }?
1691
1692 =item Return Value: $object
1693
1694 =back
1695
1696   $class->update_or_create({ col => $val, ... });
1697
1698 First, searches for an existing row matching one of the unique constraints
1699 (including the primary key) on the source of this resultset. If a row is
1700 found, updates it with the other given column values. Otherwise, creates a new
1701 row.
1702
1703 Takes an optional C<key> attribute to search on a specific unique constraint.
1704 For example:
1705
1706   # In your application
1707   my $cd = $schema->resultset('CD')->update_or_create(
1708     {
1709       artist => 'Massive Attack',
1710       title  => 'Mezzanine',
1711       year   => 1998,
1712     },
1713     { key => 'cd_artist_title' }
1714   );
1715
1716 If no C<key> is specified, it searches on all unique constraints defined on the
1717 source, including the primary key.
1718
1719 If the C<key> is specified as C<primary>, it searches only on the primary key.
1720
1721 See also L</find> and L</find_or_create>. For information on how to declare
1722 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1723
1724 =cut
1725
1726 sub update_or_create {
1727   my $self = shift;
1728   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1729   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
1730
1731   my $row = $self->find($cond, $attrs);
1732   if (defined $row) {
1733     $row->update($cond);
1734     return $row;
1735   }
1736
1737   return $self->create($cond);
1738 }
1739
1740 =head2 get_cache
1741
1742 =over 4
1743
1744 =item Arguments: none
1745
1746 =item Return Value: \@cache_objects?
1747
1748 =back
1749
1750 Gets the contents of the cache for the resultset, if the cache is set.
1751
1752 =cut
1753
1754 sub get_cache {
1755   shift->{all_cache};
1756 }
1757
1758 =head2 set_cache
1759
1760 =over 4
1761
1762 =item Arguments: \@cache_objects
1763
1764 =item Return Value: \@cache_objects
1765
1766 =back
1767
1768 Sets the contents of the cache for the resultset. Expects an arrayref
1769 of objects of the same class as those produced by the resultset. Note that
1770 if the cache is set the resultset will return the cached objects rather
1771 than re-querying the database even if the cache attr is not set.
1772
1773 =cut
1774
1775 sub set_cache {
1776   my ( $self, $data ) = @_;
1777   $self->throw_exception("set_cache requires an arrayref")
1778       if defined($data) && (ref $data ne 'ARRAY');
1779   $self->{all_cache} = $data;
1780 }
1781
1782 =head2 clear_cache
1783
1784 =over 4
1785
1786 =item Arguments: none
1787
1788 =item Return Value: []
1789
1790 =back
1791
1792 Clears the cache for the resultset.
1793
1794 =cut
1795
1796 sub clear_cache {
1797   shift->set_cache(undef);
1798 }
1799
1800 =head2 related_resultset
1801
1802 =over 4
1803
1804 =item Arguments: $relationship_name
1805
1806 =item Return Value: $resultset
1807
1808 =back
1809
1810 Returns a related resultset for the supplied relationship name.
1811
1812   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1813
1814 =cut
1815
1816 sub related_resultset {
1817   my ($self, $rel) = @_;
1818
1819   $self->{related_resultsets} ||= {};
1820   return $self->{related_resultsets}{$rel} ||= do {
1821     my $rel_obj = $self->result_source->relationship_info($rel);
1822
1823     $self->throw_exception(
1824       "search_related: result source '" . $self->result_source->source_name .
1825         "' has no such relationship $rel")
1826       unless $rel_obj;
1827     
1828     my ($from,$seen) = $self->_resolve_from($rel);
1829
1830     my $join_count = $seen->{$rel};
1831     my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
1832
1833     #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
1834     my %attrs = %{$self->{attrs}||{}};
1835     delete @attrs{qw(result_class alias)};
1836
1837     my $new_cache;
1838
1839     if (my $cache = $self->get_cache) {
1840       if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
1841         $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
1842                         @$cache ];
1843       }
1844     }
1845
1846     my $rel_source = $self->result_source->related_source($rel);
1847
1848     my $new = do {
1849
1850       # The reason we do this now instead of passing the alias to the
1851       # search_rs below is that if you wrap/overload resultset on the
1852       # source you need to know what alias it's -going- to have for things
1853       # to work sanely (e.g. RestrictWithObject wants to be able to add
1854       # extra query restrictions, and these may need to be $alias.)
1855
1856       my $attrs = $rel_source->resultset_attributes;
1857       local $attrs->{alias} = $alias;
1858
1859       $rel_source->resultset
1860                  ->search_rs(
1861                      undef, {
1862                        %attrs,
1863                        join => undef,
1864                        prefetch => undef,
1865                        select => undef,
1866                        as => undef,
1867                        where => $self->{cond},
1868                        seen_join => $seen,
1869                        from => $from,
1870                    });
1871     };
1872     $new->set_cache($new_cache) if $new_cache;
1873     $new;
1874   };
1875 }
1876
1877 sub _resolve_from {
1878   my ($self, $extra_join) = @_;
1879   my $source = $self->result_source;
1880   my $attrs = $self->{attrs};
1881   
1882   my $from = $attrs->{from}
1883     || [ { $attrs->{alias} => $source->from } ];
1884     
1885   my $seen = { %{$attrs->{seen_join}||{}} };
1886
1887   my $join = ($attrs->{join}
1888                ? [ $attrs->{join}, $extra_join ]
1889                : $extra_join);
1890
1891   # we need to take the prefetch the attrs into account before we 
1892   # ->resolve_join as otherwise they get lost - captainL
1893   my $merged = $self->_merge_attr( $join, $attrs->{prefetch} );
1894
1895   $from = [
1896     @$from,
1897     ($join ? $source->resolve_join($merged, $attrs->{alias}, $seen) : ()),
1898   ];
1899
1900   return ($from,$seen);
1901 }
1902
1903 sub _resolved_attrs {
1904   my $self = shift;
1905   return $self->{_attrs} if $self->{_attrs};
1906
1907   my $attrs = { %{$self->{attrs}||{}} };
1908   my $source = $self->result_source;
1909   my $alias = $attrs->{alias};
1910
1911   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
1912   if ($attrs->{columns}) {
1913     delete $attrs->{as};
1914   } elsif (!$attrs->{select}) {
1915     $attrs->{columns} = [ $source->columns ];
1916   }
1917  
1918   $attrs->{select} = 
1919     ($attrs->{select}
1920       ? (ref $attrs->{select} eq 'ARRAY'
1921           ? [ @{$attrs->{select}} ]
1922           : [ $attrs->{select} ])
1923       : [ map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}} ]
1924     );
1925   $attrs->{as} =
1926     ($attrs->{as}
1927       ? (ref $attrs->{as} eq 'ARRAY'
1928           ? [ @{$attrs->{as}} ]
1929           : [ $attrs->{as} ])
1930       : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}} ]
1931     );
1932   
1933   my $adds;
1934   if ($adds = delete $attrs->{include_columns}) {
1935     $adds = [$adds] unless ref $adds eq 'ARRAY';
1936     push(@{$attrs->{select}}, @$adds);
1937     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1 } @$adds);
1938   }
1939   if ($adds = delete $attrs->{'+select'}) {
1940     $adds = [$adds] unless ref $adds eq 'ARRAY';
1941     push(@{$attrs->{select}},
1942            map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds);
1943   }
1944   if (my $adds = delete $attrs->{'+as'}) {
1945     $adds = [$adds] unless ref $adds eq 'ARRAY';
1946     push(@{$attrs->{as}}, @$adds);
1947   }
1948
1949   $attrs->{from} ||= [ { 'me' => $source->from } ];
1950
1951   if (exists $attrs->{join} || exists $attrs->{prefetch}) {
1952     my $join = delete $attrs->{join} || {};
1953
1954     if (defined $attrs->{prefetch}) {
1955       $join = $self->_merge_attr(
1956         $join, $attrs->{prefetch}
1957       );
1958       
1959     }
1960
1961     $attrs->{from} =   # have to copy here to avoid corrupting the original
1962       [
1963         @{$attrs->{from}}, 
1964         $source->resolve_join($join, $alias, { %{$attrs->{seen_join}||{}} })
1965       ];
1966
1967   }
1968
1969   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
1970   if ($attrs->{order_by}) {
1971     $attrs->{order_by} = (ref($attrs->{order_by}) eq 'ARRAY'
1972                            ? [ @{$attrs->{order_by}} ]
1973                            : [ $attrs->{order_by} ]);
1974   } else {
1975     $attrs->{order_by} = [];    
1976   }
1977
1978   my $collapse = $attrs->{collapse} || {};
1979   if (my $prefetch = delete $attrs->{prefetch}) {
1980     $prefetch = $self->_merge_attr({}, $prefetch);
1981     my @pre_order;
1982     my $seen = $attrs->{seen_join} || {};
1983     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
1984       # bring joins back to level of current class
1985       my @prefetch = $source->resolve_prefetch(
1986         $p, $alias, $seen, \@pre_order, $collapse
1987       );
1988       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
1989       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
1990     }
1991     push(@{$attrs->{order_by}}, @pre_order);
1992   }
1993   $attrs->{collapse} = $collapse;
1994
1995   if ($attrs->{page}) {
1996     $attrs->{offset} ||= 0;
1997     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
1998   }
1999
2000   return $self->{_attrs} = $attrs;
2001 }
2002
2003 sub _rollout_attr {
2004   my ($self, $attr) = @_;
2005   
2006   if (ref $attr eq 'HASH') {
2007     return $self->_rollout_hash($attr);
2008   } elsif (ref $attr eq 'ARRAY') {
2009     return $self->_rollout_array($attr);
2010   } else {
2011     return [$attr];
2012   }
2013 }
2014
2015 sub _rollout_array {
2016   my ($self, $attr) = @_;
2017
2018   my @rolled_array;
2019   foreach my $element (@{$attr}) {
2020     if (ref $element eq 'HASH') {
2021       push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
2022     } elsif (ref $element eq 'ARRAY') {
2023       #  XXX - should probably recurse here
2024       push( @rolled_array, @{$self->_rollout_array($element)} );
2025     } else {
2026       push( @rolled_array, $element );
2027     }
2028   }
2029   return \@rolled_array;
2030 }
2031
2032 sub _rollout_hash {
2033   my ($self, $attr) = @_;
2034
2035   my @rolled_array;
2036   foreach my $key (keys %{$attr}) {
2037     push( @rolled_array, { $key => $attr->{$key} } );
2038   }
2039   return \@rolled_array;
2040 }
2041
2042 sub _calculate_score {
2043   my ($self, $a, $b) = @_;
2044
2045   if (ref $b eq 'HASH') {
2046     my ($b_key) = keys %{$b};
2047     if (ref $a eq 'HASH') {
2048       my ($a_key) = keys %{$a};
2049       if ($a_key eq $b_key) {
2050         return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
2051       } else {
2052         return 0;
2053       }
2054     } else {
2055       return ($a eq $b_key) ? 1 : 0;
2056     }       
2057   } else {
2058     if (ref $a eq 'HASH') {
2059       my ($a_key) = keys %{$a};
2060       return ($b eq $a_key) ? 1 : 0;
2061     } else {
2062       return ($b eq $a) ? 1 : 0;
2063     }
2064   }
2065 }
2066
2067 sub _merge_attr {
2068   my ($self, $a, $b) = @_;
2069
2070   return $b unless defined($a);
2071   return $a unless defined($b);
2072   
2073   $a = $self->_rollout_attr($a);
2074   $b = $self->_rollout_attr($b);
2075
2076   my $seen_keys;
2077   foreach my $b_element ( @{$b} ) {
2078     # find best candidate from $a to merge $b_element into
2079     my $best_candidate = { position => undef, score => 0 }; my $position = 0;
2080     foreach my $a_element ( @{$a} ) {
2081       my $score = $self->_calculate_score( $a_element, $b_element );
2082       if ($score > $best_candidate->{score}) {
2083         $best_candidate->{position} = $position;
2084         $best_candidate->{score} = $score;
2085       }
2086       $position++;
2087     }
2088     my ($b_key) = ( ref $b_element eq 'HASH' ) ? keys %{$b_element} : ($b_element);
2089
2090     if ($best_candidate->{score} == 0 || exists $seen_keys->{$b_key}) {
2091       push( @{$a}, $b_element );
2092     } else {
2093       my $a_best = $a->[$best_candidate->{position}];
2094       # merge a_best and b_element together and replace original with merged
2095       if (ref $a_best ne 'HASH') {
2096         $a->[$best_candidate->{position}] = $b_element;
2097       } elsif (ref $b_element eq 'HASH') {
2098         my ($key) = keys %{$a_best};
2099         $a->[$best_candidate->{position}] = { $key => $self->_merge_attr($a_best->{$key}, $b_element->{$key}) };
2100       }
2101     }
2102     $seen_keys->{$b_key} = 1; # don't merge the same key twice
2103   }
2104
2105   return $a;
2106 }
2107
2108 sub result_source {
2109     my $self = shift;
2110
2111     if (@_) {
2112         $self->_source_handle($_[0]->handle);
2113     } else {
2114         $self->_source_handle->resolve;
2115     }
2116 }
2117
2118 =head2 throw_exception
2119
2120 See L<DBIx::Class::Schema/throw_exception> for details.
2121
2122 =cut
2123
2124 sub throw_exception {
2125   my $self=shift;
2126   $self->_source_handle->schema->throw_exception(@_);
2127 }
2128
2129 # XXX: FIXME: Attributes docs need clearing up
2130
2131 =head1 ATTRIBUTES
2132
2133 The resultset takes various attributes that modify its behavior. Here's an
2134 overview of them:
2135
2136 =head2 order_by
2137
2138 =over 4
2139
2140 =item Value: ($order_by | \@order_by)
2141
2142 =back
2143
2144 Which column(s) to order the results by. This is currently passed
2145 through directly to SQL, so you can give e.g. C<year DESC> for a
2146 descending order on the column `year'.
2147
2148 Please note that if you have C<quote_char> enabled (see
2149 L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
2150 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
2151 so you will need to manually quote things as appropriate.)
2152
2153 =head2 columns
2154
2155 =over 4
2156
2157 =item Value: \@columns
2158
2159 =back
2160
2161 Shortcut to request a particular set of columns to be retrieved.  Adds
2162 C<me.> onto the start of any column without a C<.> in it and sets C<select>
2163 from that, then auto-populates C<as> from C<select> as normal. (You may also
2164 use the C<cols> attribute, as in earlier versions of DBIC.)
2165
2166 =head2 include_columns
2167
2168 =over 4
2169
2170 =item Value: \@columns
2171
2172 =back
2173
2174 Shortcut to include additional columns in the returned results - for example
2175
2176   $schema->resultset('CD')->search(undef, {
2177     include_columns => ['artist.name'],
2178     join => ['artist']
2179   });
2180
2181 would return all CDs and include a 'name' column to the information
2182 passed to object inflation. Note that the 'artist' is the name of the
2183 column (or relationship) accessor, and 'name' is the name of the column
2184 accessor in the related table.
2185
2186 =head2 select
2187
2188 =over 4
2189
2190 =item Value: \@select_columns
2191
2192 =back
2193
2194 Indicates which columns should be selected from the storage. You can use
2195 column names, or in the case of RDBMS back ends, function or stored procedure
2196 names:
2197
2198   $rs = $schema->resultset('Employee')->search(undef, {
2199     select => [
2200       'name',
2201       { count => 'employeeid' },
2202       { sum => 'salary' }
2203     ]
2204   });
2205
2206 When you use function/stored procedure names and do not supply an C<as>
2207 attribute, the column names returned are storage-dependent. E.g. MySQL would
2208 return a column named C<count(employeeid)> in the above example.
2209
2210 =head2 +select
2211
2212 =over 4
2213
2214 Indicates additional columns to be selected from storage.  Works the same as
2215 L</select> but adds columns to the selection.
2216
2217 =back
2218
2219 =head2 +as
2220
2221 =over 4
2222
2223 Indicates additional column names for those added via L</+select>.
2224
2225 =back
2226
2227 =head2 as
2228
2229 =over 4
2230
2231 =item Value: \@inflation_names
2232
2233 =back
2234
2235 Indicates column names for object inflation. That is, C<as>
2236 indicates the name that the column can be accessed as via the
2237 C<get_column> method (or via the object accessor, B<if one already
2238 exists>).  It has nothing to do with the SQL code C<SELECT foo AS bar>.
2239
2240 The C<as> attribute is used in conjunction with C<select>,
2241 usually when C<select> contains one or more function or stored
2242 procedure names:
2243
2244   $rs = $schema->resultset('Employee')->search(undef, {
2245     select => [
2246       'name',
2247       { count => 'employeeid' }
2248     ],
2249     as => ['name', 'employee_count'],
2250   });
2251
2252   my $employee = $rs->first(); # get the first Employee
2253
2254 If the object against which the search is performed already has an accessor
2255 matching a column name specified in C<as>, the value can be retrieved using
2256 the accessor as normal:
2257
2258   my $name = $employee->name();
2259
2260 If on the other hand an accessor does not exist in the object, you need to
2261 use C<get_column> instead:
2262
2263   my $employee_count = $employee->get_column('employee_count');
2264
2265 You can create your own accessors if required - see
2266 L<DBIx::Class::Manual::Cookbook> for details.
2267
2268 Please note: This will NOT insert an C<AS employee_count> into the SQL
2269 statement produced, it is used for internal access only. Thus
2270 attempting to use the accessor in an C<order_by> clause or similar
2271 will fail miserably.
2272
2273 To get around this limitation, you can supply literal SQL to your
2274 C<select> attibute that contains the C<AS alias> text, eg:
2275
2276   select => [\'myfield AS alias']
2277
2278 =head2 join
2279
2280 =over 4
2281
2282 =item Value: ($rel_name | \@rel_names | \%rel_names)
2283
2284 =back
2285
2286 Contains a list of relationships that should be joined for this query.  For
2287 example:
2288
2289   # Get CDs by Nine Inch Nails
2290   my $rs = $schema->resultset('CD')->search(
2291     { 'artist.name' => 'Nine Inch Nails' },
2292     { join => 'artist' }
2293   );
2294
2295 Can also contain a hash reference to refer to the other relation's relations.
2296 For example:
2297
2298   package MyApp::Schema::Track;
2299   use base qw/DBIx::Class/;
2300   __PACKAGE__->table('track');
2301   __PACKAGE__->add_columns(qw/trackid cd position title/);
2302   __PACKAGE__->set_primary_key('trackid');
2303   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
2304   1;
2305
2306   # In your application
2307   my $rs = $schema->resultset('Artist')->search(
2308     { 'track.title' => 'Teardrop' },
2309     {
2310       join     => { cd => 'track' },
2311       order_by => 'artist.name',
2312     }
2313   );
2314
2315 You need to use the relationship (not the table) name in  conditions, 
2316 because they are aliased as such. The current table is aliased as "me", so 
2317 you need to use me.column_name in order to avoid ambiguity. For example:
2318
2319   # Get CDs from 1984 with a 'Foo' track 
2320   my $rs = $schema->resultset('CD')->search(
2321     { 
2322       'me.year' => 1984,
2323       'tracks.name' => 'Foo'
2324     },
2325     { join => 'tracks' }
2326   );
2327   
2328 If the same join is supplied twice, it will be aliased to <rel>_2 (and
2329 similarly for a third time). For e.g.
2330
2331   my $rs = $schema->resultset('Artist')->search({
2332     'cds.title'   => 'Down to Earth',
2333     'cds_2.title' => 'Popular',
2334   }, {
2335     join => [ qw/cds cds/ ],
2336   });
2337
2338 will return a set of all artists that have both a cd with title 'Down
2339 to Earth' and a cd with title 'Popular'.
2340
2341 If you want to fetch related objects from other tables as well, see C<prefetch>
2342 below.
2343
2344 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
2345
2346 =head2 prefetch
2347
2348 =over 4
2349
2350 =item Value: ($rel_name | \@rel_names | \%rel_names)
2351
2352 =back
2353
2354 Contains one or more relationships that should be fetched along with
2355 the main query (when they are accessed afterwards the data will
2356 already be available, without extra queries to the database).  This is
2357 useful for when you know you will need the related objects, because it
2358 saves at least one query:
2359
2360   my $rs = $schema->resultset('Tag')->search(
2361     undef,
2362     {
2363       prefetch => {
2364         cd => 'artist'
2365       }
2366     }
2367   );
2368
2369 The initial search results in SQL like the following:
2370
2371   SELECT tag.*, cd.*, artist.* FROM tag
2372   JOIN cd ON tag.cd = cd.cdid
2373   JOIN artist ON cd.artist = artist.artistid
2374
2375 L<DBIx::Class> has no need to go back to the database when we access the
2376 C<cd> or C<artist> relationships, which saves us two SQL statements in this
2377 case.
2378
2379 Simple prefetches will be joined automatically, so there is no need
2380 for a C<join> attribute in the above search. If you're prefetching to
2381 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
2382 specify the join as well.
2383
2384 C<prefetch> can be used with the following relationship types: C<belongs_to>,
2385 C<has_one> (or if you're using C<add_relationship>, any relationship declared
2386 with an accessor type of 'single' or 'filter').
2387
2388 =head2 page
2389
2390 =over 4
2391
2392 =item Value: $page
2393
2394 =back
2395
2396 Makes the resultset paged and specifies the page to retrieve. Effectively
2397 identical to creating a non-pages resultset and then calling ->page($page)
2398 on it.
2399
2400 If L<rows> attribute is not specified it defualts to 10 rows per page.
2401
2402 =head2 rows
2403
2404 =over 4
2405
2406 =item Value: $rows
2407
2408 =back
2409
2410 Specifes the maximum number of rows for direct retrieval or the number of
2411 rows per page if the page attribute or method is used.
2412
2413 =head2 offset
2414
2415 =over 4
2416
2417 =item Value: $offset
2418
2419 =back
2420
2421 Specifies the (zero-based) row number for the  first row to be returned, or the
2422 of the first row of the first page if paging is used.
2423
2424 =head2 group_by
2425
2426 =over 4
2427
2428 =item Value: \@columns
2429
2430 =back
2431
2432 A arrayref of columns to group by. Can include columns of joined tables.
2433
2434   group_by => [qw/ column1 column2 ... /]
2435
2436 =head2 having
2437
2438 =over 4
2439
2440 =item Value: $condition
2441
2442 =back
2443
2444 HAVING is a select statement attribute that is applied between GROUP BY and
2445 ORDER BY. It is applied to the after the grouping calculations have been
2446 done.
2447
2448   having => { 'count(employee)' => { '>=', 100 } }
2449
2450 =head2 distinct
2451
2452 =over 4
2453
2454 =item Value: (0 | 1)
2455
2456 =back
2457
2458 Set to 1 to group by all columns.
2459
2460 =head2 where
2461
2462 =over 4
2463
2464 Adds to the WHERE clause.
2465
2466   # only return rows WHERE deleted IS NULL for all searches
2467   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
2468
2469 Can be overridden by passing C<{ where => undef }> as an attribute
2470 to a resulset.
2471
2472 =back
2473
2474 =head2 cache
2475
2476 Set to 1 to cache search results. This prevents extra SQL queries if you
2477 revisit rows in your ResultSet:
2478
2479   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
2480
2481   while( my $artist = $resultset->next ) {
2482     ... do stuff ...
2483   }
2484
2485   $rs->first; # without cache, this would issue a query
2486
2487 By default, searches are not cached.
2488
2489 For more examples of using these attributes, see
2490 L<DBIx::Class::Manual::Cookbook>.
2491
2492 =head2 from
2493
2494 =over 4
2495
2496 =item Value: \@from_clause
2497
2498 =back
2499
2500 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
2501 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
2502 clauses.
2503
2504 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
2505
2506 C<join> will usually do what you need and it is strongly recommended that you
2507 avoid using C<from> unless you cannot achieve the desired result using C<join>.
2508 And we really do mean "cannot", not just tried and failed. Attempting to use
2509 this because you're having problems with C<join> is like trying to use x86
2510 ASM because you've got a syntax error in your C. Trust us on this.
2511
2512 Now, if you're still really, really sure you need to use this (and if you're
2513 not 100% sure, ask the mailing list first), here's an explanation of how this
2514 works.
2515
2516 The syntax is as follows -
2517
2518   [
2519     { <alias1> => <table1> },
2520     [
2521       { <alias2> => <table2>, -join_type => 'inner|left|right' },
2522       [], # nested JOIN (optional)
2523       { <table1.column1> => <table2.column2>, ... (more conditions) },
2524     ],
2525     # More of the above [ ] may follow for additional joins
2526   ]
2527
2528   <table1> <alias1>
2529   JOIN
2530     <table2> <alias2>
2531     [JOIN ...]
2532   ON <table1.column1> = <table2.column2>
2533   <more joins may follow>
2534
2535 An easy way to follow the examples below is to remember the following:
2536
2537     Anything inside "[]" is a JOIN
2538     Anything inside "{}" is a condition for the enclosing JOIN
2539
2540 The following examples utilize a "person" table in a family tree application.
2541 In order to express parent->child relationships, this table is self-joined:
2542
2543     # Person->belongs_to('father' => 'Person');
2544     # Person->belongs_to('mother' => 'Person');
2545
2546 C<from> can be used to nest joins. Here we return all children with a father,
2547 then search against all mothers of those children:
2548
2549   $rs = $schema->resultset('Person')->search(
2550       undef,
2551       {
2552           alias => 'mother', # alias columns in accordance with "from"
2553           from => [
2554               { mother => 'person' },
2555               [
2556                   [
2557                       { child => 'person' },
2558                       [
2559                           { father => 'person' },
2560                           { 'father.person_id' => 'child.father_id' }
2561                       ]
2562                   ],
2563                   { 'mother.person_id' => 'child.mother_id' }
2564               ],
2565           ]
2566       },
2567   );
2568
2569   # Equivalent SQL:
2570   # SELECT mother.* FROM person mother
2571   # JOIN (
2572   #   person child
2573   #   JOIN person father
2574   #   ON ( father.person_id = child.father_id )
2575   # )
2576   # ON ( mother.person_id = child.mother_id )
2577
2578 The type of any join can be controlled manually. To search against only people
2579 with a father in the person table, we could explicitly use C<INNER JOIN>:
2580
2581     $rs = $schema->resultset('Person')->search(
2582         undef,
2583         {
2584             alias => 'child', # alias columns in accordance with "from"
2585             from => [
2586                 { child => 'person' },
2587                 [
2588                     { father => 'person', -join_type => 'inner' },
2589                     { 'father.id' => 'child.father_id' }
2590                 ],
2591             ]
2592         },
2593     );
2594
2595     # Equivalent SQL:
2596     # SELECT child.* FROM person child
2597     # INNER JOIN person father ON child.father_id = father.id
2598
2599 =cut
2600
2601 1;