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