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