patch ->delete to die if args
[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/) {
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 =cut
1297
1298 sub delete {
1299   my ($self) = @_;
1300   $self->throw_exception("Delete should not be passed any arguments")
1301     if $_[1];
1302   my $cond = $self->_cond_for_update_delete;
1303
1304   $self->result_source->storage->delete($self->result_source, $cond);
1305   return 1;
1306 }
1307
1308 =head2 delete_all
1309
1310 =over 4
1311
1312 =item Arguments: none
1313
1314 =item Return Value: 1
1315
1316 =back
1317
1318 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1319 will run DBIC cascade triggers, while L</delete> will not.
1320
1321 =cut
1322
1323 sub delete_all {
1324   my ($self) = @_;
1325   $_->delete for $self->all;
1326   return 1;
1327 }
1328
1329 =head2 populate
1330
1331 =over 4
1332
1333 =item Arguments: \@data;
1334
1335 =back
1336
1337 Pass an arrayref of hashrefs. Each hashref should be a structure suitable for
1338 submitting to a $resultset->create(...) method.
1339
1340 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
1341 to insert the data, as this is a faster method.  
1342
1343 Otherwise, each set of data is inserted into the database using
1344 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
1345 objects is returned.
1346
1347 Example:  Assuming an Artist Class that has many CDs Classes relating:
1348
1349   my $Artist_rs = $schema->resultset("Artist");
1350   
1351   ## Void Context Example 
1352   $Artist_rs->populate([
1353      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1354         { title => 'My First CD', year => 2006 },
1355         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1356       ],
1357      },
1358      { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
1359         { title => 'My parents sold me to a record company' ,year => 2005 },
1360         { title => 'Why Am I So Ugly?', year => 2006 },
1361         { title => 'I Got Surgery and am now Popular', year => 2007 }
1362       ],
1363      },
1364   ]);
1365   
1366   ## Array Context Example
1367   my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
1368     { name => "Artist One"},
1369     { name => "Artist Two"},
1370     { name => "Artist Three", cds=> [
1371     { title => "First CD", year => 2007},
1372     { title => "Second CD", year => 2008},
1373   ]}
1374   ]);
1375   
1376   print $ArtistOne->name; ## response is 'Artist One'
1377   print $ArtistThree->cds->count ## reponse is '2'
1378   
1379 Please note an important effect on your data when choosing between void and
1380 wantarray context. Since void context goes straight to C<insert_bulk> in 
1381 L<DBIx::Class::Storage::DBI> this will skip any component that is overriding
1382 c<insert>.  So if you are using something like L<DBIx-Class-UUIDColumns> to 
1383 create primary keys for you, you will find that your PKs are empty.  In this 
1384 case you will have to use the wantarray context in order to create those 
1385 values.
1386
1387 =cut
1388
1389 sub populate {
1390   my ($self, $data) = @_;
1391   
1392   if(defined wantarray) {
1393     my @created;
1394     foreach my $item (@$data) {
1395       push(@created, $self->create($item));
1396     }
1397     return @created;
1398   } else {
1399     my ($first, @rest) = @$data;
1400
1401     my @names = grep {!ref $first->{$_}} keys %$first;
1402     my @rels = grep { $self->result_source->has_relationship($_) } keys %$first;
1403     my @pks = $self->result_source->primary_columns;  
1404
1405     ## do the belongs_to relationships  
1406     foreach my $index (0..$#$data) {
1407       if( grep { !defined $data->[$index]->{$_} } @pks ) {
1408         my @ret = $self->populate($data);
1409         return;
1410       }
1411     
1412       foreach my $rel (@rels) {
1413         next unless $data->[$index]->{$rel} && ref $data->[$index]->{$rel} eq "HASH";
1414         my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
1415         my ($reverse) = keys %{$self->result_source->reverse_relationship_info($rel)};
1416         my $related = $result->result_source->resolve_condition(
1417           $result->result_source->relationship_info($reverse)->{cond},
1418           $self,        
1419           $result,        
1420         );
1421
1422         delete $data->[$index]->{$rel};
1423         $data->[$index] = {%{$data->[$index]}, %$related};
1424       
1425         push @names, keys %$related if $index == 0;
1426       }
1427     }
1428
1429     ## do bulk insert on current row
1430     my @values = map { [ @$_{@names} ] } @$data;
1431
1432     $self->result_source->storage->insert_bulk(
1433       $self->result_source, 
1434       \@names, 
1435       \@values,
1436     );
1437
1438     ## do the has_many relationships
1439     foreach my $item (@$data) {
1440
1441       foreach my $rel (@rels) {
1442         next unless $item->{$rel} && ref $item->{$rel} eq "ARRAY";
1443
1444         my $parent = $self->find(map {{$_=>$item->{$_}} } @pks) 
1445      || $self->throw_exception('Cannot find the relating object.');
1446      
1447         my $child = $parent->$rel;
1448     
1449         my $related = $child->result_source->resolve_condition(
1450           $parent->result_source->relationship_info($rel)->{cond},
1451           $child,
1452           $parent,
1453         );
1454
1455         my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
1456         my @populate = map { {%$_, %$related} } @rows_to_add;
1457
1458         $child->populate( \@populate );
1459       }
1460     }
1461   }
1462 }
1463
1464 =head2 pager
1465
1466 =over 4
1467
1468 =item Arguments: none
1469
1470 =item Return Value: $pager
1471
1472 =back
1473
1474 Return Value a L<Data::Page> object for the current resultset. Only makes
1475 sense for queries with a C<page> attribute.
1476
1477 =cut
1478
1479 sub pager {
1480   my ($self) = @_;
1481   my $attrs = $self->{attrs};
1482   $self->throw_exception("Can't create pager for non-paged rs")
1483     unless $self->{attrs}{page};
1484   $attrs->{rows} ||= 10;
1485   return $self->{pager} ||= Data::Page->new(
1486     $self->_count, $attrs->{rows}, $self->{attrs}{page});
1487 }
1488
1489 =head2 page
1490
1491 =over 4
1492
1493 =item Arguments: $page_number
1494
1495 =item Return Value: $rs
1496
1497 =back
1498
1499 Returns a resultset for the $page_number page of the resultset on which page
1500 is called, where each page contains a number of rows equal to the 'rows'
1501 attribute set on the resultset (10 by default).
1502
1503 =cut
1504
1505 sub page {
1506   my ($self, $page) = @_;
1507   return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
1508 }
1509
1510 =head2 new_result
1511
1512 =over 4
1513
1514 =item Arguments: \%vals
1515
1516 =item Return Value: $rowobject
1517
1518 =back
1519
1520 Creates a new row object in the resultset's result class and returns
1521 it. The row is not inserted into the database at this point, call
1522 L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
1523 will tell you whether the row object has been inserted or not.
1524
1525 Passes the hashref of input on to L<DBIx::Class::Row/new>.
1526
1527 =cut
1528
1529 sub new_result {
1530   my ($self, $values) = @_;
1531   $self->throw_exception( "new_result needs a hash" )
1532     unless (ref $values eq 'HASH');
1533
1534   my %new;
1535   my $alias = $self->{attrs}{alias};
1536
1537   if (
1538     defined $self->{cond}
1539     && $self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION
1540   ) {
1541     %new = %{$self->{attrs}{related_objects}};
1542   } else {
1543     $self->throw_exception(
1544       "Can't abstract implicit construct, condition not a hash"
1545     ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1546   
1547     my $collapsed_cond = (
1548       $self->{cond}
1549         ? $self->_collapse_cond($self->{cond})
1550         : {}
1551     );
1552   
1553     # precendence must be given to passed values over values inherited from
1554     # the cond, so the order here is important.
1555     my %implied =  %{$self->_remove_alias($collapsed_cond, $alias)};
1556     while( my($col,$value) = each %implied ){
1557       if(ref($value) eq 'HASH' && keys(%$value) && (keys %$value)[0] eq '='){
1558         $new{$col} = $value->{'='};
1559         next;
1560       }
1561       $new{$col} = $value if $self->_is_deterministic_value($value);
1562     }
1563   }
1564
1565   %new = (
1566     %new,
1567     %{ $self->_remove_alias($values, $alias) },
1568     -source_handle => $self->_source_handle,
1569     -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
1570   );
1571
1572   return $self->result_class->new(\%new);
1573 }
1574
1575 # _is_deterministic_value
1576 #
1577 # Make an effor to strip non-deterministic values from the condition, 
1578 # to make sure new_result chokes less
1579
1580 sub _is_deterministic_value {
1581   my $self = shift;
1582   my $value = shift;
1583   my $ref_type = ref $value;
1584   return 1 if $ref_type eq '' || $ref_type eq 'SCALAR';
1585   return 1 if Scalar::Util::blessed($value);
1586   return 0;
1587 }
1588
1589 # _collapse_cond
1590 #
1591 # Recursively collapse the condition.
1592
1593 sub _collapse_cond {
1594   my ($self, $cond, $collapsed) = @_;
1595
1596   $collapsed ||= {};
1597
1598   if (ref $cond eq 'ARRAY') {
1599     foreach my $subcond (@$cond) {
1600       next unless ref $subcond;  # -or
1601 #      warn "ARRAY: " . Dumper $subcond;
1602       $collapsed = $self->_collapse_cond($subcond, $collapsed);
1603     }
1604   }
1605   elsif (ref $cond eq 'HASH') {
1606     if (keys %$cond and (keys %$cond)[0] eq '-and') {
1607       foreach my $subcond (@{$cond->{-and}}) {
1608 #        warn "HASH: " . Dumper $subcond;
1609         $collapsed = $self->_collapse_cond($subcond, $collapsed);
1610       }
1611     }
1612     else {
1613 #      warn "LEAF: " . Dumper $cond;
1614       foreach my $col (keys %$cond) {
1615         my $value = $cond->{$col};
1616         $collapsed->{$col} = $value;
1617       }
1618     }
1619   }
1620
1621   return $collapsed;
1622 }
1623
1624 # _remove_alias
1625 #
1626 # Remove the specified alias from the specified query hash. A copy is made so
1627 # the original query is not modified.
1628
1629 sub _remove_alias {
1630   my ($self, $query, $alias) = @_;
1631
1632   my %orig = %{ $query || {} };
1633   my %unaliased;
1634
1635   foreach my $key (keys %orig) {
1636     if ($key !~ /\./) {
1637       $unaliased{$key} = $orig{$key};
1638       next;
1639     }
1640     $unaliased{$1} = $orig{$key}
1641       if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
1642   }
1643
1644   return \%unaliased;
1645 }
1646
1647 =head2 find_or_new
1648
1649 =over 4
1650
1651 =item Arguments: \%vals, \%attrs?
1652
1653 =item Return Value: $rowobject
1654
1655 =back
1656
1657   my $artist = $schema->resultset('Artist')->find_or_new(
1658     { artist => 'fred' }, { key => 'artists' });
1659
1660   $cd->cd_to_producer->find_or_new({ producer => $producer },
1661                                    { key => 'primary });
1662
1663 Find an existing record from this resultset, based on it's primary
1664 key, or a unique constraint. If none exists, instantiate a new result
1665 object and return it. The object will not be saved into your storage
1666 until you call L<DBIx::Class::Row/insert> on it.
1667
1668 You most likely want this method when looking for existing rows using
1669 a unique constraint that is not the primary key, or looking for
1670 related rows.
1671
1672 If you want objects to be saved immediately, use L</find_or_create> instead.
1673
1674 B<Note>: C<find_or_new> is probably not what you want when creating a
1675 new row in a table that uses primary keys supplied by the
1676 database. Passing in a primary key column with a value of I<undef>
1677 will cause L</find> to attempt to search for a row with a value of
1678 I<NULL>.
1679
1680 =cut
1681
1682 sub find_or_new {
1683   my $self     = shift;
1684   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1685   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1686   my $exists   = $self->find($hash, $attrs);
1687   return defined $exists ? $exists : $self->new_result($hash);
1688 }
1689
1690 =head2 create
1691
1692 =over 4
1693
1694 =item Arguments: \%vals
1695
1696 =item Return Value: a L<DBIx::Class::Row> $object
1697
1698 =back
1699
1700 Attempt to create a single new row or a row with multiple related rows
1701 in the table represented by the resultset (and related tables). This
1702 will not check for duplicate rows before inserting, use
1703 L</find_or_create> to do that.
1704
1705 To create one row for this resultset, pass a hashref of key/value
1706 pairs representing the columns of the table and the values you wish to
1707 store. If the appropriate relationships are set up, foreign key fields
1708 can also be passed an object representing the foreign row, and the
1709 value will be set to it's primary key.
1710
1711 To create related objects, pass a hashref for the value if the related
1712 item is a foreign key relationship (L<DBIx::Class::Relationship/belongs_to>),
1713 and use the name of the relationship as the key. (NOT the name of the field,
1714 necessarily). For C<has_many> and C<has_one> relationships, pass an arrayref
1715 of hashrefs containing the data for each of the rows to create in the foreign
1716 tables, again using the relationship name as the key.
1717
1718 Instead of hashrefs of plain related data (key/value pairs), you may
1719 also pass new or inserted objects. New objects (not inserted yet, see
1720 L</new>), will be inserted into their appropriate tables.
1721
1722 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1723
1724 Example of creating a new row.
1725
1726   $person_rs->create({
1727     name=>"Some Person",
1728         email=>"somebody@someplace.com"
1729   });
1730   
1731 Example of creating a new row and also creating rows in a related C<has_many>
1732 or C<has_one> resultset.  Note Arrayref.
1733
1734   $artist_rs->create(
1735      { artistid => 4, name => 'Manufactured Crap', cds => [ 
1736         { title => 'My First CD', year => 2006 },
1737         { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1738       ],
1739      },
1740   );
1741
1742 Example of creating a new row and also creating a row in a related
1743 C<belongs_to>resultset. Note Hashref.
1744
1745   $cd_rs->create({
1746     title=>"Music for Silly Walks",
1747         year=>2000,
1748         artist => {
1749           name=>"Silly Musician",
1750         }
1751   });
1752
1753 =cut
1754
1755 sub create {
1756   my ($self, $attrs) = @_;
1757   $self->throw_exception( "create needs a hashref" )
1758     unless ref $attrs eq 'HASH';
1759   return $self->new_result($attrs)->insert;
1760 }
1761
1762 =head2 find_or_create
1763
1764 =over 4
1765
1766 =item Arguments: \%vals, \%attrs?
1767
1768 =item Return Value: $rowobject
1769
1770 =back
1771
1772   $cd->cd_to_producer->find_or_create({ producer => $producer },
1773                                       { key => 'primary });
1774
1775 Tries to find a record based on its primary key or unique constraints; if none
1776 is found, creates one and returns that instead.
1777
1778   my $cd = $schema->resultset('CD')->find_or_create({
1779     cdid   => 5,
1780     artist => 'Massive Attack',
1781     title  => 'Mezzanine',
1782     year   => 2005,
1783   });
1784
1785 Also takes an optional C<key> attribute, to search by a specific key or unique
1786 constraint. For example:
1787
1788   my $cd = $schema->resultset('CD')->find_or_create(
1789     {
1790       artist => 'Massive Attack',
1791       title  => 'Mezzanine',
1792     },
1793     { key => 'cd_artist_title' }
1794   );
1795
1796 B<Note>: Because find_or_create() reads from the database and then
1797 possibly inserts based on the result, this method is subject to a race
1798 condition. Another process could create a record in the table after
1799 the find has completed and before the create has started. To avoid
1800 this problem, use find_or_create() inside a transaction.
1801
1802 B<Note>: C<find_or_create> is probably not what you want when creating
1803 a new row in a table that uses primary keys supplied by the
1804 database. Passing in a primary key column with a value of I<undef>
1805 will cause L</find> to attempt to search for a row with a value of
1806 I<NULL>.
1807
1808 See also L</find> and L</update_or_create>. For information on how to declare
1809 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1810
1811 =cut
1812
1813 sub find_or_create {
1814   my $self     = shift;
1815   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1816   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1817   my $exists   = $self->find($hash, $attrs);
1818   return defined $exists ? $exists : $self->create($hash);
1819 }
1820
1821 =head2 update_or_create
1822
1823 =over 4
1824
1825 =item Arguments: \%col_values, { key => $unique_constraint }?
1826
1827 =item Return Value: $rowobject
1828
1829 =back
1830
1831   $resultset->update_or_create({ col => $val, ... });
1832
1833 First, searches for an existing row matching one of the unique constraints
1834 (including the primary key) on the source of this resultset. If a row is
1835 found, updates it with the other given column values. Otherwise, creates a new
1836 row.
1837
1838 Takes an optional C<key> attribute to search on a specific unique constraint.
1839 For example:
1840
1841   # In your application
1842   my $cd = $schema->resultset('CD')->update_or_create(
1843     {
1844       artist => 'Massive Attack',
1845       title  => 'Mezzanine',
1846       year   => 1998,
1847     },
1848     { key => 'cd_artist_title' }
1849   );
1850
1851   $cd->cd_to_producer->update_or_create({ 
1852     producer => $producer, 
1853     name => 'harry',
1854   }, { 
1855     key => 'primary,
1856   });
1857
1858
1859 If no C<key> is specified, it searches on all unique constraints defined on the
1860 source, including the primary key.
1861
1862 If the C<key> is specified as C<primary>, it searches only on the primary key.
1863
1864 See also L</find> and L</find_or_create>. For information on how to declare
1865 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1866
1867 B<Note>: C<update_or_create> is probably not what you want when
1868 looking for a row in a table that uses primary keys supplied by the
1869 database, unless you actually have a key value. Passing in a primary
1870 key column with a value of I<undef> will cause L</find> to attempt to
1871 search for a row with a value of I<NULL>.
1872
1873 =cut
1874
1875 sub update_or_create {
1876   my $self = shift;
1877   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1878   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
1879
1880   my $row = $self->find($cond, $attrs);
1881   if (defined $row) {
1882     $row->update($cond);
1883     return $row;
1884   }
1885
1886   return $self->create($cond);
1887 }
1888
1889 =head2 get_cache
1890
1891 =over 4
1892
1893 =item Arguments: none
1894
1895 =item Return Value: \@cache_objects?
1896
1897 =back
1898
1899 Gets the contents of the cache for the resultset, if the cache is set.
1900
1901 The cache is populated either by using the L</prefetch> attribute to
1902 L</search> or by calling L</set_cache>.
1903
1904 =cut
1905
1906 sub get_cache {
1907   shift->{all_cache};
1908 }
1909
1910 =head2 set_cache
1911
1912 =over 4
1913
1914 =item Arguments: \@cache_objects
1915
1916 =item Return Value: \@cache_objects
1917
1918 =back
1919
1920 Sets the contents of the cache for the resultset. Expects an arrayref
1921 of objects of the same class as those produced by the resultset. Note that
1922 if the cache is set the resultset will return the cached objects rather
1923 than re-querying the database even if the cache attr is not set.
1924
1925 The contents of the cache can also be populated by using the
1926 L</prefetch> attribute to L</search>.
1927
1928 =cut
1929
1930 sub set_cache {
1931   my ( $self, $data ) = @_;
1932   $self->throw_exception("set_cache requires an arrayref")
1933       if defined($data) && (ref $data ne 'ARRAY');
1934   $self->{all_cache} = $data;
1935 }
1936
1937 =head2 clear_cache
1938
1939 =over 4
1940
1941 =item Arguments: none
1942
1943 =item Return Value: []
1944
1945 =back
1946
1947 Clears the cache for the resultset.
1948
1949 =cut
1950
1951 sub clear_cache {
1952   shift->set_cache(undef);
1953 }
1954
1955 =head2 related_resultset
1956
1957 =over 4
1958
1959 =item Arguments: $relationship_name
1960
1961 =item Return Value: $resultset
1962
1963 =back
1964
1965 Returns a related resultset for the supplied relationship name.
1966
1967   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1968
1969 =cut
1970
1971 sub related_resultset {
1972   my ($self, $rel) = @_;
1973
1974   $self->{related_resultsets} ||= {};
1975   return $self->{related_resultsets}{$rel} ||= do {
1976     my $rel_obj = $self->result_source->relationship_info($rel);
1977
1978     $self->throw_exception(
1979       "search_related: result source '" . $self->result_source->source_name .
1980         "' has no such relationship $rel")
1981       unless $rel_obj;
1982     
1983     my ($from,$seen) = $self->_resolve_from($rel);
1984
1985     my $join_count = $seen->{$rel};
1986     my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
1987
1988     #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
1989     my %attrs = %{$self->{attrs}||{}};
1990     delete @attrs{qw(result_class alias)};
1991
1992     my $new_cache;
1993
1994     if (my $cache = $self->get_cache) {
1995       if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
1996         $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
1997                         @$cache ];
1998       }
1999     }
2000
2001     my $rel_source = $self->result_source->related_source($rel);
2002
2003     my $new = do {
2004
2005       # The reason we do this now instead of passing the alias to the
2006       # search_rs below is that if you wrap/overload resultset on the
2007       # source you need to know what alias it's -going- to have for things
2008       # to work sanely (e.g. RestrictWithObject wants to be able to add
2009       # extra query restrictions, and these may need to be $alias.)
2010
2011       my $attrs = $rel_source->resultset_attributes;
2012       local $attrs->{alias} = $alias;
2013
2014       $rel_source->resultset
2015                  ->search_rs(
2016                      undef, {
2017                        %attrs,
2018                        join => undef,
2019                        prefetch => undef,
2020                        select => undef,
2021                        as => undef,
2022                        where => $self->{cond},
2023                        seen_join => $seen,
2024                        from => $from,
2025                    });
2026     };
2027     $new->set_cache($new_cache) if $new_cache;
2028     $new;
2029   };
2030 }
2031
2032 sub _resolve_from {
2033   my ($self, $extra_join) = @_;
2034   my $source = $self->result_source;
2035   my $attrs = $self->{attrs};
2036   
2037   my $from = $attrs->{from}
2038     || [ { $attrs->{alias} => $source->from } ];
2039     
2040   my $seen = { %{$attrs->{seen_join}||{}} };
2041
2042   my $join = ($attrs->{join}
2043                ? [ $attrs->{join}, $extra_join ]
2044                : $extra_join);
2045
2046   # we need to take the prefetch the attrs into account before we 
2047   # ->resolve_join as otherwise they get lost - captainL
2048   my $merged = $self->_merge_attr( $join, $attrs->{prefetch} );
2049
2050   $from = [
2051     @$from,
2052     ($join ? $source->resolve_join($merged, $attrs->{alias}, $seen) : ()),
2053   ];
2054
2055   return ($from,$seen);
2056 }
2057
2058 sub _resolved_attrs {
2059   my $self = shift;
2060   return $self->{_attrs} if $self->{_attrs};
2061
2062   my $attrs = { %{$self->{attrs}||{}} };
2063   my $source = $self->result_source;
2064   my $alias = $attrs->{alias};
2065
2066   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
2067   if ($attrs->{columns}) {
2068     delete $attrs->{as};
2069   } elsif (!$attrs->{select}) {
2070     $attrs->{columns} = [ $source->columns ];
2071   }
2072  
2073   $attrs->{select} = 
2074     ($attrs->{select}
2075       ? (ref $attrs->{select} eq 'ARRAY'
2076           ? [ @{$attrs->{select}} ]
2077           : [ $attrs->{select} ])
2078       : [ map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}} ]
2079     );
2080   $attrs->{as} =
2081     ($attrs->{as}
2082       ? (ref $attrs->{as} eq 'ARRAY'
2083           ? [ @{$attrs->{as}} ]
2084           : [ $attrs->{as} ])
2085       : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}} ]
2086     );
2087   
2088   my $adds;
2089   if ($adds = delete $attrs->{include_columns}) {
2090     $adds = [$adds] unless ref $adds eq 'ARRAY';
2091     push(@{$attrs->{select}}, @$adds);
2092     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1 } @$adds);
2093   }
2094   if ($adds = delete $attrs->{'+select'}) {
2095     $adds = [$adds] unless ref $adds eq 'ARRAY';
2096     push(@{$attrs->{select}},
2097            map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds);
2098   }
2099   if (my $adds = delete $attrs->{'+as'}) {
2100     $adds = [$adds] unless ref $adds eq 'ARRAY';
2101     push(@{$attrs->{as}}, @$adds);
2102   }
2103
2104   $attrs->{from} ||= [ { 'me' => $source->from } ];
2105
2106   if (exists $attrs->{join} || exists $attrs->{prefetch}) {
2107     my $join = delete $attrs->{join} || {};
2108
2109     if (defined $attrs->{prefetch}) {
2110       $join = $self->_merge_attr(
2111         $join, $attrs->{prefetch}
2112       );
2113       
2114     }
2115
2116     $attrs->{from} =   # have to copy here to avoid corrupting the original
2117       [
2118         @{$attrs->{from}}, 
2119         $source->resolve_join($join, $alias, { %{$attrs->{seen_join}||{}} })
2120       ];
2121
2122   }
2123
2124   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
2125   if ($attrs->{order_by}) {
2126     $attrs->{order_by} = (ref($attrs->{order_by}) eq 'ARRAY'
2127                            ? [ @{$attrs->{order_by}} ]
2128                            : [ $attrs->{order_by} ]);
2129   } else {
2130     $attrs->{order_by} = [];    
2131   }
2132
2133   my $collapse = $attrs->{collapse} || {};
2134   if (my $prefetch = delete $attrs->{prefetch}) {
2135     $prefetch = $self->_merge_attr({}, $prefetch);
2136     my @pre_order;
2137     my $seen = $attrs->{seen_join} || {};
2138     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
2139       # bring joins back to level of current class
2140       my @prefetch = $source->resolve_prefetch(
2141         $p, $alias, $seen, \@pre_order, $collapse
2142       );
2143       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
2144       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
2145     }
2146     push(@{$attrs->{order_by}}, @pre_order);
2147   }
2148   $attrs->{collapse} = $collapse;
2149
2150   if ($attrs->{page}) {
2151     $attrs->{offset} ||= 0;
2152     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
2153   }
2154
2155   return $self->{_attrs} = $attrs;
2156 }
2157
2158 sub _rollout_attr {
2159   my ($self, $attr) = @_;
2160   
2161   if (ref $attr eq 'HASH') {
2162     return $self->_rollout_hash($attr);
2163   } elsif (ref $attr eq 'ARRAY') {
2164     return $self->_rollout_array($attr);
2165   } else {
2166     return [$attr];
2167   }
2168 }
2169
2170 sub _rollout_array {
2171   my ($self, $attr) = @_;
2172
2173   my @rolled_array;
2174   foreach my $element (@{$attr}) {
2175     if (ref $element eq 'HASH') {
2176       push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
2177     } elsif (ref $element eq 'ARRAY') {
2178       #  XXX - should probably recurse here
2179       push( @rolled_array, @{$self->_rollout_array($element)} );
2180     } else {
2181       push( @rolled_array, $element );
2182     }
2183   }
2184   return \@rolled_array;
2185 }
2186
2187 sub _rollout_hash {
2188   my ($self, $attr) = @_;
2189
2190   my @rolled_array;
2191   foreach my $key (keys %{$attr}) {
2192     push( @rolled_array, { $key => $attr->{$key} } );
2193   }
2194   return \@rolled_array;
2195 }
2196
2197 sub _calculate_score {
2198   my ($self, $a, $b) = @_;
2199
2200   if (ref $b eq 'HASH') {
2201     my ($b_key) = keys %{$b};
2202     if (ref $a eq 'HASH') {
2203       my ($a_key) = keys %{$a};
2204       if ($a_key eq $b_key) {
2205         return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
2206       } else {
2207         return 0;
2208       }
2209     } else {
2210       return ($a eq $b_key) ? 1 : 0;
2211     }       
2212   } else {
2213     if (ref $a eq 'HASH') {
2214       my ($a_key) = keys %{$a};
2215       return ($b eq $a_key) ? 1 : 0;
2216     } else {
2217       return ($b eq $a) ? 1 : 0;
2218     }
2219   }
2220 }
2221
2222 sub _merge_attr {
2223   my ($self, $orig, $import) = @_;
2224
2225   return $import unless defined($orig);
2226   return $orig unless defined($import);
2227   
2228   $orig = $self->_rollout_attr($orig);
2229   $import = $self->_rollout_attr($import);
2230
2231   my $seen_keys;
2232   foreach my $import_element ( @{$import} ) {
2233     # find best candidate from $orig to merge $b_element into
2234     my $best_candidate = { position => undef, score => 0 }; my $position = 0;
2235     foreach my $orig_element ( @{$orig} ) {
2236       my $score = $self->_calculate_score( $orig_element, $import_element );
2237       if ($score > $best_candidate->{score}) {
2238         $best_candidate->{position} = $position;
2239         $best_candidate->{score} = $score;
2240       }
2241       $position++;
2242     }
2243     my ($import_key) = ( ref $import_element eq 'HASH' ) ? keys %{$import_element} : ($import_element);
2244
2245     if ($best_candidate->{score} == 0 || exists $seen_keys->{$import_key}) {
2246       push( @{$orig}, $import_element );
2247     } else {
2248       my $orig_best = $orig->[$best_candidate->{position}];
2249       # merge orig_best and b_element together and replace original with merged
2250       if (ref $orig_best ne 'HASH') {
2251         $orig->[$best_candidate->{position}] = $import_element;
2252       } elsif (ref $import_element eq 'HASH') {
2253         my ($key) = keys %{$orig_best};
2254         $orig->[$best_candidate->{position}] = { $key => $self->_merge_attr($orig_best->{$key}, $import_element->{$key}) };
2255       }
2256     }
2257     $seen_keys->{$import_key} = 1; # don't merge the same key twice
2258   }
2259
2260   return $orig;
2261 }
2262
2263 sub result_source {
2264     my $self = shift;
2265
2266     if (@_) {
2267         $self->_source_handle($_[0]->handle);
2268     } else {
2269         $self->_source_handle->resolve;
2270     }
2271 }
2272
2273 =head2 throw_exception
2274
2275 See L<DBIx::Class::Schema/throw_exception> for details.
2276
2277 =cut
2278
2279 sub throw_exception {
2280   my $self=shift;
2281   if (ref $self && $self->_source_handle->schema) {
2282     $self->_source_handle->schema->throw_exception(@_)
2283   } else {
2284     croak(@_);
2285   }
2286
2287 }
2288
2289 # XXX: FIXME: Attributes docs need clearing up
2290
2291 =head1 ATTRIBUTES
2292
2293 The resultset takes various attributes that modify its behavior. Here's an
2294 overview of them:
2295
2296 =head2 order_by
2297
2298 =over 4
2299
2300 =item Value: ($order_by | \@order_by)
2301
2302 =back
2303
2304 Which column(s) to order the results by. This is currently passed
2305 through directly to SQL, so you can give e.g. C<year DESC> for a
2306 descending order on the column `year'.
2307
2308 Please note that if you have C<quote_char> enabled (see
2309 L<DBIx::Class::Storage::DBI/connect_info>) you will need to do C<\'year DESC' > to
2310 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
2311 so you will need to manually quote things as appropriate.)
2312
2313 =head2 columns
2314
2315 =over 4
2316
2317 =item Value: \@columns
2318
2319 =back
2320
2321 Shortcut to request a particular set of columns to be retrieved.  Adds
2322 C<me.> onto the start of any column without a C<.> in it and sets C<select>
2323 from that, then auto-populates C<as> from C<select> as normal. (You may also
2324 use the C<cols> attribute, as in earlier versions of DBIC.)
2325
2326 =head2 include_columns
2327
2328 =over 4
2329
2330 =item Value: \@columns
2331
2332 =back
2333
2334 Shortcut to include additional columns in the returned results - for example
2335
2336   $schema->resultset('CD')->search(undef, {
2337     include_columns => ['artist.name'],
2338     join => ['artist']
2339   });
2340
2341 would return all CDs and include a 'name' column to the information
2342 passed to object inflation. Note that the 'artist' is the name of the
2343 column (or relationship) accessor, and 'name' is the name of the column
2344 accessor in the related table.
2345
2346 =head2 select
2347
2348 =over 4
2349
2350 =item Value: \@select_columns
2351
2352 =back
2353
2354 Indicates which columns should be selected from the storage. You can use
2355 column names, or in the case of RDBMS back ends, function or stored procedure
2356 names:
2357
2358   $rs = $schema->resultset('Employee')->search(undef, {
2359     select => [
2360       'name',
2361       { count => 'employeeid' },
2362       { sum => 'salary' }
2363     ]
2364   });
2365
2366 When you use function/stored procedure names and do not supply an C<as>
2367 attribute, the column names returned are storage-dependent. E.g. MySQL would
2368 return a column named C<count(employeeid)> in the above example.
2369
2370 =head2 +select
2371
2372 =over 4
2373
2374 Indicates additional columns to be selected from storage.  Works the same as
2375 L</select> but adds columns to the selection.
2376
2377 =back
2378
2379 =head2 +as
2380
2381 =over 4
2382
2383 Indicates additional column names for those added via L</+select>.
2384
2385 =back
2386
2387 =head2 as
2388
2389 =over 4
2390
2391 =item Value: \@inflation_names
2392
2393 =back
2394
2395 Indicates column names for object inflation. That is, C<as>
2396 indicates the name that the column can be accessed as via the
2397 C<get_column> method (or via the object accessor, B<if one already
2398 exists>).  It has nothing to do with the SQL code C<SELECT foo AS bar>.
2399
2400 The C<as> attribute is used in conjunction with C<select>,
2401 usually when C<select> contains one or more function or stored
2402 procedure names:
2403
2404   $rs = $schema->resultset('Employee')->search(undef, {
2405     select => [
2406       'name',
2407       { count => 'employeeid' }
2408     ],
2409     as => ['name', 'employee_count'],
2410   });
2411
2412   my $employee = $rs->first(); # get the first Employee
2413
2414 If the object against which the search is performed already has an accessor
2415 matching a column name specified in C<as>, the value can be retrieved using
2416 the accessor as normal:
2417
2418   my $name = $employee->name();
2419
2420 If on the other hand an accessor does not exist in the object, you need to
2421 use C<get_column> instead:
2422
2423   my $employee_count = $employee->get_column('employee_count');
2424
2425 You can create your own accessors if required - see
2426 L<DBIx::Class::Manual::Cookbook> for details.
2427
2428 Please note: This will NOT insert an C<AS employee_count> into the SQL
2429 statement produced, it is used for internal access only. Thus
2430 attempting to use the accessor in an C<order_by> clause or similar
2431 will fail miserably.
2432
2433 To get around this limitation, you can supply literal SQL to your
2434 C<select> attibute that contains the C<AS alias> text, eg:
2435
2436   select => [\'myfield AS alias']
2437
2438 =head2 join
2439
2440 =over 4
2441
2442 =item Value: ($rel_name | \@rel_names | \%rel_names)
2443
2444 =back
2445
2446 Contains a list of relationships that should be joined for this query.  For
2447 example:
2448
2449   # Get CDs by Nine Inch Nails
2450   my $rs = $schema->resultset('CD')->search(
2451     { 'artist.name' => 'Nine Inch Nails' },
2452     { join => 'artist' }
2453   );
2454
2455 Can also contain a hash reference to refer to the other relation's relations.
2456 For example:
2457
2458   package MyApp::Schema::Track;
2459   use base qw/DBIx::Class/;
2460   __PACKAGE__->table('track');
2461   __PACKAGE__->add_columns(qw/trackid cd position title/);
2462   __PACKAGE__->set_primary_key('trackid');
2463   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
2464   1;
2465
2466   # In your application
2467   my $rs = $schema->resultset('Artist')->search(
2468     { 'track.title' => 'Teardrop' },
2469     {
2470       join     => { cd => 'track' },
2471       order_by => 'artist.name',
2472     }
2473   );
2474
2475 You need to use the relationship (not the table) name in  conditions, 
2476 because they are aliased as such. The current table is aliased as "me", so 
2477 you need to use me.column_name in order to avoid ambiguity. For example:
2478
2479   # Get CDs from 1984 with a 'Foo' track 
2480   my $rs = $schema->resultset('CD')->search(
2481     { 
2482       'me.year' => 1984,
2483       'tracks.name' => 'Foo'
2484     },
2485     { join => 'tracks' }
2486   );
2487   
2488 If the same join is supplied twice, it will be aliased to <rel>_2 (and
2489 similarly for a third time). For e.g.
2490
2491   my $rs = $schema->resultset('Artist')->search({
2492     'cds.title'   => 'Down to Earth',
2493     'cds_2.title' => 'Popular',
2494   }, {
2495     join => [ qw/cds cds/ ],
2496   });
2497
2498 will return a set of all artists that have both a cd with title 'Down
2499 to Earth' and a cd with title 'Popular'.
2500
2501 If you want to fetch related objects from other tables as well, see C<prefetch>
2502 below.
2503
2504 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
2505
2506 =head2 prefetch
2507
2508 =over 4
2509
2510 =item Value: ($rel_name | \@rel_names | \%rel_names)
2511
2512 =back
2513
2514 Contains one or more relationships that should be fetched along with
2515 the main query (when they are accessed afterwards the data will
2516 already be available, without extra queries to the database).  This is
2517 useful for when you know you will need the related objects, because it
2518 saves at least one query:
2519
2520   my $rs = $schema->resultset('Tag')->search(
2521     undef,
2522     {
2523       prefetch => {
2524         cd => 'artist'
2525       }
2526     }
2527   );
2528
2529 The initial search results in SQL like the following:
2530
2531   SELECT tag.*, cd.*, artist.* FROM tag
2532   JOIN cd ON tag.cd = cd.cdid
2533   JOIN artist ON cd.artist = artist.artistid
2534
2535 L<DBIx::Class> has no need to go back to the database when we access the
2536 C<cd> or C<artist> relationships, which saves us two SQL statements in this
2537 case.
2538
2539 Simple prefetches will be joined automatically, so there is no need
2540 for a C<join> attribute in the above search. 
2541
2542 C<prefetch> can be used with the following relationship types: C<belongs_to>,
2543 C<has_one> (or if you're using C<add_relationship>, any relationship declared
2544 with an accessor type of 'single' or 'filter'). A more complex example that
2545 prefetches an artists cds, the tracks on those cds, and the tags associted 
2546 with that artist is given below (assuming many-to-many from artists to tags):
2547
2548  my $rs = $schema->resultset('Artist')->search(
2549    undef,
2550    {
2551      prefetch => [
2552        { cds => 'tracks' },
2553        { artist_tags => 'tags' }
2554      ]
2555    }
2556  );
2557  
2558
2559 B<NOTE:> If you specify a C<prefetch> attribute, the C<join> and C<select>
2560 attributes will be ignored.
2561
2562 =head2 page
2563
2564 =over 4
2565
2566 =item Value: $page
2567
2568 =back
2569
2570 Makes the resultset paged and specifies the page to retrieve. Effectively
2571 identical to creating a non-pages resultset and then calling ->page($page)
2572 on it.
2573
2574 If L<rows> attribute is not specified it defualts to 10 rows per page.
2575
2576 =head2 rows
2577
2578 =over 4
2579
2580 =item Value: $rows
2581
2582 =back
2583
2584 Specifes the maximum number of rows for direct retrieval or the number of
2585 rows per page if the page attribute or method is used.
2586
2587 =head2 offset
2588
2589 =over 4
2590
2591 =item Value: $offset
2592
2593 =back
2594
2595 Specifies the (zero-based) row number for the  first row to be returned, or the
2596 of the first row of the first page if paging is used.
2597
2598 =head2 group_by
2599
2600 =over 4
2601
2602 =item Value: \@columns
2603
2604 =back
2605
2606 A arrayref of columns to group by. Can include columns of joined tables.
2607
2608   group_by => [qw/ column1 column2 ... /]
2609
2610 =head2 having
2611
2612 =over 4
2613
2614 =item Value: $condition
2615
2616 =back
2617
2618 HAVING is a select statement attribute that is applied between GROUP BY and
2619 ORDER BY. It is applied to the after the grouping calculations have been
2620 done.
2621
2622   having => { 'count(employee)' => { '>=', 100 } }
2623
2624 =head2 distinct
2625
2626 =over 4
2627
2628 =item Value: (0 | 1)
2629
2630 =back
2631
2632 Set to 1 to group by all columns.
2633
2634 =head2 where
2635
2636 =over 4
2637
2638 Adds to the WHERE clause.
2639
2640   # only return rows WHERE deleted IS NULL for all searches
2641   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
2642
2643 Can be overridden by passing C<{ where => undef }> as an attribute
2644 to a resulset.
2645
2646 =back
2647
2648 =head2 cache
2649
2650 Set to 1 to cache search results. This prevents extra SQL queries if you
2651 revisit rows in your ResultSet:
2652
2653   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
2654
2655   while( my $artist = $resultset->next ) {
2656     ... do stuff ...
2657   }
2658
2659   $rs->first; # without cache, this would issue a query
2660
2661 By default, searches are not cached.
2662
2663 For more examples of using these attributes, see
2664 L<DBIx::Class::Manual::Cookbook>.
2665
2666 =head2 from
2667
2668 =over 4
2669
2670 =item Value: \@from_clause
2671
2672 =back
2673
2674 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
2675 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
2676 clauses.
2677
2678 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
2679
2680 C<join> will usually do what you need and it is strongly recommended that you
2681 avoid using C<from> unless you cannot achieve the desired result using C<join>.
2682 And we really do mean "cannot", not just tried and failed. Attempting to use
2683 this because you're having problems with C<join> is like trying to use x86
2684 ASM because you've got a syntax error in your C. Trust us on this.
2685
2686 Now, if you're still really, really sure you need to use this (and if you're
2687 not 100% sure, ask the mailing list first), here's an explanation of how this
2688 works.
2689
2690 The syntax is as follows -
2691
2692   [
2693     { <alias1> => <table1> },
2694     [
2695       { <alias2> => <table2>, -join_type => 'inner|left|right' },
2696       [], # nested JOIN (optional)
2697       { <table1.column1> => <table2.column2>, ... (more conditions) },
2698     ],
2699     # More of the above [ ] may follow for additional joins
2700   ]
2701
2702   <table1> <alias1>
2703   JOIN
2704     <table2> <alias2>
2705     [JOIN ...]
2706   ON <table1.column1> = <table2.column2>
2707   <more joins may follow>
2708
2709 An easy way to follow the examples below is to remember the following:
2710
2711     Anything inside "[]" is a JOIN
2712     Anything inside "{}" is a condition for the enclosing JOIN
2713
2714 The following examples utilize a "person" table in a family tree application.
2715 In order to express parent->child relationships, this table is self-joined:
2716
2717     # Person->belongs_to('father' => 'Person');
2718     # Person->belongs_to('mother' => 'Person');
2719
2720 C<from> can be used to nest joins. Here we return all children with a father,
2721 then search against all mothers of those children:
2722
2723   $rs = $schema->resultset('Person')->search(
2724       undef,
2725       {
2726           alias => 'mother', # alias columns in accordance with "from"
2727           from => [
2728               { mother => 'person' },
2729               [
2730                   [
2731                       { child => 'person' },
2732                       [
2733                           { father => 'person' },
2734                           { 'father.person_id' => 'child.father_id' }
2735                       ]
2736                   ],
2737                   { 'mother.person_id' => 'child.mother_id' }
2738               ],
2739           ]
2740       },
2741   );
2742
2743   # Equivalent SQL:
2744   # SELECT mother.* FROM person mother
2745   # JOIN (
2746   #   person child
2747   #   JOIN person father
2748   #   ON ( father.person_id = child.father_id )
2749   # )
2750   # ON ( mother.person_id = child.mother_id )
2751
2752 The type of any join can be controlled manually. To search against only people
2753 with a father in the person table, we could explicitly use C<INNER JOIN>:
2754
2755     $rs = $schema->resultset('Person')->search(
2756         undef,
2757         {
2758             alias => 'child', # alias columns in accordance with "from"
2759             from => [
2760                 { child => 'person' },
2761                 [
2762                     { father => 'person', -join_type => 'inner' },
2763                     { 'father.id' => 'child.father_id' }
2764                 ],
2765             ]
2766         },
2767     );
2768
2769     # Equivalent SQL:
2770     # SELECT child.* FROM person child
2771     # INNER JOIN person father ON child.father_id = father.id
2772
2773 =head2 for
2774
2775 =over 4
2776
2777 =item Value: ( 'update' | 'shared' )
2778
2779 =back
2780
2781 Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT
2782 ... FOR SHARED.
2783
2784 =cut
2785
2786 1;