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