0.06000 changes
[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 Data::Page;
10 use Storable;
11 use Scalar::Util qw/weaken/;
12
13 use base qw/DBIx::Class/;
14 __PACKAGE__->load_components(qw/AccessorGroup/);
15 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
16
17 =head1 NAME
18
19 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
20
21 =head1 SYNOPSIS
22
23   my $rs   = $schema->resultset('User')->search(registered => 1);
24   my @rows = $schema->resultset('CD')->search(year => 2005);
25
26 =head1 DESCRIPTION
27
28 The resultset is also known as an iterator. It is responsible for handling
29 queries that may return an arbitrary number of rows, e.g. via L</search>
30 or a C<has_many> relationship.
31
32 In the examples below, the following table classes are used:
33
34   package MyApp::Schema::Artist;
35   use base qw/DBIx::Class/;
36   __PACKAGE__->load_components(qw/Core/);
37   __PACKAGE__->table('artist');
38   __PACKAGE__->add_columns(qw/artistid name/);
39   __PACKAGE__->set_primary_key('artistid');
40   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
41   1;
42
43   package MyApp::Schema::CD;
44   use base qw/DBIx::Class/;
45   __PACKAGE__->load_components(qw/Core/);
46   __PACKAGE__->table('cd');
47   __PACKAGE__->add_columns(qw/cdid artist title year/);
48   __PACKAGE__->set_primary_key('cdid');
49   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
50   1;
51
52 =head1 METHODS
53
54 =head2 new 
55
56 =over 4
57
58 =item Arguments: $source, \%$attrs
59
60 =item Return Value: $rs
61
62 =back
63
64 The resultset constructor. Takes a source object (usually a
65 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
66 L</ATTRIBUTES> below).  Does not perform any queries -- these are
67 executed as needed by the other methods.
68
69 Generally you won't need to construct a resultset manually.  You'll
70 automatically get one from e.g. a L</search> called in scalar context:
71
72   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
73
74 IMPORTANT: If called on an object, proxies to new_result instead so
75
76   my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
77
78 will return a CD object, not a ResultSet.
79
80 =cut
81
82 sub new {
83   my $class = shift;
84   return $class->new_result(@_) if ref $class;
85   
86   my ($source, $attrs) = @_;
87   weaken $source;
88   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
89   #use Data::Dumper; warn Dumper($attrs);
90   my $alias = ($attrs->{alias} ||= 'me');
91   
92   $attrs->{columns} ||= delete $attrs->{cols} if $attrs->{cols};
93   delete $attrs->{as} if $attrs->{columns};
94   $attrs->{columns} ||= [ $source->columns ] unless $attrs->{select};
95   $attrs->{select} = [
96     map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}}
97   ] if $attrs->{columns};
98   $attrs->{as} ||= [
99     map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}}
100   ];
101   if (my $include = delete $attrs->{include_columns}) {
102     push(@{$attrs->{select}}, @$include);
103     push(@{$attrs->{as}}, map { m/([^.]+)$/; $1; } @$include);
104   }
105   #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
106
107   $attrs->{from} ||= [ { $alias => $source->from } ];
108   $attrs->{seen_join} ||= {};
109   my %seen;
110   if (my $join = delete $attrs->{join}) {
111     foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
112       if (ref $j eq 'HASH') {
113         $seen{$_} = 1 foreach keys %$j;
114       } else {
115         $seen{$j} = 1;
116       }
117     }
118     push(@{$attrs->{from}}, $source->resolve_join(
119       $join, $attrs->{alias}, $attrs->{seen_join})
120     );
121   }
122   
123   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
124   $attrs->{order_by} = [ $attrs->{order_by} ] if
125     $attrs->{order_by} and !ref($attrs->{order_by});
126   $attrs->{order_by} ||= [];
127
128   my $collapse = $attrs->{collapse} || {};
129   if (my $prefetch = delete $attrs->{prefetch}) {
130     my @pre_order;
131     foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
132       if ( ref $p eq 'HASH' ) {
133         foreach my $key (keys %$p) {
134           push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
135             unless $seen{$key};
136         }
137       } else {
138         push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
139             unless $seen{$p};
140       }
141       my @prefetch = $source->resolve_prefetch(
142            $p, $attrs->{alias}, {}, \@pre_order, $collapse);
143       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
144       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
145     }
146     push(@{$attrs->{order_by}}, @pre_order);
147   }
148   $attrs->{collapse} = $collapse;
149 #  use Data::Dumper; warn Dumper($collapse) if keys %{$collapse};
150
151   if ($attrs->{page}) {
152     $attrs->{rows} ||= 10;
153     $attrs->{offset} ||= 0;
154     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
155   }
156
157   bless {
158     result_source => $source,
159     result_class => $attrs->{result_class} || $source->result_class,
160     cond => $attrs->{where},
161     from => $attrs->{from},
162     collapse => $collapse,
163     count => undef,
164     page => delete $attrs->{page},
165     pager => undef,
166     attrs => $attrs
167   }, $class;
168 }
169
170 =head2 search
171
172 =over 4
173
174 =item Arguments: $cond, \%attrs?
175
176 =item Return Value: $resultset (scalar context), @row_objs (list context)
177
178 =back
179
180   my @cds    = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
181   my $new_rs = $cd_rs->search({ year => 2005 });
182
183   my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
184                  # year = 2005 OR year = 2004
185
186 If you need to pass in additional attributes but no additional condition,
187 call it as C<search(undef, \%attrs);>.
188
189   # "SELECT name, artistid FROM $artist_table"
190   my @all_artists = $schema->resultset('Artist')->search(undef, {
191     columns => [qw/name artistid/],
192   });
193
194 =cut
195
196 sub search {
197   my $self = shift;
198
199   my $rs;
200   if( @_ ) {
201     
202     my $attrs = { %{$self->{attrs}} };
203     my $having = delete $attrs->{having};
204     $attrs = { %$attrs, %{ pop(@_) } } if @_ > 1 and ref $_[$#_] eq 'HASH';
205
206     my $where = (@_
207                   ? ((@_ == 1 || ref $_[0] eq "HASH")
208                       ? shift
209                       : ((@_ % 2)
210                           ? $self->throw_exception(
211                               "Odd number of arguments to search")
212                           : {@_}))
213                   : undef());
214     if (defined $where) {
215       $attrs->{where} = (defined $attrs->{where}
216                 ? { '-and' =>
217                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
218                         $where, $attrs->{where} ] }
219                 : $where);
220     }
221
222     if (defined $having) {
223       $attrs->{having} = (defined $attrs->{having}
224                 ? { '-and' =>
225                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
226                         $having, $attrs->{having} ] }
227                 : $having);
228     }
229
230     $rs = (ref $self)->new($self->result_source, $attrs);
231   }
232   else {
233     $rs = $self;
234     $rs->reset;
235   }
236   return (wantarray ? $rs->all : $rs);
237 }
238
239 =head2 search_literal
240
241 =over 4
242
243 =item Arguments: $sql_fragment, @bind_values
244
245 =item Return Value: $resultset (scalar context), @row_objs (list context)
246
247 =back
248
249   my @cds   = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
250   my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
251
252 Pass a literal chunk of SQL to be added to the conditional part of the
253 resultset query.
254
255 =cut
256
257 sub search_literal {
258   my ($self, $cond, @vals) = @_;
259   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
260   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
261   return $self->search(\$cond, $attrs);
262 }
263
264 =head2 find
265
266 =over 4
267
268 =item Arguments: @values | \%cols, \%attrs?
269
270 =item Return Value: $row_object
271
272 =back
273
274 Finds a row based on its primary key or unique constraint. For example:
275
276   my $cd = $schema->resultset('CD')->find(5);
277
278 Also takes an optional C<key> attribute, to search by a specific key or unique
279 constraint. For example:
280
281   my $cd = $schema->resultset('CD')->find(
282     {
283       artist => 'Massive Attack',
284       title  => 'Mezzanine',
285     },
286     { key => 'artist_title' }
287   );
288
289 See also L</find_or_create> and L</update_or_create>.
290
291 =cut
292
293 sub find {
294   my ($self, @vals) = @_;
295   my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
296
297   my @cols = $self->result_source->primary_columns;
298   if (exists $attrs->{key}) {
299     my %uniq = $self->result_source->unique_constraints;
300     $self->throw_exception(
301       "Unknown key $attrs->{key} on '" . $self->result_source->name . "'"
302     ) unless exists $uniq{$attrs->{key}};
303     @cols = @{ $uniq{$attrs->{key}} };
304   }
305   #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
306   $self->throw_exception(
307     "Can't find unless a primary key or unique constraint is defined"
308   ) unless @cols;
309
310   my $query;
311   if (ref $vals[0] eq 'HASH') {
312     $query = { %{$vals[0]} };
313   } elsif (@cols == @vals) {
314     $query = {};
315     @{$query}{@cols} = @vals;
316   } else {
317     $query = {@vals};
318   }
319   foreach my $key (grep { ! m/\./ } keys %$query) {
320     $query->{"$self->{attrs}{alias}.$key"} = delete $query->{$key};
321   }
322   #warn Dumper($query);
323   
324   if (keys %$attrs) {
325       my $rs = $self->search($query,$attrs);
326       return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
327   } else {
328       return keys %{$self->{collapse}} ?
329         $self->search($query)->next :
330         $self->single($query);
331   }
332 }
333
334 =head2 search_related
335
336 =over 4
337
338 =item Arguments: $cond, \%attrs?
339
340 =item Return Value: $new_resultset
341
342 =back
343
344   $new_rs = $cd_rs->search_related('artist', {
345     name => 'Emo-R-Us',
346   });
347
348 Search the specified relationship, optionally specify a condition and
349 attributes for matching records. See L</ATTRIBUTES> for more information.
350
351 =cut
352
353 sub search_related {
354   return shift->related_resultset(shift)->search(@_);
355 }
356
357 =head2 cursor
358
359 =over 4
360
361 =item Arguments: none
362
363 =item Return Value: $cursor
364
365 =back
366
367 Returns a storage-driven cursor to the given resultset. See
368 L<DBIx::Class::Cursor> for more information.
369
370 =cut
371
372 sub cursor {
373   my ($self) = @_;
374   my $attrs = { %{$self->{attrs}} };
375   return $self->{cursor}
376     ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
377           $attrs->{where},$attrs);
378 }
379
380 =head2 single
381
382 =over 4
383
384 =item Arguments: $cond?
385
386 =item Return Value: $row_object?
387
388 =back
389
390   my $cd = $schema->resultset('CD')->single({ year => 2001 });
391
392 Inflates the first result without creating a cursor if the resultset has
393 any records in it; if not returns nothing. Used by find() as an optimisation.
394
395 =cut
396
397 sub single {
398   my ($self, $where) = @_;
399   my $attrs = { %{$self->{attrs}} };
400   if ($where) {
401     if (defined $attrs->{where}) {
402       $attrs->{where} = {
403         '-and' => 
404             [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
405                $where, delete $attrs->{where} ]
406       };
407     } else {
408       $attrs->{where} = $where;
409     }
410   }
411   my @data = $self->result_source->storage->select_single(
412           $self->{from}, $attrs->{select},
413           $attrs->{where},$attrs);
414   return (@data ? $self->_construct_object(@data) : ());
415 }
416
417
418 =head2 search_like
419
420 =over 4
421
422 =item Arguments: $cond, \%attrs?
423
424 =item Return Value: $resultset (scalar context), @row_objs (list context)
425
426 =back
427
428   # WHERE title LIKE '%blue%'
429   $cd_rs = $rs->search_like({ title => '%blue%'});
430
431 Perform a search, but use C<LIKE> instead of C<=> as the condition. Note
432 that this is simply a convenience method. You most likely want to use
433 L</search> with specific operators.
434
435 For more information, see L<DBIx::Class::Manual::Cookbook>.
436
437 =cut
438
439 sub search_like {
440   my $class = shift;
441   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
442   my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
443   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
444   return $class->search($query, { %$attrs });
445 }
446
447 =head2 slice
448
449 =over 4
450
451 =item Arguments: $first, $last
452
453 =item Return Value: $resultset (scalar context), @row_objs (list context)
454
455 =back
456
457 Returns a resultset or object list representing a subset of elements from the
458 resultset slice is called on.  Indexes are from 0 - i.e. to get the first
459 three records, call
460
461   my ($one, $two, $three) = $rs->slice(0, 2);
462
463 =cut
464
465 sub slice {
466   my ($self, $min, $max) = @_;
467   my $attrs = { %{ $self->{attrs} || {} } };
468   $attrs->{offset} ||= 0;
469   $attrs->{offset} += $min;
470   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
471   my $slice = (ref $self)->new($self->result_source, $attrs);
472   return (wantarray ? $slice->all : $slice);
473 }
474
475 =head2 next
476
477 =over 4
478
479 =item Arguments: none
480
481 =item Return Value: $result?
482
483 =back
484
485 Returns the next element in the resultset (C<undef> is there is none).
486
487 Can be used to efficiently iterate over records in the resultset:
488
489   my $rs = $schema->resultset('CD')->search;
490   while (my $cd = $rs->next) {
491     print $cd->title;
492   }
493
494 =cut
495
496 sub next {
497   my ($self) = @_;
498   if (@{$self->{all_cache} || []}) {
499     $self->{all_cache_position} ||= 0;
500     return $self->{all_cache}->[$self->{all_cache_position}++];
501   }
502   if ($self->{attrs}{cache}) {
503     $self->{all_cache_position} = 1;
504     return ($self->all)[0];
505   }
506   my @row = (exists $self->{stashed_row} ?
507                @{delete $self->{stashed_row}} :
508                $self->cursor->next
509   );
510 #  warn Dumper(\@row); use Data::Dumper;
511   return unless (@row);
512   return $self->_construct_object(@row);
513 }
514
515 sub _construct_object {
516   my ($self, @row) = @_;
517   my @as = @{ $self->{attrs}{as} };
518   
519   my $info = $self->_collapse_result(\@as, \@row);
520   
521   my $new = $self->result_class->inflate_result($self->result_source, @$info);
522   
523   $new = $self->{attrs}{record_filter}->($new)
524     if exists $self->{attrs}{record_filter};
525   return $new;
526 }
527
528 sub _collapse_result {
529   my ($self, $as, $row, $prefix) = @_;
530
531   my %const;
532
533   my @copy = @$row;
534   foreach my $this_as (@$as) {
535     my $val = shift @copy;
536     if (defined $prefix) {
537       if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
538         my $remain = $1;
539         $remain =~ /^(?:(.*)\.)?([^.]+)$/;
540         $const{$1||''}{$2} = $val;
541       }
542     } else {
543       $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
544       $const{$1||''}{$2} = $val;
545     }
546   }
547
548   my $info = [ {}, {} ];
549   foreach my $key (keys %const) {
550     if (length $key) {
551       my $target = $info;
552       my @parts = split(/\./, $key);
553       foreach my $p (@parts) {
554         $target = $target->[1]->{$p} ||= [];
555       }
556       $target->[0] = $const{$key};
557     } else {
558       $info->[0] = $const{$key};
559     }
560   }
561
562   my @collapse;
563   if (defined $prefix) {
564     @collapse = map {
565         m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
566     } keys %{$self->{collapse}}
567   } else {
568     @collapse = keys %{$self->{collapse}};
569   };
570
571   if (@collapse) {
572     my ($c) = sort { length $a <=> length $b } @collapse;
573     my $target = $info;
574     foreach my $p (split(/\./, $c)) {
575       $target = $target->[1]->{$p} ||= [];
576     }
577     my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
578     my @co_key = @{$self->{collapse}{$c_prefix}};
579     my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
580     my $tree = $self->_collapse_result($as, $row, $c_prefix);
581     my (@final, @raw);
582     while ( !(grep {
583                 !defined($tree->[0]->{$_}) ||
584                 $co_check{$_} ne $tree->[0]->{$_}
585               } @co_key) ) {
586       push(@final, $tree);
587       last unless (@raw = $self->cursor->next);
588       $row = $self->{stashed_row} = \@raw;
589       $tree = $self->_collapse_result($as, $row, $c_prefix);
590       #warn Data::Dumper::Dumper($tree, $row);
591     }
592     @$target = @final;
593   }
594
595   return $info;
596 }
597
598 =head2 result_source
599
600 =over 4
601
602 =item Arguments: $result_source?
603
604 =item Return Value: $result_source
605
606 =back
607
608 An accessor for the primary ResultSource object from which this ResultSet
609 is derived.
610
611 =cut
612
613
614 =head2 count
615
616 =over 4
617
618 =item Arguments: $cond, \%attrs??
619
620 =item Return Value: $count
621
622 =back
623
624 Performs an SQL C<COUNT> with the same query as the resultset was built
625 with to find the number of elements. If passed arguments, does a search
626 on the resultset and counts the results of that.
627
628 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
629 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
630 not support C<DISTINCT> with multiple columns. If you are using such a
631 database, you should only use columns from the main table in your C<group_by>
632 clause.
633
634 =cut
635
636 sub count {
637   my $self = shift;
638   return $self->search(@_)->count if @_ and defined $_[0];
639   return scalar @{ $self->get_cache } if @{ $self->get_cache };
640
641   my $count = $self->_count;
642   return 0 unless $count;
643
644   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
645   $count = $self->{attrs}{rows} if
646     $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
647   return $count;
648 }
649
650 sub _count { # Separated out so pager can get the full count
651   my $self = shift;
652   my $select = { count => '*' };
653   my $attrs = { %{ $self->{attrs} } };
654   if (my $group_by = delete $attrs->{group_by}) {
655     delete $attrs->{having};
656     my @distinct = (ref $group_by ?  @$group_by : ($group_by));
657     # todo: try CONCAT for multi-column pk
658     my @pk = $self->result_source->primary_columns;
659     if (@pk == 1) {
660       foreach my $column (@distinct) {
661         if ($column =~ qr/^(?:\Q$attrs->{alias}.\E)?$pk[0]$/) {
662           @distinct = ($column);
663           last;
664         }
665       } 
666     }
667
668     $select = { count => { distinct => \@distinct } };
669     #use Data::Dumper; die Dumper $select;
670   }
671
672   $attrs->{select} = $select;
673   $attrs->{as} = [qw/count/];
674
675   # offset, order by and page are not needed to count. record_filter is cdbi
676   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
677         
678   my ($count) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
679   return $count;
680 }
681
682 =head2 count_literal
683
684 =over 4
685
686 =item Arguments: $sql_fragment, @bind_values
687
688 =item Return Value: $count
689
690 =back
691
692 Counts the results in a literal query. Equivalent to calling L</search_literal>
693 with the passed arguments, then L</count>.
694
695 =cut
696
697 sub count_literal { shift->search_literal(@_)->count; }
698
699 =head2 all
700
701 =over 4
702
703 =item Arguments: none
704
705 =item Return Value: @objects
706
707 =back
708
709 Returns all elements in the resultset. Called implicitly if the resultset
710 is returned in list context.
711
712 =cut
713
714 sub all {
715   my ($self) = @_;
716   return @{ $self->get_cache } if @{ $self->get_cache };
717
718   my @obj;
719
720   if (keys %{$self->{collapse}}) {
721       # Using $self->cursor->all is really just an optimisation.
722       # If we're collapsing has_many prefetches it probably makes
723       # very little difference, and this is cleaner than hacking
724       # _construct_object to survive the approach
725     $self->cursor->reset;
726     my @row = $self->cursor->next;
727     while (@row) {
728       push(@obj, $self->_construct_object(@row));
729       @row = (exists $self->{stashed_row}
730                ? @{delete $self->{stashed_row}}
731                : $self->cursor->next);
732     }
733   } else {
734     @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
735   }
736
737   $self->set_cache(\@obj) if $self->{attrs}{cache};
738   return @obj;
739 }
740
741 =head2 reset
742
743 =over 4
744
745 =item Arguments: none
746
747 =item Return Value: $self
748
749 =back
750
751 Resets the resultset's cursor, so you can iterate through the elements again.
752
753 =cut
754
755 sub reset {
756   my ($self) = @_;
757   $self->{all_cache_position} = 0;
758   $self->cursor->reset;
759   return $self;
760 }
761
762 =head2 first
763
764 =over 4
765
766 =item Arguments: none
767
768 =item Return Value: $object?
769
770 =back
771
772 Resets the resultset and returns an object for the first result (if the
773 resultset contains anything).
774
775 =cut
776
777 sub first {
778   return $_[0]->reset->next;
779 }
780
781 =head2 update
782
783 =over 4
784
785 =item Arguments: \%values
786
787 =item Return Value: $storage_rv
788
789 =back
790
791 Sets the specified columns in the resultset to the supplied values in a
792 single query. Return value will be true if the update succeeded or false
793 if no records were updated; exact type of success value is storage-dependent.
794
795 =cut
796
797 sub update {
798   my ($self, $values) = @_;
799   $self->throw_exception("Values for update must be a hash")
800     unless ref $values eq 'HASH';
801   return $self->result_source->storage->update(
802     $self->result_source->from, $values, $self->{cond}
803   );
804 }
805
806 =head2 update_all
807
808 =over 4
809
810 =item Arguments: \%values
811
812 =item Return Value: 1
813
814 =back
815
816 Fetches all objects and updates them one at a time.  Note that C<update_all>
817 will run cascade triggers while L</update> will not.
818
819 =cut
820
821 sub update_all {
822   my ($self, $values) = @_;
823   $self->throw_exception("Values for update must be a hash")
824     unless ref $values eq 'HASH';
825   foreach my $obj ($self->all) {
826     $obj->set_columns($values)->update;
827   }
828   return 1;
829 }
830
831 =head2 delete
832
833 =over 4
834
835 =item Arguments: none
836
837 =item Return Value: 1
838
839 =back
840
841 Deletes the contents of the resultset from its result source. Note that this
842 will not run cascade triggers. See L</delete_all> if you need triggers to run.
843
844 =cut
845
846 sub delete {
847   my ($self) = @_;
848   my $del = {};
849
850   if (!ref($self->{cond})) {
851
852     # No-op. No condition, we're deleting everything
853
854   } elsif (ref $self->{cond} eq 'ARRAY') {
855
856     $del = [ map { my %hash;
857       foreach my $key (keys %{$_}) {
858         $key =~ /([^.]+)$/;
859         $hash{$1} = $_->{$key};
860       }; \%hash; } @{$self->{cond}} ];
861
862   } elsif (ref $self->{cond} eq 'HASH') {
863
864     if ((keys %{$self->{cond}})[0] eq '-and') {
865
866       $del->{-and} = [ map { my %hash;
867         foreach my $key (keys %{$_}) {
868           $key =~ /([^.]+)$/;
869           $hash{$1} = $_->{$key};
870         }; \%hash; } @{$self->{cond}{-and}} ];
871
872     } else {
873
874       foreach my $key (keys %{$self->{cond}}) {
875         $key =~ /([^.]+)$/;
876         $del->{$1} = $self->{cond}{$key};
877       }
878     }
879
880   } else {
881     $self->throw_exception(
882       "Can't delete on resultset with condition unless hash or array"
883     );
884   }
885
886   $self->result_source->storage->delete($self->result_source->from, $del);
887   return 1;
888 }
889
890 =head2 delete_all
891
892 =over 4
893
894 =item Arguments: none
895
896 =item Return Value: 1
897
898 =back
899
900 Fetches all objects and deletes them one at a time.  Note that C<delete_all>
901 will run cascade triggers while L</delete> will not.
902
903 =cut
904
905 sub delete_all {
906   my ($self) = @_;
907   $_->delete for $self->all;
908   return 1;
909 }
910
911 =head2 pager
912
913 =over 4
914
915 =item Arguments: none
916
917 =item Return Value: $pager
918
919 =back
920
921 Return Value a L<Data::Page> object for the current resultset. Only makes
922 sense for queries with a C<page> attribute.
923
924 =cut
925
926 sub pager {
927   my ($self) = @_;
928   my $attrs = $self->{attrs};
929   $self->throw_exception("Can't create pager for non-paged rs")
930     unless $self->{page};
931   $attrs->{rows} ||= 10;
932   return $self->{pager} ||= Data::Page->new(
933     $self->_count, $attrs->{rows}, $self->{page});
934 }
935
936 =head2 page
937
938 =over 4
939
940 =item Arguments: $page_number
941
942 =item Return Value: $rs
943
944 =back
945
946 Returns a resultset for the $page_number page of the resultset on which page
947 is called, where each page contains a number of rows equal to the 'rows'
948 attribute set on the resultset, or 10 by default
949
950 =cut
951
952 sub page {
953   my ($self, $page) = @_;
954   my $attrs = { %{$self->{attrs}} };
955   $attrs->{page} = $page;
956   return (ref $self)->new($self->result_source, $attrs);
957 }
958
959 =head2 new_result
960
961 =over 4
962
963 =item Arguments: \%vals
964
965 =item Return Value: $object
966
967 =back
968
969 Creates an object in the resultset's result class and returns it.
970
971 =cut
972
973 sub new_result {
974   my ($self, $values) = @_;
975   $self->throw_exception( "new_result needs a hash" )
976     unless (ref $values eq 'HASH');
977   $self->throw_exception(
978     "Can't abstract implicit construct, condition not a hash"
979   ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
980   my %new = %$values;
981   my $alias = $self->{attrs}{alias};
982   foreach my $key (keys %{$self->{cond}||{}}) {
983     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:\Q${alias}.\E)?([^.]+)$/);
984   }
985   my $obj = $self->result_class->new(\%new);
986   $obj->result_source($self->result_source) if $obj->can('result_source');
987   return $obj;
988 }
989
990 =head2 create
991
992 =over 4
993
994 =item Arguments: \%vals
995
996 =item Return Value: $object
997
998 =back
999
1000 Inserts a record into the resultset and returns the object representing it.
1001
1002 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1003
1004 =cut
1005
1006 sub create {
1007   my ($self, $attrs) = @_;
1008   $self->throw_exception( "create needs a hashref" )
1009     unless ref $attrs eq 'HASH';
1010   return $self->new_result($attrs)->insert;
1011 }
1012
1013 =head2 find_or_create
1014
1015 =over 4
1016
1017 =item Arguments: \%vals, \%attrs?
1018
1019 =item Return Value: $object
1020
1021 =back
1022
1023   $class->find_or_create({ key => $val, ... });
1024
1025 Searches for a record matching the search condition; if it doesn't find one,
1026 creates one and returns that instead.
1027
1028   my $cd = $schema->resultset('CD')->find_or_create({
1029     cdid   => 5,
1030     artist => 'Massive Attack',
1031     title  => 'Mezzanine',
1032     year   => 2005,
1033   });
1034
1035 Also takes an optional C<key> attribute, to search by a specific key or unique
1036 constraint. For example:
1037
1038   my $cd = $schema->resultset('CD')->find_or_create(
1039     {
1040       artist => 'Massive Attack',
1041       title  => 'Mezzanine',
1042     },
1043     { key => 'artist_title' }
1044   );
1045
1046 See also L</find> and L</update_or_create>.
1047
1048 =cut
1049
1050 sub find_or_create {
1051   my $self     = shift;
1052   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1053   my $hash     = ref $_[0] eq 'HASH' ? shift : {@_};
1054   my $exists   = $self->find($hash, $attrs);
1055   return defined $exists ? $exists : $self->create($hash);
1056 }
1057
1058 =head2 update_or_create
1059
1060 =over 4
1061
1062 =item Arguments: \%col_values, { key => $unique_constraint }?
1063
1064 =item Return Value: $object
1065
1066 =back
1067
1068   $class->update_or_create({ col => $val, ... });
1069
1070 First, search for an existing row matching one of the unique constraints
1071 (including the primary key) on the source of this resultset.  If a row is
1072 found, update it with the other given column values.  Otherwise, create a new
1073 row.
1074
1075 Takes an optional C<key> attribute to search on a specific unique constraint.
1076 For example:
1077
1078   # In your application
1079   my $cd = $schema->resultset('CD')->update_or_create(
1080     {
1081       artist => 'Massive Attack',
1082       title  => 'Mezzanine',
1083       year   => 1998,
1084     },
1085     { key => 'artist_title' }
1086   );
1087
1088 If no C<key> is specified, it searches on all unique constraints defined on the
1089 source, including the primary key.
1090
1091 If the C<key> is specified as C<primary>, search only on the primary key.
1092
1093 See also L</find> and L</find_or_create>.
1094
1095 =cut
1096
1097 sub update_or_create {
1098   my $self = shift;
1099   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1100   my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1101
1102   my %unique_constraints = $self->result_source->unique_constraints;
1103   my @constraint_names   = (exists $attrs->{key}
1104                             ? ($attrs->{key})
1105                             : keys %unique_constraints);
1106
1107   my @unique_hashes;
1108   foreach my $name (@constraint_names) {
1109     my @unique_cols = @{ $unique_constraints{$name} };
1110     my %unique_hash =
1111       map  { $_ => $hash->{$_} }
1112       grep { exists $hash->{$_} }
1113       @unique_cols;
1114
1115     push @unique_hashes, \%unique_hash
1116       if (scalar keys %unique_hash == scalar @unique_cols);
1117   }
1118
1119   if (@unique_hashes) {
1120     my $row = $self->single(\@unique_hashes);
1121     if (defined $row) {
1122       $row->set_columns($hash);
1123       $row->update;
1124       return $row;
1125     }
1126   }
1127
1128   return $self->create($hash);
1129 }
1130
1131 =head2 get_cache
1132
1133 =over 4
1134
1135 =item Arguments: none
1136
1137 =item Return Value: \@cache_objects?
1138
1139 =back
1140
1141 Gets the contents of the cache for the resultset if the cache is set
1142
1143 =cut
1144
1145 sub get_cache {
1146   shift->{all_cache} || [];
1147 }
1148
1149 =head2 set_cache
1150
1151 =over 4
1152
1153 =item Arguments: \@cache_objects
1154
1155 =item Return Value: \@cache_objects
1156
1157 =back
1158
1159 Sets the contents of the cache for the resultset. Expects an arrayref
1160 of objects of the same class as those produced by the resultset. Note that
1161 if the cache is set the resultset will return the cached objects rather
1162 than re-querying the database even if the cache attr is not set.
1163
1164 =cut
1165
1166 sub set_cache {
1167   my ( $self, $data ) = @_;
1168   $self->throw_exception("set_cache requires an arrayref")
1169     if ref $data ne 'ARRAY';
1170   my $result_class = $self->result_class;
1171   foreach( @$data ) {
1172     $self->throw_exception(
1173       "cannot cache object of type '$_', expected '$result_class'"
1174     ) if ref $_ ne $result_class;
1175   }
1176   $self->{all_cache} = $data;
1177 }
1178
1179 =head2 clear_cache
1180
1181 =over 4
1182
1183 =item Arguments: none
1184
1185 =item Return Value: []
1186
1187 =back
1188
1189 Clears the cache for the resultset.
1190
1191 =cut
1192
1193 sub clear_cache {
1194   shift->set_cache([]);
1195 }
1196
1197 =head2 related_resultset
1198
1199 =over 4
1200
1201 =item Arguments: $relationship_name
1202
1203 =item Return Value: $resultset
1204
1205 =back
1206
1207 Returns a related resultset for the supplied relationship name.
1208
1209   $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1210
1211 =cut
1212
1213 sub related_resultset {
1214   my ( $self, $rel ) = @_;
1215   $self->{related_resultsets} ||= {};
1216   return $self->{related_resultsets}{$rel} ||= do {
1217       #warn "fetching related resultset for rel '$rel'";
1218       my $rel_obj = $self->result_source->relationship_info($rel);
1219       $self->throw_exception(
1220         "search_related: result source '" . $self->result_source->name .
1221         "' has no such relationship ${rel}")
1222         unless $rel_obj; #die Dumper $self->{attrs};
1223
1224       my $rs = $self->search(undef, { join => $rel });
1225       my $alias = defined $rs->{attrs}{seen_join}{$rel}
1226                     && $rs->{attrs}{seen_join}{$rel} > 1
1227                   ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
1228                   : $rel;
1229
1230       $self->result_source->schema->resultset($rel_obj->{class}
1231            )->search( undef,
1232              { %{$rs->{attrs}},
1233                alias => $alias,
1234                select => undef,
1235                as => undef }
1236            );
1237   };
1238 }
1239
1240 =head2 throw_exception
1241
1242 See L<DBIx::Class::Schema/throw_exception> for details.
1243
1244 =cut
1245
1246 sub throw_exception {
1247   my $self=shift;
1248   $self->result_source->schema->throw_exception(@_);
1249 }
1250
1251 # XXX: FIXME: Attributes docs need clearing up
1252
1253 =head1 ATTRIBUTES
1254
1255 The resultset takes various attributes that modify its behavior. Here's an
1256 overview of them:
1257
1258 =head2 order_by
1259
1260 =over 4
1261
1262 =item Value: ($order_by | \@order_by)
1263
1264 =back
1265
1266 Which column(s) to order the results by. This is currently passed
1267 through directly to SQL, so you can give e.g. C<year DESC> for a
1268 descending order on the column `year'.
1269
1270 =head2 columns
1271
1272 =over 4
1273
1274 =item Value: \@columns
1275
1276 =back
1277
1278 Shortcut to request a particular set of columns to be retrieved.  Adds
1279 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1280 from that, then auto-populates C<as> from C<select> as normal. (You may also
1281 use the C<cols> attribute, as in earlier versions of DBIC.)
1282
1283 =head2 include_columns
1284
1285 =over 4
1286
1287 =item Value: \@columns
1288
1289 =back
1290
1291 Shortcut to include additional columns in the returned results - for example
1292
1293   $schema->resultset('CD')->search(undef, {
1294     include_columns => ['artist.name'],
1295     join => ['artist']
1296   });
1297
1298 would return all CDs and include a 'name' column to the information
1299 passed to object inflation
1300
1301 =head2 select
1302
1303 =over 4
1304
1305 =item Value: \@select_columns
1306
1307 =back
1308
1309 Indicates which columns should be selected from the storage. You can use
1310 column names, or in the case of RDBMS back ends, function or stored procedure
1311 names:
1312
1313   $rs = $schema->resultset('Employee')->search(undef, {
1314     select => [
1315       'name',
1316       { count => 'employeeid' },
1317       { sum => 'salary' }
1318     ]
1319   });
1320
1321 When you use function/stored procedure names and do not supply an C<as>
1322 attribute, the column names returned are storage-dependent. E.g. MySQL would
1323 return a column named C<count(employeeid)> in the above example.
1324
1325 =head2 as
1326
1327 =over 4
1328
1329 =item Value: \@inflation_names
1330
1331 =back
1332
1333 Indicates column names for object inflation. This is used in conjunction with
1334 C<select>, usually when C<select> contains one or more function or stored
1335 procedure names:
1336
1337   $rs = $schema->resultset('Employee')->search(undef, {
1338     select => [
1339       'name',
1340       { count => 'employeeid' }
1341     ],
1342     as => ['name', 'employee_count'],
1343   });
1344
1345   my $employee = $rs->first(); # get the first Employee
1346
1347 If the object against which the search is performed already has an accessor
1348 matching a column name specified in C<as>, the value can be retrieved using
1349 the accessor as normal:
1350
1351   my $name = $employee->name();
1352
1353 If on the other hand an accessor does not exist in the object, you need to
1354 use C<get_column> instead:
1355
1356   my $employee_count = $employee->get_column('employee_count');
1357
1358 You can create your own accessors if required - see
1359 L<DBIx::Class::Manual::Cookbook> for details.
1360
1361 =head2 join
1362
1363 =over 4
1364
1365 =item Value: ($rel_name | \@rel_names | \%rel_names)
1366
1367 =back
1368
1369 Contains a list of relationships that should be joined for this query.  For
1370 example:
1371
1372   # Get CDs by Nine Inch Nails
1373   my $rs = $schema->resultset('CD')->search(
1374     { 'artist.name' => 'Nine Inch Nails' },
1375     { join => 'artist' }
1376   );
1377
1378 Can also contain a hash reference to refer to the other relation's relations.
1379 For example:
1380
1381   package MyApp::Schema::Track;
1382   use base qw/DBIx::Class/;
1383   __PACKAGE__->table('track');
1384   __PACKAGE__->add_columns(qw/trackid cd position title/);
1385   __PACKAGE__->set_primary_key('trackid');
1386   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1387   1;
1388
1389   # In your application
1390   my $rs = $schema->resultset('Artist')->search(
1391     { 'track.title' => 'Teardrop' },
1392     {
1393       join     => { cd => 'track' },
1394       order_by => 'artist.name',
1395     }
1396   );
1397
1398 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1399 similarly for a third time). For e.g.
1400
1401   my $rs = $schema->resultset('Artist')->search({
1402     'cds.title'   => 'Down to Earth',
1403     'cds_2.title' => 'Popular',
1404   }, {
1405     join => [ qw/cds cds/ ],
1406   });
1407
1408 will return a set of all artists that have both a cd with title 'Down
1409 to Earth' and a cd with title 'Popular'.
1410
1411 If you want to fetch related objects from other tables as well, see C<prefetch>
1412 below.
1413
1414 =head2 prefetch
1415
1416 =over 4
1417
1418 =item Value: ($rel_name | \@rel_names | \%rel_names)
1419
1420 =back
1421
1422 Contains one or more relationships that should be fetched along with the main 
1423 query (when they are accessed afterwards they will have already been
1424 "prefetched").  This is useful for when you know you will need the related
1425 objects, because it saves at least one query:
1426
1427   my $rs = $schema->resultset('Tag')->search(
1428     undef,
1429     {
1430       prefetch => {
1431         cd => 'artist'
1432       }
1433     }
1434   );
1435
1436 The initial search results in SQL like the following:
1437
1438   SELECT tag.*, cd.*, artist.* FROM tag
1439   JOIN cd ON tag.cd = cd.cdid
1440   JOIN artist ON cd.artist = artist.artistid
1441
1442 L<DBIx::Class> has no need to go back to the database when we access the
1443 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1444 case.
1445
1446 Simple prefetches will be joined automatically, so there is no need
1447 for a C<join> attribute in the above search. If you're prefetching to
1448 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1449 specify the join as well.
1450
1451 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1452 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1453 with an accessor type of 'single' or 'filter').
1454
1455 =head2 from
1456
1457 =over 4
1458
1459 =item Value: \@from_clause
1460
1461 =back
1462
1463 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1464 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1465 clauses.
1466
1467 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
1468 C<join> will usually do what you need and it is strongly recommended that you
1469 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1470
1471 In simple terms, C<from> works as follows:
1472
1473     [
1474         { <alias> => <table>, -join-type => 'inner|left|right' }
1475         [] # nested JOIN (optional)
1476         { <table.column> => <foreign_table.foreign_key> }
1477     ]
1478
1479     JOIN
1480         <alias> <table>
1481         [JOIN ...]
1482     ON <table.column> = <foreign_table.foreign_key>
1483
1484 An easy way to follow the examples below is to remember the following:
1485
1486     Anything inside "[]" is a JOIN
1487     Anything inside "{}" is a condition for the enclosing JOIN
1488
1489 The following examples utilize a "person" table in a family tree application.
1490 In order to express parent->child relationships, this table is self-joined:
1491
1492     # Person->belongs_to('father' => 'Person');
1493     # Person->belongs_to('mother' => 'Person');
1494
1495 C<from> can be used to nest joins. Here we return all children with a father,
1496 then search against all mothers of those children:
1497
1498   $rs = $schema->resultset('Person')->search(
1499       undef,
1500       {
1501           alias => 'mother', # alias columns in accordance with "from"
1502           from => [
1503               { mother => 'person' },
1504               [
1505                   [
1506                       { child => 'person' },
1507                       [
1508                           { father => 'person' },
1509                           { 'father.person_id' => 'child.father_id' }
1510                       ]
1511                   ],
1512                   { 'mother.person_id' => 'child.mother_id' }
1513               ],
1514           ]
1515       },
1516   );
1517
1518   # Equivalent SQL:
1519   # SELECT mother.* FROM person mother
1520   # JOIN (
1521   #   person child
1522   #   JOIN person father
1523   #   ON ( father.person_id = child.father_id )
1524   # )
1525   # ON ( mother.person_id = child.mother_id )
1526
1527 The type of any join can be controlled manually. To search against only people
1528 with a father in the person table, we could explicitly use C<INNER JOIN>:
1529
1530     $rs = $schema->resultset('Person')->search(
1531         undef,
1532         {
1533             alias => 'child', # alias columns in accordance with "from"
1534             from => [
1535                 { child => 'person' },
1536                 [
1537                     { father => 'person', -join-type => 'inner' },
1538                     { 'father.id' => 'child.father_id' }
1539                 ],
1540             ]
1541         },
1542     );
1543
1544     # Equivalent SQL:
1545     # SELECT child.* FROM person child
1546     # INNER JOIN person father ON child.father_id = father.id
1547
1548 =head2 page
1549
1550 =over 4
1551
1552 =item Value: $page
1553
1554 =back
1555
1556 Makes the resultset paged and specifies the page to retrieve. Effectively
1557 identical to creating a non-pages resultset and then calling ->page($page)
1558 on it.
1559
1560 =head2 rows
1561
1562 =over 4
1563
1564 =item Value: $rows
1565
1566 =back
1567
1568 Specifes the maximum number of rows for direct retrieval or the number of
1569 rows per page if the page attribute or method is used.
1570
1571 =head2 group_by
1572
1573 =over 4
1574
1575 =item Value: \@columns
1576
1577 =back
1578
1579 A arrayref of columns to group by. Can include columns of joined tables.
1580
1581   group_by => [qw/ column1 column2 ... /]
1582
1583 =head2 distinct
1584
1585 =over 4
1586
1587 =item Value: (0 | 1)
1588
1589 =back
1590
1591 Set to 1 to group by all columns.
1592
1593 =head2 cache
1594
1595 Set to 1 to cache search results. This prevents extra SQL queries if you
1596 revisit rows in your ResultSet:
1597
1598   my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1599   
1600   while( my $artist = $resultset->next ) {
1601     ... do stuff ...
1602   }
1603
1604   $rs->first; # without cache, this would issue a query 
1605
1606 By default, searches are not cached.
1607
1608 For more examples of using these attributes, see
1609 L<DBIx::Class::Manual::Cookbook>.
1610
1611 =cut
1612
1613 1;