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