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