more fiddling, but it still don't work
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use overload
6         '0+'     => \&count,
7         'bool'   => sub { 1; },
8         fallback => 1;
9 use Carp::Clan qw/^DBIx::Class/;
10 use Data::Page;
11 use Storable;
12 use DBIx::Class::ResultSetColumn;
13 use base qw/DBIx::Class/;
14
15 use Data::Dumper; $Data::Dumper::Indent = 1;
16
17 __PACKAGE__->load_components(qw/AccessorGroup/);
18 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
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);
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 METHODS
56
57 =head2 new
58
59 =over 4
60
61 =item Arguments: $source, \%$attrs
62
63 =item Return Value: $rs
64
65 =back
66
67 The resultset constructor. Takes a source object (usually a
68 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
69 L</ATTRIBUTES> below).  Does not perform any queries -- these are
70 executed as needed by the other methods.
71
72 Generally you won't need to construct a resultset manually.  You'll
73 automatically get one from e.g. a L</search> called in scalar context:
74
75   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
76
77 IMPORTANT: If called on an object, proxies to new_result instead so
78
79   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
80
81 will return a CD object, not a ResultSet.
82
83 =cut
84
85 sub new {
86   my $class = shift;
87   return $class->new_result(@_) if ref $class;
88
89   my ($source, $attrs) = @_;
90   #weaken $source;
91
92   if ($attrs->{page}) {
93     $attrs->{rows} ||= 10;
94     $attrs->{offset} ||= 0;
95     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
96   }
97
98   $attrs->{alias} ||= 'me';
99
100   bless {
101     result_source => $source,
102     result_class => $attrs->{result_class} || $source->result_class,
103     cond => $attrs->{where},
104 #    from => $attrs->{from},
105 #    collapse => $collapse,
106     count => undef,
107     pager => undef,
108     attrs => $attrs
109   }, $class;
110 }
111
112 =head2 search
113
114 =over 4
115
116 =item Arguments: $cond, \%attrs?
117
118 =item Return Value: $resultset (scalar context), @row_objs (list context)
119
120 =back
121
122   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
123   my $new_rs = $cd_rs->search({ year => 2005 });
124
125   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
126                  # year = 2005 OR year = 2004
127
128 If you need to pass in additional attributes but no additional condition,
129 call it as C<search(undef, \%attrs)>.
130
131   # "SELECT name, artistid FROM $artist_table"
132   my @all_artists = $schema->resultset('Artist')->search(undef, {
133     columns => [qw/name artistid/],
134   });
135
136 =cut
137
138 sub search {
139   my $self = shift;
140   my $rs = $self->search_rs( @_ );
141   return (wantarray ? $rs->all : $rs);
142 }
143
144 =head2 search_rs
145
146 =over 4
147
148 =item Arguments: $cond, \%attrs?
149
150 =item Return Value: $resultset
151
152 =back
153
154 This method does the same exact thing as search() except it will
155 always return a resultset, even in list context.
156
157 =cut
158
159 sub search_rs {
160   my $self = shift;
161
162   my $rows;
163
164   unless (@_) {                 # no search, effectively just a clone
165     $rows = $self->get_cache;
166   }
167
168   my $attrs = {};
169   $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
170   my $our_attrs = exists $attrs->{_parent_attrs}
171     ? { %{delete $attrs->{_parent_attrs}} }
172     : { %{$self->{attrs}} };
173   my $having = delete $our_attrs->{having};
174
175   # merge new attrs into inherited
176   foreach my $key (qw/join prefetch/) {
177     next unless exists $attrs->{$key};
178     $our_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, delete $attrs->{$key});
179   }
180
181   my $new_attrs = { %{$our_attrs}, %{$attrs} };
182   my $where = (@_
183     ? (
184         (@_ == 1 || ref $_[0] eq "HASH")
185           ? shift
186           : (
187               (@_ % 2)
188                 ? $self->throw_exception("Odd number of arguments to search")
189                 : {@_}
190              )
191       )
192     : undef
193   );
194
195   if (defined $where) {
196     $new_attrs->{where} = (
197       defined $new_attrs->{where}
198         ? { '-and' => [
199               map {
200                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
201               } $where, $new_attrs->{where}
202             ]
203           }
204         : $where);
205   }
206
207   if (defined $having) {
208     $new_attrs->{having} = (
209       defined $new_attrs->{having}
210         ? { '-and' => [
211               map {
212                 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
213               } $having, $new_attrs->{having}
214             ]
215           }
216         : $having);
217   }
218
219   my $rs = (ref $self)->new($self->result_source, $new_attrs);
220   if ($rows) {
221     $rs->set_cache($rows);
222   }
223   return $rs;
224 }
225
226 =head2 search_literal
227
228 =over 4
229
230 =item Arguments: $sql_fragment, @bind_values
231
232 =item Return Value: $resultset (scalar context), @row_objs (list context)
233
234 =back
235
236   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
237   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
238
239 Pass a literal chunk of SQL to be added to the conditional part of the
240 resultset query.
241
242 =cut
243
244 sub search_literal {
245   my ($self, $cond, @vals) = @_;
246   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
247   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
248   return $self->search(\$cond, $attrs);
249 }
250
251 =head2 find
252
253 =over 4
254
255 =item Arguments: @values | \%cols, \%attrs?
256
257 =item Return Value: $row_object
258
259 =back
260
261 Finds a row based on its primary key or unique constraint. For example, to find
262 a row by its primary key:
263
264   my $cd = $schema->resultset('CD')->find(5);
265
266 You can also find a row by a specific unique constraint using the C<key>
267 attribute. For example:
268
269   my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', {
270     key => 'cd_artist_title'
271   });
272
273 Additionally, you can specify the columns explicitly by name:
274
275   my $cd = $schema->resultset('CD')->find(
276     {
277       artist => 'Massive Attack',
278       title  => 'Mezzanine',
279     },
280     { key => 'cd_artist_title' }
281   );
282
283 If the C<key> is specified as C<primary>, it searches only on the primary key.
284
285 If no C<key> is specified, it searches on all unique constraints defined on the
286 source, including the primary key.
287
288 See also L</find_or_create> and L</update_or_create>. For information on how to
289 declare unique constraints, see
290 L<DBIx::Class::ResultSource/add_unique_constraint>.
291
292 =cut
293
294 sub find {
295   my $self = shift;
296   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
297
298   # Default to the primary key, but allow a specific key
299   my @cols = exists $attrs->{key}
300     ? $self->result_source->unique_constraint_columns($attrs->{key})
301     : $self->result_source->primary_columns;
302   $self->throw_exception(
303     "Can't find unless a primary key or unique constraint is defined"
304   ) unless @cols;
305
306   # Parse out a hashref from input
307   my $input_query;
308   if (ref $_[0] eq 'HASH') {
309     $input_query = { %{$_[0]} };
310   }
311   elsif (@_ == @cols) {
312     $input_query = {};
313     @{$input_query}{@cols} = @_;
314   }
315   else {
316     # Compatibility: Allow e.g. find(id => $value)
317     carp "Find by key => value deprecated; please use a hashref instead";
318     $input_query = {@_};
319   }
320
321   my @unique_queries = $self->_unique_queries($input_query, $attrs);
322
323   # Handle cases where the ResultSet defines the query, or where the user is
324   # abusing find
325   my $query = @unique_queries ? \@unique_queries : $input_query;
326
327   # Run the query
328   if (keys %$attrs) {
329     my $rs = $self->search($query, $attrs);
330     return keys %{$rs->_resolved_attrs->{collapse}} ? $rs->next : $rs->single;
331   }
332   else {
333     return keys %{$self->_resolved_attrs->{collapse}}
334       ? $self->search($query)->next
335       : $self->single($query);
336   }
337 }
338
339 # _unique_queries
340 #
341 # Build a list of queries which satisfy unique constraints.
342
343 sub _unique_queries {
344   my ($self, $query, $attrs) = @_;
345
346   my $alias = $self->{attrs}{alias};
347   my @constraint_names = exists $attrs->{key}
348     ? ($attrs->{key})
349     : $self->result_source->unique_constraint_names;
350
351   my @unique_queries;
352   foreach my $name (@constraint_names) {
353     my @unique_cols = $self->result_source->unique_constraint_columns($name);
354     my $unique_query = $self->_build_unique_query($query, \@unique_cols);
355
356     my $num_query = scalar keys %$unique_query;
357     next unless $num_query;
358
359     # Add the ResultSet's alias
360     foreach my $col (grep { ! m/\./ } keys %$unique_query) {
361       $unique_query->{"$alias.$col"} = delete $unique_query->{$col};
362     }
363
364     # XXX: Assuming quite a bit about $self->{attrs}{where}
365     my $num_cols = scalar @unique_cols;
366     my $num_where = exists $self->{attrs}{where}
367       ? scalar keys %{ $self->{attrs}{where} }
368       : 0;
369     push @unique_queries, $unique_query
370       if $num_query + $num_where == $num_cols;
371   }
372
373   return @unique_queries;
374 }
375
376 # _build_unique_query
377 #
378 # Constrain the specified query hash based on the specified column names.
379
380 sub _build_unique_query {
381   my ($self, $query, $unique_cols) = @_;
382
383   return {
384     map  { $_ => $query->{$_} }
385     grep { exists $query->{$_} }
386       @$unique_cols
387   };
388 }
389
390 =head2 search_related
391
392 =over 4
393
394 =item Arguments: $rel, $cond, \%attrs?
395
396 =item Return Value: $new_resultset
397
398 =back
399
400   $new_rs = $cd_rs->search_related('artist', {
401     name => 'Emo-R-Us',
402   });
403
404 Searches the specified relationship, optionally specifying a condition and
405 attributes for matching records. See L</ATTRIBUTES> for more information.
406
407 =cut
408
409 sub search_related {
410   return shift->related_resultset(shift)->search(@_);
411 }
412
413 =head2 cursor
414
415 =over 4
416
417 =item Arguments: none
418
419 =item Return Value: $cursor
420
421 =back
422
423 Returns a storage-driven cursor to the given resultset. See
424 L<DBIx::Class::Cursor> for more information.
425
426 =cut
427
428 sub cursor {
429   my ($self) = @_;
430
431   my $attrs = { %{$self->_resolved_attrs} };
432   return $self->{cursor}
433     ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
434           $attrs->{where},$attrs);
435 }
436
437 =head2 single
438
439 =over 4
440
441 =item Arguments: $cond?
442
443 =item Return Value: $row_object?
444
445 =back
446
447   my $cd = $schema->resultset('CD')->single({ year => 2001 });
448
449 Inflates the first result without creating a cursor if the resultset has
450 any records in it; if not returns nothing. Used by L</find> as an optimisation.
451
452 Can optionally take an additional condition *only* - this is a fast-code-path
453 method; if you need to add extra joins or similar call ->search and then
454 ->single without a condition on the $rs returned from that.
455
456 =cut
457
458 sub single {
459   my ($self, $where) = @_;
460   my $attrs = { %{$self->_resolved_attrs} };
461   if ($where) {
462     if (defined $attrs->{where}) {
463       $attrs->{where} = {
464         '-and' =>
465             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
466                $where, delete $attrs->{where} ]
467       };
468     } else {
469       $attrs->{where} = $where;
470     }
471   }
472
473   unless ($self->_is_unique_query($attrs->{where})) {
474     carp "Query not guaranteed to return a single row"
475       . "; please declare your unique constraints or use search instead";
476   }
477
478   my @data = $self->result_source->storage->select_single(
479     $attrs->{from}, $attrs->{select},
480     $attrs->{where}, $attrs
481   );
482
483   return (@data ? $self->_construct_object(@data) : ());
484 }
485
486 # _is_unique_query
487 #
488 # Try to determine if the specified query is guaranteed to be unique, based on
489 # the declared unique constraints.
490
491 sub _is_unique_query {
492   my ($self, $query) = @_;
493
494   my $collapsed = $self->_collapse_query($query);
495   my $alias = $self->{attrs}{alias};
496
497   foreach my $name ($self->result_source->unique_constraint_names) {
498     my @unique_cols = map {
499       "$alias.$_"
500     } $self->result_source->unique_constraint_columns($name);
501
502     # Count the values for each unique column
503     my %seen = map { $_ => 0 } @unique_cols;
504
505     foreach my $key (keys %$collapsed) {
506       my $aliased = $key =~ /\./ ? $key : "$alias.$key";
507       next unless exists $seen{$aliased};  # Additional constraints are okay
508       $seen{$aliased} = scalar keys %{ $collapsed->{$key} };
509     }
510
511     # If we get 0 or more than 1 value for a column, it's not necessarily unique
512     return 1 unless grep { $_ != 1 } values %seen;
513   }
514
515   return 0;
516 }
517
518 # _collapse_query
519 #
520 # Recursively collapse the query, accumulating values for each column.
521
522 sub _collapse_query {
523   my ($self, $query, $collapsed) = @_;
524
525   $collapsed ||= {};
526
527   if (ref $query eq 'ARRAY') {
528     foreach my $subquery (@$query) {
529       next unless ref $subquery;  # -or
530 #      warn "ARRAY: " . Dumper $subquery;
531       $collapsed = $self->_collapse_query($subquery, $collapsed);
532     }
533   }
534   elsif (ref $query eq 'HASH') {
535     if (keys %$query and (keys %$query)[0] eq '-and') {
536       foreach my $subquery (@{$query->{-and}}) {
537 #        warn "HASH: " . Dumper $subquery;
538         $collapsed = $self->_collapse_query($subquery, $collapsed);
539       }
540     }
541     else {
542 #      warn "LEAF: " . Dumper $query;
543       foreach my $col (keys %$query) {
544         my $value = $query->{$col};
545         $collapsed->{$col}{$value}++;
546       }
547     }
548   }
549
550   return $collapsed;
551 }
552
553 =head2 get_column
554
555 =over 4
556
557 =item Arguments: $cond?
558
559 =item Return Value: $resultsetcolumn
560
561 =back
562
563   my $max_length = $rs->get_column('length')->max;
564
565 Returns a ResultSetColumn instance for $column based on $self
566
567 =cut
568
569 sub get_column {
570   my ($self, $column) = @_;
571   my $new = DBIx::Class::ResultSetColumn->new($self, $column);
572   return $new;
573 }
574
575 =head2 search_like
576
577 =over 4
578
579 =item Arguments: $cond, \%attrs?
580
581 =item Return Value: $resultset (scalar context), @row_objs (list context)
582
583 =back
584
585   # WHERE title LIKE '%blue%'
586   $cd_rs = $rs->search_like({ title => '%blue%'});
587
588 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
589 that this is simply a convenience method. You most likely want to use
590 L</search> with specific operators.
591
592 For more information, see L<DBIx::Class::Manual::Cookbook>.
593
594 =cut
595
596 sub search_like {
597   my $class = shift;
598   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
599   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
600   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
601   return $class->search($query, { %$attrs });
602 }
603
604 =head2 slice
605
606 =over 4
607
608 =item Arguments: $first, $last
609
610 =item Return Value: $resultset (scalar context), @row_objs (list context)
611
612 =back
613
614 Returns a resultset or object list representing a subset of elements from the
615 resultset slice is called on. Indexes are from 0, i.e., to get the first
616 three records, call:
617
618   my ($one, $two, $three) = $rs->slice(0, 2);
619
620 =cut
621
622 sub slice {
623   my ($self, $min, $max) = @_;
624   my $attrs = {}; # = { %{ $self->{attrs} || {} } };
625   $attrs->{offset} = $self->{attrs}{offset} || 0;
626   $attrs->{offset} += $min;
627   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
628   return $self->search(undef(), $attrs);
629   #my $slice = (ref $self)->new($self->result_source, $attrs);
630   #return (wantarray ? $slice->all : $slice);
631 }
632
633 =head2 next
634
635 =over 4
636
637 =item Arguments: none
638
639 =item Return Value: $result?
640
641 =back
642
643 Returns the next element in the resultset (C<undef> is there is none).
644
645 Can be used to efficiently iterate over records in the resultset:
646
647   my $rs = $schema->resultset('CD')->search;
648   while (my $cd = $rs->next) {
649     print $cd->title;
650   }
651
652 Note that you need to store the resultset object, and call C<next> on it.
653 Calling C<< resultset('Table')->next >> repeatedly will always return the
654 first record from the resultset.
655
656 =cut
657
658 sub next {
659   my ($self) = @_;
660   if (my $cache = $self->get_cache) {
661     $self->{all_cache_position} ||= 0;
662     return $cache->[$self->{all_cache_position}++];
663   }
664   if ($self->{attrs}{cache}) {
665     $self->{all_cache_position} = 1;
666     return ($self->all)[0];
667   }
668   my @row = (
669     exists $self->{stashed_row}
670       ? @{delete $self->{stashed_row}}
671       : $self->cursor->next
672   );
673   return unless (@row);
674   return $self->_construct_object(@row);
675 }
676
677 sub _resolved_attrs {
678   my $self = shift;
679   return $self->{_attrs} if $self->{_attrs};
680
681   my $attrs = { %{$self->{attrs}||{}} };
682   my $source = $self->{result_source};
683   my $alias = $attrs->{alias};
684
685   # XXX - lose storable dclone
686   my $record_filter = delete $attrs->{record_filter};
687   #$attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
688
689   $attrs->{record_filter} = $record_filter if $record_filter;
690
691   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
692   if ($attrs->{columns}) {
693     delete $attrs->{as};
694   } elsif (!$attrs->{select}) {
695     $attrs->{columns} = [ $self->{result_source}->columns ];
696   }
697   
698   my $select_alias = $self->{attrs}{alias};
699   $attrs->{select} ||= [
700     map { m/\./ ? $_ : "${select_alias}.$_" } @{delete $attrs->{columns}}
701   ];
702   $attrs->{as} ||= [
703     map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}}
704   ];
705   
706   my $adds;
707   if ($adds = delete $attrs->{include_columns}) {
708     $adds = [$adds] unless ref $adds eq 'ARRAY';
709     push(@{$attrs->{select}}, @$adds);
710     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1 } @$adds);
711   }
712   if ($adds = delete $attrs->{'+select'}) {
713     $adds = [$adds] unless ref $adds eq 'ARRAY';
714     push(@{$attrs->{select}}, map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds);
715   }
716   if (my $adds = delete $attrs->{'+as'}) {
717     $adds = [$adds] unless ref $adds eq 'ARRAY';
718     push(@{$attrs->{as}}, @$adds);
719   }
720
721
722   $attrs->{from} ||= $attrs->{_parent_from}
723     || [ { $alias => $source->from } ];
724   #$attrs->{from} ||= [ { $alias => $source->from } ];
725
726   if (exists $attrs->{join} || exists $attrs->{prefetch}) {
727
728     my $join = delete $attrs->{join} || {};
729
730     if (defined $attrs->{prefetch}) {
731       $join = $self->_merge_attr(
732         $join, $attrs->{prefetch}
733       );
734     }
735
736     push(@{$attrs->{from}},
737       $source->resolve_join($join, $alias, { %{$self->{_parent_seen_join}||{}} })
738     );
739   }
740
741   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
742   if ($attrs->{order_by}) {
743     $attrs->{order_by} = [ $attrs->{order_by} ] unless ref $attrs->{order_by};    
744   } else {
745     $attrs->{order_by} ||= [];    
746   }
747
748   my $collapse = $attrs->{collapse} || {};
749   if (my $prefetch = delete $attrs->{prefetch}) {
750     my @pre_order;
751     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
752       # bring joins back to level of current class
753       my @prefetch = $source->resolve_prefetch(
754         $p, $alias, { %{$attrs->{_parent_seen_join}||{}} }, \@pre_order, $collapse
755       );
756       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
757       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
758     }
759     push(@{$attrs->{order_by}}, @pre_order);
760   }
761   $attrs->{collapse} = $collapse;
762
763   return $self->{_attrs} = $attrs;
764 }
765
766 sub _resolve_from {
767   my ($self) = @_;
768   my $source = $self->result_source;
769   my $attrs = $self->{attrs};
770   
771   my $from = $attrs->{_parent_from}
772     || [ { $attrs->{alias} => $source->from } ];
773     
774   my $seen = { %{$attrs->{_parent_seen_join}||{}} };
775   
776   if ($attrs->{join}) {
777     push(@{$from}, 
778       $source->resolve_join($attrs->{join}, $attrs->{alias}, $seen)
779     );
780   }
781   
782   return ($from,$seen);
783 }
784
785 sub _merge_attr {
786   my ($self, $a, $b) = @_;
787   return $b unless $a;
788   
789   if (ref $b eq 'HASH' && ref $a eq 'HASH') {
790     foreach my $key (keys %{$b}) {
791       if (exists $a->{$key}) {
792         $a->{$key} = $self->_merge_attr($a->{$key}, $b->{$key});
793       } else {
794         $a->{$key} = $b->{$key};
795       }
796     }
797     return $a;
798   } else {
799     $a = [$a] unless ref $a eq 'ARRAY';
800     $b = [$b] unless ref $b eq 'ARRAY';
801
802     my $hash = {};
803     my @array;
804     foreach my $x ($a, $b) {
805       foreach my $element (@{$x}) {
806         if (ref $element eq 'HASH') {
807           $hash = $self->_merge_attr($hash, $element);
808         } elsif (ref $element eq 'ARRAY') {
809           push(@array, @{$element});
810         } else {
811           push(@array, $element) unless $b == $x
812             && grep { $_ eq $element } @array;
813         }
814       }
815     }
816     
817     @array = grep { !exists $hash->{$_} } @array;
818
819     return keys %{$hash}
820       ? ( scalar(@array)
821             ? [$hash, @array]
822             : $hash
823         )
824       : \@array;
825   }
826 }
827
828 sub _construct_object {
829   my ($self, @row) = @_;
830   my $info = $self->_collapse_result($self->{_attrs}{as}, \@row);
831   my $new = $self->result_class->inflate_result($self->result_source, @$info);
832   $new = $self->{_attrs}{record_filter}->($new)
833     if exists $self->{_attrs}{record_filter};
834   return $new;
835 }
836
837 sub _collapse_result {
838   my ($self, $as, $row, $prefix) = @_;
839
840   my %const;
841   my @copy = @$row;
842   
843   foreach my $this_as (@$as) {
844     my $val = shift @copy;
845     if (defined $prefix) {
846       if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
847         my $remain = $1;
848         $remain =~ /^(?:(.*)\.)?([^.]+)$/;
849         $const{$1||''}{$2} = $val;
850       }
851     } else {
852       $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
853       $const{$1||''}{$2} = $val;
854     }
855   }
856
857   my $alias = $self->{attrs}{alias};
858   my $info = [ {}, {} ];
859   foreach my $key (keys %const) {
860     if (length $key && $key ne $alias) {
861       my $target = $info;
862       my @parts = split(/\./, $key);
863       foreach my $p (@parts) {
864         $target = $target->[1]->{$p} ||= [];
865       }
866       $target->[0] = $const{$key};
867     } else {
868       $info->[0] = $const{$key};
869     }
870   }
871   
872   my @collapse;
873   if (defined $prefix) {
874     @collapse = map {
875         m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
876     } keys %{$self->{_attrs}{collapse}}
877   } else {
878     @collapse = keys %{$self->{_attrs}{collapse}};
879   };
880
881   if (@collapse) {
882     my ($c) = sort { length $a <=> length $b } @collapse;
883     my $target = $info;
884     foreach my $p (split(/\./, $c)) {
885       $target = $target->[1]->{$p} ||= [];
886     }
887     my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
888     my @co_key = @{$self->{_attrs}{collapse}{$c_prefix}};
889     my $tree = $self->_collapse_result($as, $row, $c_prefix);
890     my %co_check = map { ($_, $tree->[0]->{$_}); } @co_key;
891     my (@final, @raw);
892
893     while (
894       !(
895         grep {
896           !defined($tree->[0]->{$_}) || $co_check{$_} ne $tree->[0]->{$_}
897         } @co_key
898         )
899     ) {
900       push(@final, $tree);
901       last unless (@raw = $self->cursor->next);
902       $row = $self->{stashed_row} = \@raw;
903       $tree = $self->_collapse_result($as, $row, $c_prefix);
904     }
905     @$target = (@final ? @final : [ {}, {} ]);
906       # single empty result to indicate an empty prefetched has_many
907   }
908
909   #print "final info: " . Dumper($info);
910   return $info;
911 }
912
913 =head2 result_source
914
915 =over 4
916
917 =item Arguments: $result_source?
918
919 =item Return Value: $result_source
920
921 =back
922
923 An accessor for the primary ResultSource object from which this ResultSet
924 is derived.
925
926 =cut
927
928
929 =head2 count
930
931 =over 4
932
933 =item Arguments: $cond, \%attrs??
934
935 =item Return Value: $count
936
937 =back
938
939 Performs an SQL C<COUNT> with the same query as the resultset was built
940 with to find the number of elements. If passed arguments, does a search
941 on the resultset and counts the results of that.
942
943 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
944 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
945 not support C<DISTINCT> with multiple columns. If you are using such a
946 database, you should only use columns from the main table in your C<group_by>
947 clause.
948
949 =cut
950
951 sub count {
952   my $self = shift;
953   return $self->search(@_)->count if @_ and defined $_[0];
954   return scalar @{ $self->get_cache } if $self->get_cache;
955   my $count = $self->_count;
956   return 0 unless $count;
957
958   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
959   $count = $self->{attrs}{rows} if
960     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
961   return $count;
962 }
963
964 sub _count { # Separated out so pager can get the full count
965   my $self = shift;
966   my $select = { count => '*' };
967
968   my $attrs = { %{$self->_resolved_attrs} };
969   if (my $group_by = delete $attrs->{group_by}) {
970     delete $attrs->{having};
971     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
972     # todo: try CONCAT for multi-column pk
973     my @pk = $self->result_source->primary_columns;
974     if (@pk == 1) {
975       my $alias = $attrs->{alias};
976       foreach my $column (@distinct) {
977         if ($column =~ qr/^(?:\Q${alias}.\E)?$pk[0]$/) {
978           @distinct = ($column);
979           last;
980         }
981       }
982     }
983
984     $select = { count => { distinct => \@distinct } };
985   }
986
987   $attrs->{select} = $select;
988   $attrs->{as} = [qw/count/];
989
990   # offset, order by and page are not needed to count. record_filter is cdbi
991   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
992
993   my $tmp_rs = (ref $self)->new($self->result_source, $attrs);
994   my ($count) = $tmp_rs->cursor->next;
995   return $count;
996 }
997
998 =head2 count_literal
999
1000 =over 4
1001
1002 =item Arguments: $sql_fragment, @bind_values
1003
1004 =item Return Value: $count
1005
1006 =back
1007
1008 Counts the results in a literal query. Equivalent to calling L</search_literal>
1009 with the passed arguments, then L</count>.
1010
1011 =cut
1012
1013 sub count_literal { shift->search_literal(@_)->count; }
1014
1015 =head2 all
1016
1017 =over 4
1018
1019 =item Arguments: none
1020
1021 =item Return Value: @objects
1022
1023 =back
1024
1025 Returns all elements in the resultset. Called implicitly if the resultset
1026 is returned in list context.
1027
1028 =cut
1029
1030 sub all {
1031   my ($self) = @_;
1032   return @{ $self->get_cache } if $self->get_cache;
1033
1034   my @obj;
1035
1036   # TODO: don't call resolve here
1037   if (keys %{$self->_resolved_attrs->{collapse}}) {
1038 #  if ($self->{attrs}{prefetch}) {
1039       # Using $self->cursor->all is really just an optimisation.
1040       # If we're collapsing has_many prefetches it probably makes
1041       # very little difference, and this is cleaner than hacking
1042       # _construct_object to survive the approach
1043     my @row = $self->cursor->next;
1044     while (@row) {
1045       push(@obj, $self->_construct_object(@row));
1046       @row = (exists $self->{stashed_row}
1047                ? @{delete $self->{stashed_row}}
1048                : $self->cursor->next);
1049     }
1050   } else {
1051     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
1052   }
1053
1054   $self->set_cache(\@obj) if $self->{attrs}{cache};
1055   return @obj;
1056 }
1057
1058 =head2 reset
1059
1060 =over 4
1061
1062 =item Arguments: none
1063
1064 =item Return Value: $self
1065
1066 =back
1067
1068 Resets the resultset's cursor, so you can iterate through the elements again.
1069
1070 =cut
1071
1072 sub reset {
1073   my ($self) = @_;
1074   delete $self->{_attrs} if exists $self->{_attrs};
1075   $self->{all_cache_position} = 0;
1076   $self->cursor->reset;
1077   return $self;
1078 }
1079
1080 =head2 first
1081
1082 =over 4
1083
1084 =item Arguments: none
1085
1086 =item Return Value: $object?
1087
1088 =back
1089
1090 Resets the resultset and returns an object for the first result (if the
1091 resultset returns anything).
1092
1093 =cut
1094
1095 sub first {
1096   return $_[0]->reset->next;
1097 }
1098
1099 # _cond_for_update_delete
1100 #
1101 # update/delete require the condition to be modified to handle
1102 # the differing SQL syntax available.  This transforms the $self->{cond}
1103 # appropriately, returning the new condition.
1104
1105 sub _cond_for_update_delete {
1106   my ($self) = @_;
1107   my $cond = {};
1108
1109   # No-op. No condition, we're updating/deleting everything
1110   return $cond unless ref $self->{cond};
1111
1112   if (ref $self->{cond} eq 'ARRAY') {
1113     $cond = [
1114       map {
1115         my %hash;
1116         foreach my $key (keys %{$_}) {
1117           $key =~ /([^.]+)$/;
1118           $hash{$1} = $_->{$key};
1119         }
1120         \%hash;
1121       } @{$self->{cond}}
1122     ];
1123   }
1124   elsif (ref $self->{cond} eq 'HASH') {
1125     if ((keys %{$self->{cond}})[0] eq '-and') {
1126       $cond->{-and} = [];
1127
1128       my @cond = @{$self->{cond}{-and}};
1129       for (my $i = 0; $i < @cond; $i++) {
1130         my $entry = $cond[$i];
1131
1132         my %hash;
1133         if (ref $entry eq 'HASH') {
1134           foreach my $key (keys %{$entry}) {
1135             $key =~ /([^.]+)$/;
1136             $hash{$1} = $entry->{$key};
1137           }
1138         }
1139         else {
1140           $entry =~ /([^.]+)$/;
1141           $hash{$1} = $cond[++$i];
1142         }
1143
1144         push @{$cond->{-and}}, \%hash;
1145       }
1146     }
1147     else {
1148       foreach my $key (keys %{$self->{cond}}) {
1149         $key =~ /([^.]+)$/;
1150         $cond->{$1} = $self->{cond}{$key};
1151       }
1152     }
1153   }
1154   else {
1155     $self->throw_exception(
1156       "Can't update/delete on resultset with condition unless hash or array"
1157     );
1158   }
1159
1160   return $cond;
1161 }
1162
1163
1164 =head2 update
1165
1166 =over 4
1167
1168 =item Arguments: \%values
1169
1170 =item Return Value: $storage_rv
1171
1172 =back
1173
1174 Sets the specified columns in the resultset to the supplied values in a
1175 single query. Return value will be true if the update succeeded or false
1176 if no records were updated; exact type of success value is storage-dependent.
1177
1178 =cut
1179
1180 sub update {
1181   my ($self, $values) = @_;
1182   $self->throw_exception("Values for update must be a hash")
1183     unless ref $values eq 'HASH';
1184
1185   my $cond = $self->_cond_for_update_delete;
1186
1187   return $self->result_source->storage->update(
1188     $self->result_source->from, $values, $cond
1189   );
1190 }
1191
1192 =head2 update_all
1193
1194 =over 4
1195
1196 =item Arguments: \%values
1197
1198 =item Return Value: 1
1199
1200 =back
1201
1202 Fetches all objects and updates them one at a time. Note that C<update_all>
1203 will run DBIC cascade triggers, while L</update> will not.
1204
1205 =cut
1206
1207 sub update_all {
1208   my ($self, $values) = @_;
1209   $self->throw_exception("Values for update must be a hash")
1210     unless ref $values eq 'HASH';
1211   foreach my $obj ($self->all) {
1212     $obj->set_columns($values)->update;
1213   }
1214   return 1;
1215 }
1216
1217 =head2 delete
1218
1219 =over 4
1220
1221 =item Arguments: none
1222
1223 =item Return Value: 1
1224
1225 =back
1226
1227 Deletes the contents of the resultset from its result source. Note that this
1228 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1229 to run.
1230
1231 =cut
1232
1233 sub delete {
1234   my ($self) = @_;
1235
1236   my $cond = $self->_cond_for_update_delete;
1237
1238   $self->result_source->storage->delete($self->result_source->from, $cond);
1239   return 1;
1240 }
1241
1242 =head2 delete_all
1243
1244 =over 4
1245
1246 =item Arguments: none
1247
1248 =item Return Value: 1
1249
1250 =back
1251
1252 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1253 will run DBIC cascade triggers, while L</delete> will not.
1254
1255 =cut
1256
1257 sub delete_all {
1258   my ($self) = @_;
1259   $_->delete for $self->all;
1260   return 1;
1261 }
1262
1263 =head2 pager
1264
1265 =over 4
1266
1267 =item Arguments: none
1268
1269 =item Return Value: $pager
1270
1271 =back
1272
1273 Return Value a L<Data::Page> object for the current resultset. Only makes
1274 sense for queries with a C<page> attribute.
1275
1276 =cut
1277
1278 sub pager {
1279   my ($self) = @_;
1280   my $attrs = $self->{attrs};
1281   $self->throw_exception("Can't create pager for non-paged rs")
1282     unless $self->{attrs}{page};
1283   $attrs->{rows} ||= 10;
1284   return $self->{pager} ||= Data::Page->new(
1285     $self->_count, $attrs->{rows}, $self->{attrs}{page});
1286 }
1287
1288 =head2 page
1289
1290 =over 4
1291
1292 =item Arguments: $page_number
1293
1294 =item Return Value: $rs
1295
1296 =back
1297
1298 Returns a resultset for the $page_number page of the resultset on which page
1299 is called, where each page contains a number of rows equal to the 'rows'
1300 attribute set on the resultset (10 by default).
1301
1302 =cut
1303
1304 sub page {
1305   my ($self, $page) = @_;
1306   return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
1307 }
1308
1309 =head2 new_result
1310
1311 =over 4
1312
1313 =item Arguments: \%vals
1314
1315 =item Return Value: $object
1316
1317 =back
1318
1319 Creates an object in the resultset's result class and returns it.
1320
1321 =cut
1322
1323 sub new_result {
1324   my ($self, $values) = @_;
1325   $self->throw_exception( "new_result needs a hash" )
1326     unless (ref $values eq 'HASH');
1327   $self->throw_exception(
1328     "Can't abstract implicit construct, condition not a hash"
1329   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1330   my %new = %$values;
1331   my $alias = $self->{attrs}{alias};
1332   foreach my $key (keys %{$self->{cond}||{}}) {
1333     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:\Q${alias}.\E)?([^.]+)$/);
1334   }
1335   my $obj = $self->result_class->new(\%new);
1336   $obj->result_source($self->result_source) if $obj->can('result_source');
1337   return $obj;
1338 }
1339
1340 =head2 find_or_new
1341
1342 =over 4
1343
1344 =item Arguments: \%vals, \%attrs?
1345
1346 =item Return Value: $object
1347
1348 =back
1349
1350 Find an existing record from this resultset. If none exists, instantiate a new
1351 result object and return it. The object will not be saved into your storage
1352 until you call L<DBIx::Class::Row/insert> on it.
1353
1354 If you want objects to be saved immediately, use L</find_or_create> instead.
1355
1356 =cut
1357
1358 sub find_or_new {
1359   my $self     = shift;
1360   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1361   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1362   my $exists   = $self->find($hash, $attrs);
1363   return defined $exists ? $exists : $self->new_result($hash);
1364 }
1365
1366 =head2 create
1367
1368 =over 4
1369
1370 =item Arguments: \%vals
1371
1372 =item Return Value: $object
1373
1374 =back
1375
1376 Inserts a record into the resultset and returns the object representing it.
1377
1378 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1379
1380 =cut
1381
1382 sub create {
1383   my ($self, $attrs) = @_;
1384   $self->throw_exception( "create needs a hashref" )
1385     unless ref $attrs eq 'HASH';
1386   return $self->new_result($attrs)->insert;
1387 }
1388
1389 =head2 find_or_create
1390
1391 =over 4
1392
1393 =item Arguments: \%vals, \%attrs?
1394
1395 =item Return Value: $object
1396
1397 =back
1398
1399   $class->find_or_create({ key => $val, ... });
1400
1401 Tries to find a record based on its primary key or unique constraint; if none
1402 is found, creates one and returns that instead.
1403
1404   my $cd = $schema->resultset('CD')->find_or_create({
1405     cdid   => 5,
1406     artist => 'Massive Attack',
1407     title  => 'Mezzanine',
1408     year   => 2005,
1409   });
1410
1411 Also takes an optional C<key> attribute, to search by a specific key or unique
1412 constraint. For example:
1413
1414   my $cd = $schema->resultset('CD')->find_or_create(
1415     {
1416       artist => 'Massive Attack',
1417       title  => 'Mezzanine',
1418     },
1419     { key => 'cd_artist_title' }
1420   );
1421
1422 See also L</find> and L</update_or_create>. For information on how to declare
1423 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1424
1425 =cut
1426
1427 sub find_or_create {
1428   my $self     = shift;
1429   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1430   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1431   my $exists   = $self->find($hash, $attrs);
1432   return defined $exists ? $exists : $self->create($hash);
1433 }
1434
1435 =head2 update_or_create
1436
1437 =over 4
1438
1439 =item Arguments: \%col_values, { key => $unique_constraint }?
1440
1441 =item Return Value: $object
1442
1443 =back
1444
1445   $class->update_or_create({ col => $val, ... });
1446
1447 First, searches for an existing row matching one of the unique constraints
1448 (including the primary key) on the source of this resultset. If a row is
1449 found, updates it with the other given column values. Otherwise, creates a new
1450 row.
1451
1452 Takes an optional C<key> attribute to search on a specific unique constraint.
1453 For example:
1454
1455   # In your application
1456   my $cd = $schema->resultset('CD')->update_or_create(
1457     {
1458       artist => 'Massive Attack',
1459       title  => 'Mezzanine',
1460       year   => 1998,
1461     },
1462     { key => 'cd_artist_title' }
1463   );
1464
1465 If no C<key> is specified, it searches on all unique constraints defined on the
1466 source, including the primary key.
1467
1468 If the C<key> is specified as C<primary>, it searches only on the primary key.
1469
1470 See also L</find> and L</find_or_create>. For information on how to declare
1471 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1472
1473 =cut
1474
1475 sub update_or_create {
1476   my $self = shift;
1477   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1478   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
1479
1480   my $row = $self->find($cond);
1481   if (defined $row) {
1482     $row->update($cond);
1483     return $row;
1484   }
1485
1486   return $self->create($cond);
1487 }
1488
1489 =head2 get_cache
1490
1491 =over 4
1492
1493 =item Arguments: none
1494
1495 =item Return Value: \@cache_objects?
1496
1497 =back
1498
1499 Gets the contents of the cache for the resultset, if the cache is set.
1500
1501 =cut
1502
1503 sub get_cache {
1504   shift->{all_cache};
1505 }
1506
1507 =head2 set_cache
1508
1509 =over 4
1510
1511 =item Arguments: \@cache_objects
1512
1513 =item Return Value: \@cache_objects
1514
1515 =back
1516
1517 Sets the contents of the cache for the resultset. Expects an arrayref
1518 of objects of the same class as those produced by the resultset. Note that
1519 if the cache is set the resultset will return the cached objects rather
1520 than re-querying the database even if the cache attr is not set.
1521
1522 =cut
1523
1524 sub set_cache {
1525   my ( $self, $data ) = @_;
1526   $self->throw_exception("set_cache requires an arrayref")
1527       if defined($data) && (ref $data ne 'ARRAY');
1528   $self->{all_cache} = $data;
1529 }
1530
1531 =head2 clear_cache
1532
1533 =over 4
1534
1535 =item Arguments: none
1536
1537 =item Return Value: []
1538
1539 =back
1540
1541 Clears the cache for the resultset.
1542
1543 =cut
1544
1545 sub clear_cache {
1546   shift->set_cache(undef);
1547 }
1548
1549 =head2 related_resultset
1550
1551 =over 4
1552
1553 =item Arguments: $relationship_name
1554
1555 =item Return Value: $resultset
1556
1557 =back
1558
1559 Returns a related resultset for the supplied relationship name.
1560
1561   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1562
1563 =cut
1564
1565 sub related_resultset {
1566   my ($self, $rel) = @_;
1567
1568   $self->{related_resultsets} ||= {};
1569   return $self->{related_resultsets}{$rel} ||= do {
1570     my $rel_obj = $self->result_source->relationship_info($rel);
1571
1572     $self->throw_exception(
1573       "search_related: result source '" . $self->result_source->name .
1574         "' has no such relationship $rel")
1575       unless $rel_obj;
1576
1577     my ($from,$seen) = $self->_resolve_from;
1578     
1579     my $join_count = $self->{_parent_seen_join}{$rel};
1580     my $alias = $join_count ? join('_', $rel, $join_count+1) : $rel;
1581
1582     my $rs = $self->result_source->schema->resultset($rel_obj->{class})->search(
1583       undef, {
1584         select => undef,
1585         as => undef,
1586         alias => $alias,
1587         _parent_from => $from,
1588         _parent_seen_join => $seen,
1589         _parent_attrs => $self->{attrs},
1590     });
1591
1592     $rs;
1593   };
1594 }
1595
1596 =head2 throw_exception
1597
1598 See L<DBIx::Class::Schema/throw_exception> for details.
1599
1600 =cut
1601
1602 sub throw_exception {
1603   my $self=shift;
1604   $self->result_source->schema->throw_exception(@_);
1605 }
1606
1607 # XXX: FIXME: Attributes docs need clearing up
1608
1609 =head1 ATTRIBUTES
1610
1611 The resultset takes various attributes that modify its behavior. Here's an
1612 overview of them:
1613
1614 =head2 order_by
1615
1616 =over 4
1617
1618 =item Value: ($order_by | \@order_by)
1619
1620 =back
1621
1622 Which column(s) to order the results by. This is currently passed
1623 through directly to SQL, so you can give e.g. C<year DESC> for a
1624 descending order on the column `year'.
1625
1626 Please note that if you have quoting enabled (see
1627 L<DBIx::Class::Storage/quote_char>) you will need to do C<\'year DESC' > to
1628 specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
1629 so you will need to manually quote things as appropriate.)
1630
1631 =head2 columns
1632
1633 =over 4
1634
1635 =item Value: \@columns
1636
1637 =back
1638
1639 Shortcut to request a particular set of columns to be retrieved.  Adds
1640 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1641 from that, then auto-populates C<as> from C<select> as normal. (You may also
1642 use the C<cols> attribute, as in earlier versions of DBIC.)
1643
1644 =head2 include_columns
1645
1646 =over 4
1647
1648 =item Value: \@columns
1649
1650 =back
1651
1652 Shortcut to include additional columns in the returned results - for example
1653
1654   $schema->resultset('CD')->search(undef, {
1655     include_columns => ['artist.name'],
1656     join => ['artist']
1657   });
1658
1659 would return all CDs and include a 'name' column to the information
1660 passed to object inflation
1661
1662 =head2 select
1663
1664 =over 4
1665
1666 =item Value: \@select_columns
1667
1668 =back
1669
1670 Indicates which columns should be selected from the storage. You can use
1671 column names, or in the case of RDBMS back ends, function or stored procedure
1672 names:
1673
1674   $rs = $schema->resultset('Employee')->search(undef, {
1675     select => [
1676       'name',
1677       { count => 'employeeid' },
1678       { sum => 'salary' }
1679     ]
1680   });
1681
1682 When you use function/stored procedure names and do not supply an C<as>
1683 attribute, the column names returned are storage-dependent. E.g. MySQL would
1684 return a column named C<count(employeeid)> in the above example.
1685
1686 =head2 +select
1687
1688 =over 4
1689
1690 Indicates additional columns to be selected from storage.  Works the same as
1691 L<select> but adds columns to the selection.
1692
1693 =back
1694
1695 =head2 +as
1696
1697 =over 4
1698
1699 Indicates additional column names for those added via L<+select>.
1700
1701 =back
1702
1703 =head2 as
1704
1705 =over 4
1706
1707 =item Value: \@inflation_names
1708
1709 =back
1710
1711 Indicates column names for object inflation. This is used in conjunction with
1712 C<select>, usually when C<select> contains one or more function or stored
1713 procedure names:
1714
1715   $rs = $schema->resultset('Employee')->search(undef, {
1716     select => [
1717       'name',
1718       { count => 'employeeid' }
1719     ],
1720     as => ['name', 'employee_count'],
1721   });
1722
1723   my $employee = $rs->first(); # get the first Employee
1724
1725 If the object against which the search is performed already has an accessor
1726 matching a column name specified in C<as>, the value can be retrieved using
1727 the accessor as normal:
1728
1729   my $name = $employee->name();
1730
1731 If on the other hand an accessor does not exist in the object, you need to
1732 use C<get_column> instead:
1733
1734   my $employee_count = $employee->get_column('employee_count');
1735
1736 You can create your own accessors if required - see
1737 L<DBIx::Class::Manual::Cookbook> for details.
1738
1739 Please note: This will NOT insert an C<AS employee_count> into the SQL statement
1740 produced, it is used for internal access only. Thus attempting to use the accessor
1741 in an C<order_by> clause or similar will fail misrably.
1742
1743 =head2 join
1744
1745 =over 4
1746
1747 =item Value: ($rel_name | \@rel_names | \%rel_names)
1748
1749 =back
1750
1751 Contains a list of relationships that should be joined for this query.  For
1752 example:
1753
1754   # Get CDs by Nine Inch Nails
1755   my $rs = $schema->resultset('CD')->search(
1756     { 'artist.name' => 'Nine Inch Nails' },
1757     { join => 'artist' }
1758   );
1759
1760 Can also contain a hash reference to refer to the other relation's relations.
1761 For example:
1762
1763   package MyApp::Schema::Track;
1764   use base qw/DBIx::Class/;
1765   __PACKAGE__->table('track');
1766   __PACKAGE__->add_columns(qw/trackid cd position title/);
1767   __PACKAGE__->set_primary_key('trackid');
1768   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1769   1;
1770
1771   # In your application
1772   my $rs = $schema->resultset('Artist')->search(
1773     { 'track.title' => 'Teardrop' },
1774     {
1775       join     => { cd => 'track' },
1776       order_by => 'artist.name',
1777     }
1778   );
1779
1780 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1781 similarly for a third time). For e.g.
1782
1783   my $rs = $schema->resultset('Artist')->search({
1784     'cds.title'   => 'Down to Earth',
1785     'cds_2.title' => 'Popular',
1786   }, {
1787     join => [ qw/cds cds/ ],
1788   });
1789
1790 will return a set of all artists that have both a cd with title 'Down
1791 to Earth' and a cd with title 'Popular'.
1792
1793 If you want to fetch related objects from other tables as well, see C<prefetch>
1794 below.
1795
1796 =head2 prefetch
1797
1798 =over 4
1799
1800 =item Value: ($rel_name | \@rel_names | \%rel_names)
1801
1802 =back
1803
1804 Contains one or more relationships that should be fetched along with the main
1805 query (when they are accessed afterwards they will have already been
1806 "prefetched").  This is useful for when you know you will need the related
1807 objects, because it saves at least one query:
1808
1809   my $rs = $schema->resultset('Tag')->search(
1810     undef,
1811     {
1812       prefetch => {
1813         cd => 'artist'
1814       }
1815     }
1816   );
1817
1818 The initial search results in SQL like the following:
1819
1820   SELECT tag.*, cd.*, artist.* FROM tag
1821   JOIN cd ON tag.cd = cd.cdid
1822   JOIN artist ON cd.artist = artist.artistid
1823
1824 L<DBIx::Class> has no need to go back to the database when we access the
1825 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1826 case.
1827
1828 Simple prefetches will be joined automatically, so there is no need
1829 for a C<join> attribute in the above search. If you're prefetching to
1830 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1831 specify the join as well.
1832
1833 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1834 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1835 with an accessor type of 'single' or 'filter').
1836
1837 =head2 page
1838
1839 =over 4
1840
1841 =item Value: $page
1842
1843 =back
1844
1845 Makes the resultset paged and specifies the page to retrieve. Effectively
1846 identical to creating a non-pages resultset and then calling ->page($page)
1847 on it.
1848
1849 If L<rows> attribute is not specified it defualts to 10 rows per page.
1850
1851 =head2 rows
1852
1853 =over 4
1854
1855 =item Value: $rows
1856
1857 =back
1858
1859 Specifes the maximum number of rows for direct retrieval or the number of
1860 rows per page if the page attribute or method is used.
1861
1862 =head2 offset
1863
1864 =over 4
1865
1866 =item Value: $offset
1867
1868 =back
1869
1870 Specifies the (zero-based) row number for the  first row to be returned, or the
1871 of the first row of the first page if paging is used.
1872
1873 =head2 group_by
1874
1875 =over 4
1876
1877 =item Value: \@columns
1878
1879 =back
1880
1881 A arrayref of columns to group by. Can include columns of joined tables.
1882
1883   group_by => [qw/ column1 column2 ... /]
1884
1885 =head2 having
1886
1887 =over 4
1888
1889 =item Value: $condition
1890
1891 =back
1892
1893 HAVING is a select statement attribute that is applied between GROUP BY and
1894 ORDER BY. It is applied to the after the grouping calculations have been
1895 done.
1896
1897   having => { 'count(employee)' => { '>=', 100 } }
1898
1899 =head2 distinct
1900
1901 =over 4
1902
1903 =item Value: (0 | 1)
1904
1905 =back
1906
1907 Set to 1 to group by all columns.
1908
1909 =head2 where
1910
1911 =over 4
1912
1913 Adds to the WHERE clause.
1914
1915   # only return rows WHERE deleted IS NULL for all searches
1916   __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
1917
1918 Can be overridden by passing C<{ where => undef }> as an attribute
1919 to a resulset.
1920
1921 =back
1922
1923 =head2 cache
1924
1925 Set to 1 to cache search results. This prevents extra SQL queries if you
1926 revisit rows in your ResultSet:
1927
1928   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1929
1930   while( my $artist = $resultset->next ) {
1931     ... do stuff ...
1932   }
1933
1934   $rs->first; # without cache, this would issue a query
1935
1936 By default, searches are not cached.
1937
1938 For more examples of using these attributes, see
1939 L<DBIx::Class::Manual::Cookbook>.
1940
1941 =head2 from
1942
1943 =over 4
1944
1945 =item Value: \@from_clause
1946
1947 =back
1948
1949 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1950 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1951 clauses.
1952
1953 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1954
1955 C<join> will usually do what you need and it is strongly recommended that you
1956 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1957 And we really do mean "cannot", not just tried and failed. Attempting to use
1958 this because you're having problems with C<join> is like trying to use x86
1959 ASM because you've got a syntax error in your C. Trust us on this.
1960
1961 Now, if you're still really, really sure you need to use this (and if you're
1962 not 100% sure, ask the mailing list first), here's an explanation of how this
1963 works.
1964
1965 The syntax is as follows -
1966
1967   [
1968     { <alias1> => <table1> },
1969     [
1970       { <alias2> => <table2>, -join_type => 'inner|left|right' },
1971       [], # nested JOIN (optional)
1972       { <table1.column1> => <table2.column2>, ... (more conditions) },
1973     ],
1974     # More of the above [ ] may follow for additional joins
1975   ]
1976
1977   <table1> <alias1>
1978   JOIN
1979     <table2> <alias2>
1980     [JOIN ...]
1981   ON <table1.column1> = <table2.column2>
1982   <more joins may follow>
1983
1984 An easy way to follow the examples below is to remember the following:
1985
1986     Anything inside "[]" is a JOIN
1987     Anything inside "{}" is a condition for the enclosing JOIN
1988
1989 The following examples utilize a "person" table in a family tree application.
1990 In order to express parent->child relationships, this table is self-joined:
1991
1992     # Person->belongs_to('father' => 'Person');
1993     # Person->belongs_to('mother' => 'Person');
1994
1995 C<from> can be used to nest joins. Here we return all children with a father,
1996 then search against all mothers of those children:
1997
1998   $rs = $schema->resultset('Person')->search(
1999       undef,
2000       {
2001           alias => 'mother', # alias columns in accordance with "from"
2002           from => [
2003               { mother => 'person' },
2004               [
2005                   [
2006                       { child => 'person' },
2007                       [
2008                           { father => 'person' },
2009                           { 'father.person_id' => 'child.father_id' }
2010                       ]
2011                   ],
2012                   { 'mother.person_id' => 'child.mother_id' }
2013               ],
2014           ]
2015       },
2016   );
2017
2018   # Equivalent SQL:
2019   # SELECT mother.* FROM person mother
2020   # JOIN (
2021   #   person child
2022   #   JOIN person father
2023   #   ON ( father.person_id = child.father_id )
2024   # )
2025   # ON ( mother.person_id = child.mother_id )
2026
2027 The type of any join can be controlled manually. To search against only people
2028 with a father in the person table, we could explicitly use C<INNER JOIN>:
2029
2030     $rs = $schema->resultset('Person')->search(
2031         undef,
2032         {
2033             alias => 'child', # alias columns in accordance with "from"
2034             from => [
2035                 { child => 'person' },
2036                 [
2037                     { father => 'person', -join_type => 'inner' },
2038                     { 'father.id' => 'child.father_id' }
2039                 ],
2040             ]
2041         },
2042     );
2043
2044     # Equivalent SQL:
2045     # SELECT child.* FROM person child
2046     # INNER JOIN person father ON child.father_id = father.id
2047
2048 =cut
2049
2050 1;