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