This version passes tests but is ugly
[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     if ( $attrs->{select} ) {
2082         $attrs->{select} =
2083             ( ref $attrs->{select} eq 'ARRAY' )
2084           ? [ @{ $attrs->{select} } ]
2085           : [ $attrs->{select} ];
2086         $attrs->{as} = (
2087             $attrs->{as}
2088             ? (
2089                 ref $attrs->{as} eq 'ARRAY'
2090                 ? [ @{ $attrs->{as} } ]
2091                 : [ $attrs->{as} ]
2092               )
2093             : [
2094                 map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{ $attrs->{select} }
2095             ]
2096         );
2097     }
2098     else {
2099         $attrs->{columns} ||= [ $source->columns ];
2100
2101         # if columns is set we overwrite select & as
2102         $attrs->{select} = [];
2103         $attrs->{as}     = [];
2104         foreach my $colbit ( @{ $attrs->{columns} } ) {
2105             if ( ref($_) eq 'HASH' ) {
2106                 push(
2107                     @{ $attrs->{select} },
2108                     map { ref($_) ? $_ : m/\./ ? $_ : "${alias}.$_" }
2109                       values( %{$colbit} )
2110                 );
2111                 push(
2112                     @{ $attrs->{as} },
2113                     map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } keys( %{$colbit} )
2114                 );
2115             }
2116             else {
2117                 push(
2118                     @{ $attrs->{select} },
2119                     ( $colbit =~ m/\./ ) ? $colbit : "${alias}.${colbit}"
2120                 );
2121                 push(
2122                     @{ $attrs->{as} },
2123                     ( $colbit =~ m/^\Q${alias}.\E(.+)$/ ) ? $1 : $colbit
2124                 );
2125             }
2126         }
2127         delete $attrs->{columns};
2128     }
2129
2130     my $adds;
2131     if ( $adds = delete $attrs->{include_columns} ) {
2132         $adds = [$adds] unless ref $adds eq 'ARRAY';
2133         push( @{ $attrs->{select} }, @$adds );
2134         push( @{ $attrs->{as} }, map { m/([^.]+)$/; $1 } @$adds );
2135     }
2136     if ( $adds = delete $attrs->{'+columns'} ) {
2137         $adds = [$adds] unless ref $adds eq 'ARRAY';
2138         push(
2139             @{ $attrs->{select} },
2140             map { ref($_) eq 'HASH' ? values( %{$_} ) : $_ } @$adds
2141         );
2142         push(
2143             @{ $attrs->{as} },
2144             map { ref($_) eq 'HASH' ? keys( %{$_} ) : $_ } @$adds
2145         );
2146     }
2147     if ( $adds = delete $attrs->{'+select'} ) {
2148         $adds = [$adds] unless ref $adds eq 'ARRAY';
2149         push(
2150             @{ $attrs->{select} },
2151             map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds
2152         );
2153     }
2154     if ( $adds = delete $attrs->{'+as'} ) {
2155         $adds = [$adds] unless ref $adds eq 'ARRAY';
2156         push( @{ $attrs->{as} }, @$adds );
2157     }
2158
2159     $attrs->{from} ||= [ { 'me' => $source->from } ];
2160
2161     if ( exists $attrs->{join} || exists $attrs->{prefetch} ) {
2162         my $join = delete $attrs->{join} || {};
2163
2164         if ( defined $attrs->{prefetch} ) {
2165             $join = $self->_merge_attr( $join, $attrs->{prefetch} );
2166
2167         }
2168
2169         $attrs->{from} =    # have to copy here to avoid corrupting the original
2170           [
2171             @{ $attrs->{from} },
2172             $source->resolve_join(
2173                 $join, $alias, { %{ $attrs->{seen_join} || {} } }
2174             )
2175           ];
2176
2177     }
2178
2179     $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
2180     if ( $attrs->{order_by} ) {
2181         $attrs->{order_by} = (
2182             ref( $attrs->{order_by} ) eq 'ARRAY'
2183             ? [ @{ $attrs->{order_by} } ]
2184             : [ $attrs->{order_by} ]
2185         );
2186     }
2187     else {
2188         $attrs->{order_by} = [];
2189     }
2190
2191     my $collapse = $attrs->{collapse} || {};
2192     if ( my $prefetch = delete $attrs->{prefetch} ) {
2193         $prefetch = $self->_merge_attr( {}, $prefetch );
2194         my @pre_order;
2195         my $seen = $attrs->{seen_join} || {};
2196         foreach my $p ( ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch) ) {
2197
2198             # bring joins back to level of current class
2199             my @prefetch =
2200               $source->resolve_prefetch( $p, $alias, $seen, \@pre_order,
2201                 $collapse );
2202             push( @{ $attrs->{select} }, map { $_->[0] } @prefetch );
2203             push( @{ $attrs->{as} },     map { $_->[1] } @prefetch );
2204         }
2205         push( @{ $attrs->{order_by} }, @pre_order );
2206     }
2207     $attrs->{collapse} = $collapse;
2208
2209     if ( $attrs->{page} ) {
2210         $attrs->{offset} ||= 0;
2211         $attrs->{offset} += ( $attrs->{rows} * ( $attrs->{page} - 1 ) );
2212     }
2213
2214     return $self->{_attrs} = $attrs;
2215 }
2216
2217 sub _rollout_attr {
2218   my ($self, $attr) = @_;
2219   
2220   if (ref $attr eq 'HASH') {
2221     return $self->_rollout_hash($attr);
2222   } elsif (ref $attr eq 'ARRAY') {
2223     return $self->_rollout_array($attr);
2224   } else {
2225     return [$attr];
2226   }
2227 }
2228
2229 sub _rollout_array {
2230   my ($self, $attr) = @_;
2231
2232   my @rolled_array;
2233   foreach my $element (@{$attr}) {
2234     if (ref $element eq 'HASH') {
2235       push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
2236     } elsif (ref $element eq 'ARRAY') {
2237       #  XXX - should probably recurse here
2238       push( @rolled_array, @{$self->_rollout_array($element)} );
2239     } else {
2240       push( @rolled_array, $element );
2241     }
2242   }
2243   return \@rolled_array;
2244 }
2245
2246 sub _rollout_hash {
2247   my ($self, $attr) = @_;
2248
2249   my @rolled_array;
2250   foreach my $key (keys %{$attr}) {
2251     push( @rolled_array, { $key => $attr->{$key} } );
2252   }
2253   return \@rolled_array;
2254 }
2255
2256 sub _calculate_score {
2257   my ($self, $a, $b) = @_;
2258
2259   if (ref $b eq 'HASH') {
2260     my ($b_key) = keys %{$b};
2261     if (ref $a eq 'HASH') {
2262       my ($a_key) = keys %{$a};
2263       if ($a_key eq $b_key) {
2264         return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
2265       } else {
2266         return 0;
2267       }
2268     } else {
2269       return ($a eq $b_key) ? 1 : 0;
2270     }       
2271   } else {
2272     if (ref $a eq 'HASH') {
2273       my ($a_key) = keys %{$a};
2274       return ($b eq $a_key) ? 1 : 0;
2275     } else {
2276       return ($b eq $a) ? 1 : 0;
2277     }
2278   }
2279 }
2280
2281 sub _merge_attr {
2282   my ($self, $orig, $import) = @_;
2283
2284   return $import unless defined($orig);
2285   return $orig unless defined($import);
2286   
2287   $orig = $self->_rollout_attr($orig);
2288   $import = $self->_rollout_attr($import);
2289
2290   my $seen_keys;
2291   foreach my $import_element ( @{$import} ) {
2292     # find best candidate from $orig to merge $b_element into
2293     my $best_candidate = { position => undef, score => 0 }; my $position = 0;
2294     foreach my $orig_element ( @{$orig} ) {
2295       my $score = $self->_calculate_score( $orig_element, $import_element );
2296       if ($score > $best_candidate->{score}) {
2297         $best_candidate->{position} = $position;
2298         $best_candidate->{score} = $score;
2299       }
2300       $position++;
2301     }
2302     my ($import_key) = ( ref $import_element eq 'HASH' ) ? keys %{$import_element} : ($import_element);
2303
2304     if ($best_candidate->{score} == 0 || exists $seen_keys->{$import_key}) {
2305       push( @{$orig}, $import_element );
2306     } else {
2307       my $orig_best = $orig->[$best_candidate->{position}];
2308       # merge orig_best and b_element together and replace original with merged
2309       if (ref $orig_best ne 'HASH') {
2310         $orig->[$best_candidate->{position}] = $import_element;
2311       } elsif (ref $import_element eq 'HASH') {
2312         my ($key) = keys %{$orig_best};
2313         $orig->[$best_candidate->{position}] = { $key => $self->_merge_attr($orig_best->{$key}, $import_element->{$key}) };
2314       }
2315     }
2316     $seen_keys->{$import_key} = 1; # don't merge the same key twice
2317   }
2318
2319   return $orig;
2320 }
2321
2322 sub result_source {
2323     my $self = shift;
2324
2325     if (@_) {
2326         $self->_source_handle($_[0]->handle);
2327     } else {
2328         $self->_source_handle->resolve;
2329     }
2330 }
2331
2332 =head2 throw_exception
2333
2334 See L<DBIx::Class::Schema/throw_exception> for details.
2335
2336 =cut
2337
2338 sub throw_exception {
2339   my $self=shift;
2340   if (ref $self && $self->_source_handle->schema) {
2341     $self->_source_handle->schema->throw_exception(@_)
2342   } else {
2343     croak(@_);
2344   }
2345
2346 }
2347
2348 # XXX: FIXME: Attributes docs need clearing up
2349
2350 =head1 ATTRIBUTES
2351
2352 The resultset takes various attributes that modify its behavior. Here's an
2353 overview of them:
2354
2355 =head2 order_by
2356
2357 =over 4
2358
2359 =item Value: ($order_by | \@order_by)
2360
2361 =back
2362
2363 Which column(s) to order the results by. This is currently passed
2364 through directly to SQL, so you can give e.g. C<year DESC> for a
2365 descending order on the column `year'.
2366
2367 Please note that if you have C<quote_char> enabled (see
2368 L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
2369 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
2370 so you will need to manually quote things as appropriate.)
2371
2372 =head2 columns
2373
2374 =over 4
2375
2376 =item Value: \@columns
2377
2378 =back
2379
2380 Shortcut to request a particular set of columns to be retrieved. Each
2381 column spec may be a string (a table column name), or a hash (in which
2382 case the key is the C<as> value, and the value is used as the C<select>
2383 expression). Adds C<me.> onto the start of any column without a C<.> in
2384 it and sets C<select> from that, then auto-populates C<as> from
2385 C<select> as normal. (You may also use the C<cols> attribute, as in
2386 earlier versions of DBIC.)
2387
2388 =head2 +columns
2389
2390 =over 4
2391
2392 =item Value: \@columns
2393
2394 =back
2395
2396 Indicates additional columns to be selected from storage. Works the same
2397 as L</columns> but adds columns to the selection. (You may also use the
2398 C<include_columns> attribute, as in earlier versions of DBIC). For
2399 example:-
2400
2401   $schema->resultset('CD')->search(undef, {
2402     '+columns' => ['artist.name'],
2403     join => ['artist']
2404   });
2405
2406 would return all CDs and include a 'name' column to the information
2407 passed to object inflation. Note that the 'artist' is the name of the
2408 column (or relationship) accessor, and 'name' is the name of the column
2409 accessor in the related table.
2410
2411 =head2 select
2412
2413 =over 4
2414
2415 =item Value: \@select_columns
2416
2417 =back
2418
2419 Indicates which columns should be selected from the storage. You can use
2420 column names, or in the case of RDBMS back ends, function or stored procedure
2421 names:
2422
2423   $rs = $schema->resultset('Employee')->search(undef, {
2424     select => [
2425       'name',
2426       { count => 'employeeid' },
2427       { sum => 'salary' }
2428     ]
2429   });
2430
2431 When you use function/stored procedure names and do not supply an C<as>
2432 attribute, the column names returned are storage-dependent. E.g. MySQL would
2433 return a column named C<count(employeeid)> in the above example.
2434
2435 =head2 +select
2436
2437 =over 4
2438
2439 Indicates additional columns to be selected from storage.  Works the same as
2440 L</select> but adds columns to the selection.
2441
2442 =back
2443
2444 =head2 +as
2445
2446 =over 4
2447
2448 Indicates additional column names for those added via L</+select>.
2449
2450 =back
2451
2452 =head2 as
2453
2454 =over 4
2455
2456 =item Value: \@inflation_names
2457
2458 =back
2459
2460 Indicates column names for object inflation. That is, C<as>
2461 indicates the name that the column can be accessed as via the
2462 C<get_column> method (or via the object accessor, B<if one already
2463 exists>).  It has nothing to do with the SQL code C<SELECT foo AS bar>.
2464
2465 The C<as> attribute is used in conjunction with C<select>,
2466 usually when C<select> contains one or more function or stored
2467 procedure names:
2468
2469   $rs = $schema->resultset('Employee')->search(undef, {
2470     select => [
2471       'name',
2472       { count => 'employeeid' }
2473     ],
2474     as => ['name', 'employee_count'],
2475   });
2476
2477   my $employee = $rs->first(); # get the first Employee
2478
2479 If the object against which the search is performed already has an accessor
2480 matching a column name specified in C<as>, the value can be retrieved using
2481 the accessor as normal:
2482
2483   my $name = $employee->name();
2484
2485 If on the other hand an accessor does not exist in the object, you need to
2486 use C<get_column> instead:
2487
2488   my $employee_count = $employee->get_column('employee_count');
2489
2490 You can create your own accessors if required - see
2491 L<DBIx::Class::Manual::Cookbook> for details.
2492
2493 Please note: This will NOT insert an C<AS employee_count> into the SQL
2494 statement produced, it is used for internal access only. Thus
2495 attempting to use the accessor in an C<order_by> clause or similar
2496 will fail miserably.
2497
2498 To get around this limitation, you can supply literal SQL to your
2499 C<select> attibute that contains the C<AS alias> text, eg:
2500
2501   select => [\'myfield AS alias']
2502
2503 =head2 join
2504
2505 =over 4
2506
2507 =item Value: ($rel_name | \@rel_names | \%rel_names)
2508
2509 =back
2510
2511 Contains a list of relationships that should be joined for this query.  For
2512 example:
2513
2514   # Get CDs by Nine Inch Nails
2515   my $rs = $schema->resultset('CD')->search(
2516     { 'artist.name' => 'Nine Inch Nails' },
2517     { join => 'artist' }
2518   );
2519
2520 Can also contain a hash reference to refer to the other relation's relations.
2521 For example:
2522
2523   package MyApp::Schema::Track;
2524   use base qw/DBIx::Class/;
2525   __PACKAGE__->table('track');
2526   __PACKAGE__->add_columns(qw/trackid cd position title/);
2527   __PACKAGE__->set_primary_key('trackid');
2528   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
2529   1;
2530
2531   # In your application
2532   my $rs = $schema->resultset('Artist')->search(
2533     { 'track.title' => 'Teardrop' },
2534     {
2535       join     => { cd => 'track' },
2536       order_by => 'artist.name',
2537     }
2538   );
2539
2540 You need to use the relationship (not the table) name in  conditions, 
2541 because they are aliased as such. The current table is aliased as "me", so 
2542 you need to use me.column_name in order to avoid ambiguity. For example:
2543
2544   # Get CDs from 1984 with a 'Foo' track 
2545   my $rs = $schema->resultset('CD')->search(
2546     { 
2547       'me.year' => 1984,
2548       'tracks.name' => 'Foo'
2549     },
2550     { join => 'tracks' }
2551   );
2552   
2553 If the same join is supplied twice, it will be aliased to <rel>_2 (and
2554 similarly for a third time). For e.g.
2555
2556   my $rs = $schema->resultset('Artist')->search({
2557     'cds.title'   => 'Down to Earth',
2558     'cds_2.title' => 'Popular',
2559   }, {
2560     join => [ qw/cds cds/ ],
2561   });
2562
2563 will return a set of all artists that have both a cd with title 'Down
2564 to Earth' and a cd with title 'Popular'.
2565
2566 If you want to fetch related objects from other tables as well, see C<prefetch>
2567 below.
2568
2569 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
2570
2571 =head2 prefetch
2572
2573 =over 4
2574
2575 =item Value: ($rel_name | \@rel_names | \%rel_names)
2576
2577 =back
2578
2579 Contains one or more relationships that should be fetched along with
2580 the main query (when they are accessed afterwards the data will
2581 already be available, without extra queries to the database).  This is
2582 useful for when you know you will need the related objects, because it
2583 saves at least one query:
2584
2585   my $rs = $schema->resultset('Tag')->search(
2586     undef,
2587     {
2588       prefetch => {
2589         cd => 'artist'
2590       }
2591     }
2592   );
2593
2594 The initial search results in SQL like the following:
2595
2596   SELECT tag.*, cd.*, artist.* FROM tag
2597   JOIN cd ON tag.cd = cd.cdid
2598   JOIN artist ON cd.artist = artist.artistid
2599
2600 L<DBIx::Class> has no need to go back to the database when we access the
2601 C<cd> or C<artist> relationships, which saves us two SQL statements in this
2602 case.
2603
2604 Simple prefetches will be joined automatically, so there is no need
2605 for a C<join> attribute in the above search. 
2606
2607 C<prefetch> can be used with the following relationship types: C<belongs_to>,
2608 C<has_one> (or if you're using C<add_relationship>, any relationship declared
2609 with an accessor type of 'single' or 'filter'). A more complex example that
2610 prefetches an artists cds, the tracks on those cds, and the tags associted 
2611 with that artist is given below (assuming many-to-many from artists to tags):
2612
2613  my $rs = $schema->resultset('Artist')->search(
2614    undef,
2615    {
2616      prefetch => [
2617        { cds => 'tracks' },
2618        { artist_tags => 'tags' }
2619      ]
2620    }
2621  );
2622  
2623
2624 B<NOTE:> If you specify a C<prefetch> attribute, the C<join> and C<select>
2625 attributes will be ignored.
2626
2627 =head2 page
2628
2629 =over 4
2630
2631 =item Value: $page
2632
2633 =back
2634
2635 Makes the resultset paged and specifies the page to retrieve. Effectively
2636 identical to creating a non-pages resultset and then calling ->page($page)
2637 on it.
2638
2639 If L<rows> attribute is not specified it defualts to 10 rows per page.
2640
2641 =head2 rows
2642
2643 =over 4
2644
2645 =item Value: $rows
2646
2647 =back
2648
2649 Specifes the maximum number of rows for direct retrieval or the number of
2650 rows per page if the page attribute or method is used.
2651
2652 =head2 offset
2653
2654 =over 4
2655
2656 =item Value: $offset
2657
2658 =back
2659
2660 Specifies the (zero-based) row number for the  first row to be returned, or the
2661 of the first row of the first page if paging is used.
2662
2663 =head2 group_by
2664
2665 =over 4
2666
2667 =item Value: \@columns
2668
2669 =back
2670
2671 A arrayref of columns to group by. Can include columns of joined tables.
2672
2673   group_by => [qw/ column1 column2 ... /]
2674
2675 =head2 having
2676
2677 =over 4
2678
2679 =item Value: $condition
2680
2681 =back
2682
2683 HAVING is a select statement attribute that is applied between GROUP BY and
2684 ORDER BY. It is applied to the after the grouping calculations have been
2685 done.
2686
2687   having => { 'count(employee)' => { '>=', 100 } }
2688
2689 =head2 distinct
2690
2691 =over 4
2692
2693 =item Value: (0 | 1)
2694
2695 =back
2696
2697 Set to 1 to group by all columns.
2698
2699 =head2 where
2700
2701 =over 4
2702
2703 Adds to the WHERE clause.
2704
2705   # only return rows WHERE deleted IS NULL for all searches
2706   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
2707
2708 Can be overridden by passing C<{ where => undef }> as an attribute
2709 to a resulset.
2710
2711 =back
2712
2713 =head2 cache
2714
2715 Set to 1 to cache search results. This prevents extra SQL queries if you
2716 revisit rows in your ResultSet:
2717
2718   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
2719
2720   while( my $artist = $resultset->next ) {
2721     ... do stuff ...
2722   }
2723
2724   $rs->first; # without cache, this would issue a query
2725
2726 By default, searches are not cached.
2727
2728 For more examples of using these attributes, see
2729 L<DBIx::Class::Manual::Cookbook>.
2730
2731 =head2 from
2732
2733 =over 4
2734
2735 =item Value: \@from_clause
2736
2737 =back
2738
2739 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
2740 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
2741 clauses.
2742
2743 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
2744
2745 C<join> will usually do what you need and it is strongly recommended that you
2746 avoid using C<from> unless you cannot achieve the desired result using C<join>.
2747 And we really do mean "cannot", not just tried and failed. Attempting to use
2748 this because you're having problems with C<join> is like trying to use x86
2749 ASM because you've got a syntax error in your C. Trust us on this.
2750
2751 Now, if you're still really, really sure you need to use this (and if you're
2752 not 100% sure, ask the mailing list first), here's an explanation of how this
2753 works.
2754
2755 The syntax is as follows -
2756
2757   [
2758     { <alias1> => <table1> },
2759     [
2760       { <alias2> => <table2>, -join_type => 'inner|left|right' },
2761       [], # nested JOIN (optional)
2762       { <table1.column1> => <table2.column2>, ... (more conditions) },
2763     ],
2764     # More of the above [ ] may follow for additional joins
2765   ]
2766
2767   <table1> <alias1>
2768   JOIN
2769     <table2> <alias2>
2770     [JOIN ...]
2771   ON <table1.column1> = <table2.column2>
2772   <more joins may follow>
2773
2774 An easy way to follow the examples below is to remember the following:
2775
2776     Anything inside "[]" is a JOIN
2777     Anything inside "{}" is a condition for the enclosing JOIN
2778
2779 The following examples utilize a "person" table in a family tree application.
2780 In order to express parent->child relationships, this table is self-joined:
2781
2782     # Person->belongs_to('father' => 'Person');
2783     # Person->belongs_to('mother' => 'Person');
2784
2785 C<from> can be used to nest joins. Here we return all children with a father,
2786 then search against all mothers of those children:
2787
2788   $rs = $schema->resultset('Person')->search(
2789       undef,
2790       {
2791           alias => 'mother', # alias columns in accordance with "from"
2792           from => [
2793               { mother => 'person' },
2794               [
2795                   [
2796                       { child => 'person' },
2797                       [
2798                           { father => 'person' },
2799                           { 'father.person_id' => 'child.father_id' }
2800                       ]
2801                   ],
2802                   { 'mother.person_id' => 'child.mother_id' }
2803               ],
2804           ]
2805       },
2806   );
2807
2808   # Equivalent SQL:
2809   # SELECT mother.* FROM person mother
2810   # JOIN (
2811   #   person child
2812   #   JOIN person father
2813   #   ON ( father.person_id = child.father_id )
2814   # )
2815   # ON ( mother.person_id = child.mother_id )
2816
2817 The type of any join can be controlled manually. To search against only people
2818 with a father in the person table, we could explicitly use C<INNER JOIN>:
2819
2820     $rs = $schema->resultset('Person')->search(
2821         undef,
2822         {
2823             alias => 'child', # alias columns in accordance with "from"
2824             from => [
2825                 { child => 'person' },
2826                 [
2827                     { father => 'person', -join_type => 'inner' },
2828                     { 'father.id' => 'child.father_id' }
2829                 ],
2830             ]
2831         },
2832     );
2833
2834     # Equivalent SQL:
2835     # SELECT child.* FROM person child
2836     # INNER JOIN person father ON child.father_id = father.id
2837
2838 =head2 for
2839
2840 =over 4
2841
2842 =item Value: ( 'update' | 'shared' )
2843
2844 =back
2845
2846 Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT
2847 ... FOR SHARED.
2848
2849 =cut
2850
2851 1;