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