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