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