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