Reduce the number of times $self->_dbh is called inside dbh_do() to speed
[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   if (ref $self && $self->_source_handle->schema) {
2136     $self->_source_handle->schema->throw_exception(@_)
2137   } else {
2138     croak(@_);
2139   }
2140
2141 }
2142
2143 # XXX: FIXME: Attributes docs need clearing up
2144
2145 =head1 ATTRIBUTES
2146
2147 The resultset takes various attributes that modify its behavior. Here's an
2148 overview of them:
2149
2150 =head2 order_by
2151
2152 =over 4
2153
2154 =item Value: ($order_by | \@order_by)
2155
2156 =back
2157
2158 Which column(s) to order the results by. This is currently passed
2159 through directly to SQL, so you can give e.g. C<year DESC> for a
2160 descending order on the column `year'.
2161
2162 Please note that if you have C<quote_char> enabled (see
2163 L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
2164 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
2165 so you will need to manually quote things as appropriate.)
2166
2167 =head2 columns
2168
2169 =over 4
2170
2171 =item Value: \@columns
2172
2173 =back
2174
2175 Shortcut to request a particular set of columns to be retrieved.  Adds
2176 C<me.> onto the start of any column without a C<.> in it and sets C<select>
2177 from that, then auto-populates C<as> from C<select> as normal. (You may also
2178 use the C<cols> attribute, as in earlier versions of DBIC.)
2179
2180 =head2 include_columns
2181
2182 =over 4
2183
2184 =item Value: \@columns
2185
2186 =back
2187
2188 Shortcut to include additional columns in the returned results - for example
2189
2190   $schema->resultset('CD')->search(undef, {
2191     include_columns => ['artist.name'],
2192     join => ['artist']
2193   });
2194
2195 would return all CDs and include a 'name' column to the information
2196 passed to object inflation. Note that the 'artist' is the name of the
2197 column (or relationship) accessor, and 'name' is the name of the column
2198 accessor in the related table.
2199
2200 =head2 select
2201
2202 =over 4
2203
2204 =item Value: \@select_columns
2205
2206 =back
2207
2208 Indicates which columns should be selected from the storage. You can use
2209 column names, or in the case of RDBMS back ends, function or stored procedure
2210 names:
2211
2212   $rs = $schema->resultset('Employee')->search(undef, {
2213     select => [
2214       'name',
2215       { count => 'employeeid' },
2216       { sum => 'salary' }
2217     ]
2218   });
2219
2220 When you use function/stored procedure names and do not supply an C<as>
2221 attribute, the column names returned are storage-dependent. E.g. MySQL would
2222 return a column named C<count(employeeid)> in the above example.
2223
2224 =head2 +select
2225
2226 =over 4
2227
2228 Indicates additional columns to be selected from storage.  Works the same as
2229 L</select> but adds columns to the selection.
2230
2231 =back
2232
2233 =head2 +as
2234
2235 =over 4
2236
2237 Indicates additional column names for those added via L</+select>.
2238
2239 =back
2240
2241 =head2 as
2242
2243 =over 4
2244
2245 =item Value: \@inflation_names
2246
2247 =back
2248
2249 Indicates column names for object inflation. That is, C<as>
2250 indicates the name that the column can be accessed as via the
2251 C<get_column> method (or via the object accessor, B<if one already
2252 exists>).  It has nothing to do with the SQL code C<SELECT foo AS bar>.
2253
2254 The C<as> attribute is used in conjunction with C<select>,
2255 usually when C<select> contains one or more function or stored
2256 procedure names:
2257
2258   $rs = $schema->resultset('Employee')->search(undef, {
2259     select => [
2260       'name',
2261       { count => 'employeeid' }
2262     ],
2263     as => ['name', 'employee_count'],
2264   });
2265
2266   my $employee = $rs->first(); # get the first Employee
2267
2268 If the object against which the search is performed already has an accessor
2269 matching a column name specified in C<as>, the value can be retrieved using
2270 the accessor as normal:
2271
2272   my $name = $employee->name();
2273
2274 If on the other hand an accessor does not exist in the object, you need to
2275 use C<get_column> instead:
2276
2277   my $employee_count = $employee->get_column('employee_count');
2278
2279 You can create your own accessors if required - see
2280 L<DBIx::Class::Manual::Cookbook> for details.
2281
2282 Please note: This will NOT insert an C<AS employee_count> into the SQL
2283 statement produced, it is used for internal access only. Thus
2284 attempting to use the accessor in an C<order_by> clause or similar
2285 will fail miserably.
2286
2287 To get around this limitation, you can supply literal SQL to your
2288 C<select> attibute that contains the C<AS alias> text, eg:
2289
2290   select => [\'myfield AS alias']
2291
2292 =head2 join
2293
2294 =over 4
2295
2296 =item Value: ($rel_name | \@rel_names | \%rel_names)
2297
2298 =back
2299
2300 Contains a list of relationships that should be joined for this query.  For
2301 example:
2302
2303   # Get CDs by Nine Inch Nails
2304   my $rs = $schema->resultset('CD')->search(
2305     { 'artist.name' => 'Nine Inch Nails' },
2306     { join => 'artist' }
2307   );
2308
2309 Can also contain a hash reference to refer to the other relation's relations.
2310 For example:
2311
2312   package MyApp::Schema::Track;
2313   use base qw/DBIx::Class/;
2314   __PACKAGE__->table('track');
2315   __PACKAGE__->add_columns(qw/trackid cd position title/);
2316   __PACKAGE__->set_primary_key('trackid');
2317   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
2318   1;
2319
2320   # In your application
2321   my $rs = $schema->resultset('Artist')->search(
2322     { 'track.title' => 'Teardrop' },
2323     {
2324       join     => { cd => 'track' },
2325       order_by => 'artist.name',
2326     }
2327   );
2328
2329 You need to use the relationship (not the table) name in  conditions, 
2330 because they are aliased as such. The current table is aliased as "me", so 
2331 you need to use me.column_name in order to avoid ambiguity. For example:
2332
2333   # Get CDs from 1984 with a 'Foo' track 
2334   my $rs = $schema->resultset('CD')->search(
2335     { 
2336       'me.year' => 1984,
2337       'tracks.name' => 'Foo'
2338     },
2339     { join => 'tracks' }
2340   );
2341   
2342 If the same join is supplied twice, it will be aliased to <rel>_2 (and
2343 similarly for a third time). For e.g.
2344
2345   my $rs = $schema->resultset('Artist')->search({
2346     'cds.title'   => 'Down to Earth',
2347     'cds_2.title' => 'Popular',
2348   }, {
2349     join => [ qw/cds cds/ ],
2350   });
2351
2352 will return a set of all artists that have both a cd with title 'Down
2353 to Earth' and a cd with title 'Popular'.
2354
2355 If you want to fetch related objects from other tables as well, see C<prefetch>
2356 below.
2357
2358 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
2359
2360 =head2 prefetch
2361
2362 =over 4
2363
2364 =item Value: ($rel_name | \@rel_names | \%rel_names)
2365
2366 =back
2367
2368 Contains one or more relationships that should be fetched along with
2369 the main query (when they are accessed afterwards the data will
2370 already be available, without extra queries to the database).  This is
2371 useful for when you know you will need the related objects, because it
2372 saves at least one query:
2373
2374   my $rs = $schema->resultset('Tag')->search(
2375     undef,
2376     {
2377       prefetch => {
2378         cd => 'artist'
2379       }
2380     }
2381   );
2382
2383 The initial search results in SQL like the following:
2384
2385   SELECT tag.*, cd.*, artist.* FROM tag
2386   JOIN cd ON tag.cd = cd.cdid
2387   JOIN artist ON cd.artist = artist.artistid
2388
2389 L<DBIx::Class> has no need to go back to the database when we access the
2390 C<cd> or C<artist> relationships, which saves us two SQL statements in this
2391 case.
2392
2393 Simple prefetches will be joined automatically, so there is no need
2394 for a C<join> attribute in the above search. If you're prefetching to
2395 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
2396 specify the join as well.
2397
2398 C<prefetch> can be used with the following relationship types: C<belongs_to>,
2399 C<has_one> (or if you're using C<add_relationship>, any relationship declared
2400 with an accessor type of 'single' or 'filter').
2401
2402 =head2 page
2403
2404 =over 4
2405
2406 =item Value: $page
2407
2408 =back
2409
2410 Makes the resultset paged and specifies the page to retrieve. Effectively
2411 identical to creating a non-pages resultset and then calling ->page($page)
2412 on it.
2413
2414 If L<rows> attribute is not specified it defualts to 10 rows per page.
2415
2416 =head2 rows
2417
2418 =over 4
2419
2420 =item Value: $rows
2421
2422 =back
2423
2424 Specifes the maximum number of rows for direct retrieval or the number of
2425 rows per page if the page attribute or method is used.
2426
2427 =head2 offset
2428
2429 =over 4
2430
2431 =item Value: $offset
2432
2433 =back
2434
2435 Specifies the (zero-based) row number for the  first row to be returned, or the
2436 of the first row of the first page if paging is used.
2437
2438 =head2 group_by
2439
2440 =over 4
2441
2442 =item Value: \@columns
2443
2444 =back
2445
2446 A arrayref of columns to group by. Can include columns of joined tables.
2447
2448   group_by => [qw/ column1 column2 ... /]
2449
2450 =head2 having
2451
2452 =over 4
2453
2454 =item Value: $condition
2455
2456 =back
2457
2458 HAVING is a select statement attribute that is applied between GROUP BY and
2459 ORDER BY. It is applied to the after the grouping calculations have been
2460 done.
2461
2462   having => { 'count(employee)' => { '>=', 100 } }
2463
2464 =head2 distinct
2465
2466 =over 4
2467
2468 =item Value: (0 | 1)
2469
2470 =back
2471
2472 Set to 1 to group by all columns.
2473
2474 =head2 where
2475
2476 =over 4
2477
2478 Adds to the WHERE clause.
2479
2480   # only return rows WHERE deleted IS NULL for all searches
2481   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
2482
2483 Can be overridden by passing C<{ where => undef }> as an attribute
2484 to a resulset.
2485
2486 =back
2487
2488 =head2 cache
2489
2490 Set to 1 to cache search results. This prevents extra SQL queries if you
2491 revisit rows in your ResultSet:
2492
2493   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
2494
2495   while( my $artist = $resultset->next ) {
2496     ... do stuff ...
2497   }
2498
2499   $rs->first; # without cache, this would issue a query
2500
2501 By default, searches are not cached.
2502
2503 For more examples of using these attributes, see
2504 L<DBIx::Class::Manual::Cookbook>.
2505
2506 =head2 from
2507
2508 =over 4
2509
2510 =item Value: \@from_clause
2511
2512 =back
2513
2514 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
2515 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
2516 clauses.
2517
2518 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
2519
2520 C<join> will usually do what you need and it is strongly recommended that you
2521 avoid using C<from> unless you cannot achieve the desired result using C<join>.
2522 And we really do mean "cannot", not just tried and failed. Attempting to use
2523 this because you're having problems with C<join> is like trying to use x86
2524 ASM because you've got a syntax error in your C. Trust us on this.
2525
2526 Now, if you're still really, really sure you need to use this (and if you're
2527 not 100% sure, ask the mailing list first), here's an explanation of how this
2528 works.
2529
2530 The syntax is as follows -
2531
2532   [
2533     { <alias1> => <table1> },
2534     [
2535       { <alias2> => <table2>, -join_type => 'inner|left|right' },
2536       [], # nested JOIN (optional)
2537       { <table1.column1> => <table2.column2>, ... (more conditions) },
2538     ],
2539     # More of the above [ ] may follow for additional joins
2540   ]
2541
2542   <table1> <alias1>
2543   JOIN
2544     <table2> <alias2>
2545     [JOIN ...]
2546   ON <table1.column1> = <table2.column2>
2547   <more joins may follow>
2548
2549 An easy way to follow the examples below is to remember the following:
2550
2551     Anything inside "[]" is a JOIN
2552     Anything inside "{}" is a condition for the enclosing JOIN
2553
2554 The following examples utilize a "person" table in a family tree application.
2555 In order to express parent->child relationships, this table is self-joined:
2556
2557     # Person->belongs_to('father' => 'Person');
2558     # Person->belongs_to('mother' => 'Person');
2559
2560 C<from> can be used to nest joins. Here we return all children with a father,
2561 then search against all mothers of those children:
2562
2563   $rs = $schema->resultset('Person')->search(
2564       undef,
2565       {
2566           alias => 'mother', # alias columns in accordance with "from"
2567           from => [
2568               { mother => 'person' },
2569               [
2570                   [
2571                       { child => 'person' },
2572                       [
2573                           { father => 'person' },
2574                           { 'father.person_id' => 'child.father_id' }
2575                       ]
2576                   ],
2577                   { 'mother.person_id' => 'child.mother_id' }
2578               ],
2579           ]
2580       },
2581   );
2582
2583   # Equivalent SQL:
2584   # SELECT mother.* FROM person mother
2585   # JOIN (
2586   #   person child
2587   #   JOIN person father
2588   #   ON ( father.person_id = child.father_id )
2589   # )
2590   # ON ( mother.person_id = child.mother_id )
2591
2592 The type of any join can be controlled manually. To search against only people
2593 with a father in the person table, we could explicitly use C<INNER JOIN>:
2594
2595     $rs = $schema->resultset('Person')->search(
2596         undef,
2597         {
2598             alias => 'child', # alias columns in accordance with "from"
2599             from => [
2600                 { child => 'person' },
2601                 [
2602                     { father => 'person', -join_type => 'inner' },
2603                     { 'father.id' => 'child.father_id' }
2604                 ],
2605             ]
2606         },
2607     );
2608
2609     # Equivalent SQL:
2610     # SELECT child.* FROM person child
2611     # INNER JOIN person father ON child.father_id = father.id
2612
2613 =cut
2614
2615 1;