Fixes to deep search and search_related
[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
12 use base qw/DBIx::Class/;
13 __PACKAGE__->load_components(qw/AccessorGroup/);
14 __PACKAGE__->mk_group_accessors('simple' => 'result_source');
15
16 =head1 NAME
17
18 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
19
20 =head1 SYNOPSIS
21
22   my $rs   = $schema->resultset('User')->search(registered => 1);
23   my @rows = $schema->resultset('Foo')->search(bar => 'baz');
24
25 =head1 DESCRIPTION
26
27 The resultset is also known as an iterator. It is responsible for handling
28 queries that may return an arbitrary number of rows, e.g. via L</search>
29 or a C<has_many> relationship.
30
31 In the examples below, the following table classes are used:
32
33   package MyApp::Schema::Artist;
34   use base qw/DBIx::Class/;
35   __PACKAGE__->table('artist');
36   __PACKAGE__->add_columns(qw/artistid name/);
37   __PACKAGE__->set_primary_key('artistid');
38   __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
39   1;
40
41   package MyApp::Schema::CD;
42   use base qw/DBIx::Class/;
43   __PACKAGE__->table('artist');
44   __PACKAGE__->add_columns(qw/cdid artist title year/);
45   __PACKAGE__->set_primary_key('cdid');
46   __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
47   1;
48
49 =head1 METHODS
50
51 =head2 new($source, \%$attrs)
52
53 The resultset constructor. Takes a source object (usually a
54 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see L</ATRRIBUTES>
55 below).  Does not perform any queries -- these are executed as needed by the
56 other methods.
57
58 Generally you won't need to construct a resultset manually.  You'll
59 automatically get one from e.g. a L</search> called in scalar context:
60
61   my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
62
63 =cut
64
65 sub new {
66   my $class = shift;
67   return $class->new_result(@_) if ref $class;
68   my ($source, $attrs) = @_;
69   #use Data::Dumper; warn Dumper($attrs);
70   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
71   my %seen;
72   my $alias = ($attrs->{alias} ||= 'me');
73   if ($attrs->{cols} || !$attrs->{select}) {
74     delete $attrs->{as} if $attrs->{cols};
75     my @cols = ($attrs->{cols}
76                  ? @{delete $attrs->{cols}}
77                  : $source->columns);
78     $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @cols ];
79   }
80   $attrs->{as} ||= [ map { m/^$alias\.(.*)$/ ? $1 : $_ } @{$attrs->{select}} ];
81   if (my $include = delete $attrs->{include_columns}) {
82     push(@{$attrs->{select}}, @$include);
83     push(@{$attrs->{as}}, map { m/([^\.]+)$/; $1; } @$include);
84   }
85   #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
86   $attrs->{from} ||= [ { $alias => $source->from } ];
87   $attrs->{seen_join} ||= {};
88   if (my $join = delete $attrs->{join}) {
89     foreach my $j (ref $join eq 'ARRAY'
90               ? (@{$join}) : ($join)) {
91       if (ref $j eq 'HASH') {
92         $seen{$_} = 1 foreach keys %$j;
93       } else {
94         $seen{$j} = 1;
95       }
96     }
97     push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}, $attrs->{seen_join}));
98   }
99   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
100
101   if (my $prefetch = delete $attrs->{prefetch}) {
102     foreach my $p (ref $prefetch eq 'ARRAY'
103               ? (@{$prefetch}) : ($prefetch)) {
104       if( ref $p eq 'HASH' ) {
105         foreach my $key (keys %$p) {
106           push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
107             unless $seen{$key};
108         }
109       }
110       else {
111         push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
112             unless $seen{$p};
113       }
114       my @prefetch = $source->resolve_prefetch($p, $attrs->{alias});
115       #die Dumper \@cols;
116       push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
117       push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
118     }
119   }
120
121   if ($attrs->{page}) {
122     $attrs->{rows} ||= 10;
123     $attrs->{offset} ||= 0;
124     $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
125   }
126   my $new = {
127     result_source => $source,
128     cond => $attrs->{where},
129     from => $attrs->{from},
130     count => undef,
131     page => delete $attrs->{page},
132     pager => undef,
133     attrs => $attrs };
134   bless ($new, $class);
135   return $new;
136 }
137
138 =head2 search
139
140   my @obj    = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
141   my $new_rs = $rs->search({ foo => 3 });
142
143 If you need to pass in additional attributes but no additional condition,
144 call it as C<search({}, \%attrs);>.
145
146   # "SELECT foo, bar FROM $class_table"
147   my @all = $class->search({}, { cols => [qw/foo bar/] });
148
149 =cut
150
151 sub search {
152   my $self = shift;
153
154   #use Data::Dumper;warn Dumper(@_);
155
156   my $attrs = { %{$self->{attrs}} };
157   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
158     $attrs = { %$attrs, %{ pop(@_) } };
159   }
160
161   my $where = (@_ ? ((@_ == 1 || ref $_[0] eq "HASH") ? shift : {@_}) : undef());
162   if (defined $where) {
163     $where = (defined $attrs->{where}
164                 ? { '-and' =>
165                     [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
166                         $where, $attrs->{where} ] }
167                 : $where);
168     $attrs->{where} = $where;
169   }
170
171   my $rs = (ref $self)->new($self->result_source, $attrs);
172
173   return (wantarray ? $rs->all : $rs);
174 }
175
176 =head2 search_literal
177
178   my @obj    = $rs->search_literal($literal_where_cond, @bind);
179   my $new_rs = $rs->search_literal($literal_where_cond, @bind);
180
181 Pass a literal chunk of SQL to be added to the conditional part of the
182 resultset.
183
184 =cut
185                                                          
186 sub search_literal {
187   my ($self, $cond, @vals) = @_;
188   my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
189   $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
190   return $self->search(\$cond, $attrs);
191 }
192
193 =head2 find(@colvalues), find(\%cols, \%attrs?)
194
195 Finds a row based on its primary key or unique constraint. For example:
196
197   my $cd = $schema->resultset('CD')->find(5);
198
199 Also takes an optional C<key> attribute, to search by a specific key or unique
200 constraint. For example:
201
202   my $cd = $schema->resultset('CD')->find_or_create(
203     {
204       artist => 'Massive Attack',
205       title  => 'Mezzanine',
206     },
207     { key => 'artist_title' }
208   );
209
210 See also L</find_or_create> and L</update_or_create>.
211
212 =cut
213
214 sub find {
215   my ($self, @vals) = @_;
216   my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
217
218   my @cols = $self->result_source->primary_columns;
219   if (exists $attrs->{key}) {
220     my %uniq = $self->result_source->unique_constraints;
221     $self->( "Unknown key " . $attrs->{key} . " on " . $self->name )
222       unless exists $uniq{$attrs->{key}};
223     @cols = @{ $uniq{$attrs->{key}} };
224   }
225   #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
226   $self->throw_exception( "Can't find unless a primary key or unique constraint is defined" )
227     unless @cols;
228
229   my $query;
230   if (ref $vals[0] eq 'HASH') {
231     $query = { %{$vals[0]} };
232   } elsif (@cols == @vals) {
233     $query = {};
234     @{$query}{@cols} = @vals;
235   } else {
236     $query = {@vals};
237   }
238   foreach (keys %$query) {
239     next if m/\./;
240     $query->{$self->{attrs}{alias}.'.'.$_} = delete $query->{$_};
241   }
242   #warn Dumper($query);
243   return $self->search($query,$attrs)->next;
244 }
245
246 =head2 search_related
247
248   $rs->search_related('relname', $cond?, $attrs?);
249
250 Search the specified relationship. Optionally specify a condition for matching
251 records.
252
253 =cut
254
255 sub search_related {
256   my ($self, $rel, @rest) = @_;
257   my $rel_obj = $self->result_source->relationship_info($rel);
258   $self->throw_exception(
259     "No such relationship ${rel} in search_related")
260       unless $rel_obj;
261   my $rs = $self->search(undef, { join => $rel });
262   my $alias = ($rs->{attrs}{seen_join}{$rel} > 1
263                 ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
264                 : $rel);
265   return $self->result_source->schema->resultset($rel_obj->{class}
266            )->search( undef,
267              { %{$rs->{attrs}},
268                alias => $alias,
269                select => undef(),
270                as => undef() }
271            )->search(@rest);
272 }
273
274 =head2 cursor
275
276 Returns a storage-driven cursor to the given resultset.
277
278 =cut
279
280 sub cursor {
281   my ($self) = @_;
282   my ($attrs) = $self->{attrs};
283   $attrs = { %$attrs };
284   return $self->{cursor}
285     ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
286           $attrs->{where},$attrs);
287 }
288
289 =head2 search_like
290
291 Perform a search, but use C<LIKE> instead of equality as the condition. Note
292 that this is simply a convenience method; you most likely want to use
293 L</search> with specific operators.
294
295 For more information, see L<DBIx::Class::Manual::Cookbook>.
296
297 =cut
298
299 sub search_like {
300   my $class    = shift;
301   my $attrs = { };
302   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
303     $attrs = pop(@_);
304   }
305   my $query    = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
306   $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
307   return $class->search($query, { %$attrs });
308 }
309
310 =head2 slice($first, $last)
311
312 Returns a subset of elements from the resultset.
313
314 =cut
315
316 sub slice {
317   my ($self, $min, $max) = @_;
318   my $attrs = { %{ $self->{attrs} || {} } };
319   $attrs->{offset} ||= 0;
320   $attrs->{offset} += $min;
321   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
322   my $slice = (ref $self)->new($self->result_source, $attrs);
323   return (wantarray ? $slice->all : $slice);
324 }
325
326 =head2 next
327
328 Returns the next element in the resultset (C<undef> is there is none).
329
330 Can be used to efficiently iterate over records in the resultset:
331
332   my $rs = $schema->resultset('CD')->search({});
333   while (my $cd = $rs->next) {
334     print $cd->title;
335   }
336
337 =cut
338
339 sub next {
340   my ($self) = @_;
341   my @row = $self->cursor->next;
342 #  warn Dumper(\@row); use Data::Dumper;
343   return unless (@row);
344   return $self->_construct_object(@row);
345 }
346
347 sub _construct_object {
348   my ($self, @row) = @_;
349   my @as = @{ $self->{attrs}{as} };
350   #warn "@cols -> @row";
351   my $info = [ {}, {} ];
352   foreach my $as (@as) {
353     my $target = $info;
354     my @parts = split(/\./, $as);
355     my $col = pop(@parts);
356     foreach my $p (@parts) {
357       $target = $target->[1]->{$p} ||= [];
358     }
359     $target->[0]->{$col} = shift @row;
360   }
361   #use Data::Dumper; warn Dumper(\@as, $info);
362   my $new = $self->result_source->result_class->inflate_result(
363               $self->result_source, @$info);
364   $new = $self->{attrs}{record_filter}->($new)
365     if exists $self->{attrs}{record_filter};
366   return $new;
367 }
368
369 =head2 result_source 
370
371 Returns a reference to the result source for this recordset.
372
373 =cut
374
375
376 =head2 count
377
378 Performs an SQL C<COUNT> with the same query as the resultset was built
379 with to find the number of elements. If passed arguments, does a search
380 on the resultset and counts the results of that.
381
382 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
383 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
384 not support C<DISTINCT> with multiple columns. If you are using such a
385 database, you should only use columns from the main table in your C<group_by>
386 clause.
387
388 =cut
389
390 sub count {
391   my $self = shift;
392   return $self->search(@_)->count if @_ && defined $_[0];
393   unless (defined $self->{count}) {
394     my $group_by;
395     my $select = { 'count' => '*' };
396     if( $group_by = delete $self->{attrs}{group_by} ) {
397       my @distinct = @$group_by;
398       # todo: try CONCAT for multi-column pk
399       my @pk = $self->result_source->primary_columns;
400       if( scalar(@pk) == 1 ) {
401         my $pk = shift(@pk);
402         my $alias = $self->{attrs}{alias};
403         my $re = qr/^($alias\.)?$pk$/;
404         foreach my $column ( @$group_by ) {
405           if( $column =~ $re ) {
406             @distinct = ( $column );
407             last;
408           }
409         } 
410       }
411
412       $select = { count => { 'distinct' => \@distinct } };
413       #use Data::Dumper; die Dumper $select;
414     }
415
416     my $attrs = { %{ $self->{attrs} },
417                   select => $select,
418                   as => [ 'count' ] };
419     # offset, order by and page are not needed to count. record_filter is cdbi
420     delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
421         
422     ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
423     $self->{attrs}{group_by} = $group_by;
424   }
425   return 0 unless $self->{count};
426   my $count = $self->{count};
427   $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
428   $count = $self->{attrs}{rows} if
429     ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
430   return $count;
431 }
432
433 =head2 count_literal
434
435 Calls L</search_literal> with the passed arguments, then L</count>.
436
437 =cut
438
439 sub count_literal { shift->search_literal(@_)->count; }
440
441 =head2 all
442
443 Returns all elements in the resultset. Called implictly if the resultset
444 is returned in list context.
445
446 =cut
447
448 sub all {
449   my ($self) = @_;
450   return map { $self->_construct_object(@$_); }
451            $self->cursor->all;
452 }
453
454 =head2 reset
455
456 Resets the resultset's cursor, so you can iterate through the elements again.
457
458 =cut
459
460 sub reset {
461   my ($self) = @_;
462   $self->cursor->reset;
463   return $self;
464 }
465
466 =head2 first
467
468 Resets the resultset and returns the first element.
469
470 =cut
471
472 sub first {
473   return $_[0]->reset->next;
474 }
475
476 =head2 update(\%values)
477
478 Sets the specified columns in the resultset to the supplied values.
479
480 =cut
481
482 sub update {
483   my ($self, $values) = @_;
484   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
485   return $self->result_source->storage->update(
486            $self->result_source->from, $values, $self->{cond});
487 }
488
489 =head2 update_all(\%values)
490
491 Fetches all objects and updates them one at a time.  Note that C<update_all>
492 will run cascade triggers while L</update> will not.
493
494 =cut
495
496 sub update_all {
497   my ($self, $values) = @_;
498   $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
499   foreach my $obj ($self->all) {
500     $obj->set_columns($values)->update;
501   }
502   return 1;
503 }
504
505 =head2 delete
506
507 Deletes the contents of the resultset from its result source.
508
509 =cut
510
511 sub delete {
512   my ($self) = @_;
513   $self->result_source->storage->delete($self->result_source->from, $self->{cond});
514   return 1;
515 }
516
517 =head2 delete_all
518
519 Fetches all objects and deletes them one at a time.  Note that C<delete_all>
520 will run cascade triggers while L</delete> will not.
521
522 =cut
523
524 sub delete_all {
525   my ($self) = @_;
526   $_->delete for $self->all;
527   return 1;
528 }
529
530 =head2 pager
531
532 Returns a L<Data::Page> object for the current resultset. Only makes
533 sense for queries with a C<page> attribute.
534
535 =cut
536
537 sub pager {
538   my ($self) = @_;
539   my $attrs = $self->{attrs};
540   $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
541   $attrs->{rows} ||= 10;
542   $self->count;
543   return $self->{pager} ||= Data::Page->new(
544     $self->{count}, $attrs->{rows}, $self->{page});
545 }
546
547 =head2 page($page_num)
548
549 Returns a new resultset for the specified page.
550
551 =cut
552
553 sub page {
554   my ($self, $page) = @_;
555   my $attrs = { %{$self->{attrs}} };
556   $attrs->{page} = $page;
557   return (ref $self)->new($self->result_source, $attrs);
558 }
559
560 =head2 new_result(\%vals)
561
562 Creates a result in the resultset's result class.
563
564 =cut
565
566 sub new_result {
567   my ($self, $values) = @_;
568   $self->throw_exception( "new_result needs a hash" )
569     unless (ref $values eq 'HASH');
570   $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
571     if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
572   my %new = %$values;
573   my $alias = $self->{attrs}{alias};
574   foreach my $key (keys %{$self->{cond}||{}}) {
575     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
576   }
577   my $obj = $self->result_source->result_class->new(\%new);
578   $obj->result_source($self->result_source) if $obj->can('result_source');
579   $obj;
580 }
581
582 =head2 create(\%vals)
583
584 Inserts a record into the resultset and returns the object.
585
586 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
587
588 =cut
589
590 sub create {
591   my ($self, $attrs) = @_;
592   $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
593   return $self->new_result($attrs)->insert;
594 }
595
596 =head2 find_or_create(\%vals, \%attrs?)
597
598   $class->find_or_create({ key => $val, ... });
599
600 Searches for a record matching the search condition; if it doesn't find one,    
601 creates one and returns that instead.                                       
602
603   my $cd = $schema->resultset('CD')->find_or_create({
604     cdid   => 5,
605     artist => 'Massive Attack',
606     title  => 'Mezzanine',
607     year   => 2005,
608   });
609
610 Also takes an optional C<key> attribute, to search by a specific key or unique
611 constraint. For example:
612
613   my $cd = $schema->resultset('CD')->find_or_create(
614     {
615       artist => 'Massive Attack',
616       title  => 'Mezzanine',
617     },
618     { key => 'artist_title' }
619   );
620
621 See also L</find> and L</update_or_create>.
622
623 =cut
624
625 sub find_or_create {
626   my $self     = shift;
627   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
628   my $hash     = ref $_[0] eq "HASH" ? shift : {@_};
629   my $exists   = $self->find($hash, $attrs);
630   return defined($exists) ? $exists : $self->create($hash);
631 }
632
633 =head2 update_or_create
634
635   $class->update_or_create({ key => $val, ... });
636
637 First, search for an existing row matching one of the unique constraints
638 (including the primary key) on the source of this resultset.  If a row is
639 found, update it with the other given column values.  Otherwise, create a new
640 row.
641
642 Takes an optional C<key> attribute to search on a specific unique constraint.
643 For example:
644
645   # In your application
646   my $cd = $schema->resultset('CD')->update_or_create(
647     {
648       artist => 'Massive Attack',
649       title  => 'Mezzanine',
650       year   => 1998,
651     },
652     { key => 'artist_title' }
653   );
654
655 If no C<key> is specified, it searches on all unique constraints defined on the
656 source, including the primary key.
657
658 If the C<key> is specified as C<primary>, search only on the primary key.
659
660 See also L</find> and L</find_or_create>.
661
662 =cut
663
664 sub update_or_create {
665   my $self = shift;
666
667   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
668   my $hash  = ref $_[0] eq "HASH" ? shift : {@_};
669
670   my %unique_constraints = $self->result_source->unique_constraints;
671   my @constraint_names   = (exists $attrs->{key}
672                             ? ($attrs->{key})
673                             : keys %unique_constraints);
674
675   my @unique_hashes;
676   foreach my $name (@constraint_names) {
677     my @unique_cols = @{ $unique_constraints{$name} };
678     my %unique_hash =
679       map  { $_ => $hash->{$_} }
680       grep { exists $hash->{$_} }
681       @unique_cols;
682
683     push @unique_hashes, \%unique_hash
684       if (scalar keys %unique_hash == scalar @unique_cols);
685   }
686
687   my $row;
688   if (@unique_hashes) {
689     $row = $self->search(\@unique_hashes, { rows => 1 })->first;
690     if ($row) {
691       $row->set_columns($hash);
692       $row->update;
693     }
694   }
695
696   unless ($row) {
697     $row = $self->create($hash);
698   }
699
700   return $row;
701 }
702
703 =head2 throw_exception
704
705 See Schema's throw_exception
706
707 =cut
708
709 sub throw_exception {
710   my $self=shift;
711   $self->result_source->schema->throw_exception(@_);
712 }
713
714 =head1 ATTRIBUTES
715
716 The resultset takes various attributes that modify its behavior. Here's an
717 overview of them:
718
719 =head2 order_by
720
721 Which column(s) to order the results by. This is currently passed through
722 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
723
724 =head2 cols (arrayref)
725
726 Shortcut to request a particular set of columns to be retrieved.  Adds
727 C<me.> onto the start of any column without a C<.> in it and sets C<select>
728 from that, then auto-populates C<as> from C<select> as normal.
729
730 =head2 include_columns (arrayref)
731
732 Shortcut to include additional columns in the returned results - for example
733
734   { include_columns => ['foo.name'], join => ['foo'] }
735
736 would add a 'name' column to the information passed to object inflation
737
738 =head2 select (arrayref)
739
740 Indicates which columns should be selected from the storage. You can use
741 column names, or in the case of RDBMS back ends, function or stored procedure
742 names:
743
744   $rs = $schema->resultset('Foo')->search(
745     {},
746     {
747       select => [
748         'column_name',
749         { count => 'column_to_count' },
750         { sum => 'column_to_sum' }
751       ]
752     }
753   );
754
755 When you use function/stored procedure names and do not supply an C<as>
756 attribute, the column names returned are storage-dependent. E.g. MySQL would
757 return a column named C<count(column_to_count)> in the above example.
758
759 =head2 as (arrayref)
760
761 Indicates column names for object inflation. This is used in conjunction with
762 C<select>, usually when C<select> contains one or more function or stored
763 procedure names:
764
765   $rs = $schema->resultset('Foo')->search(
766     {},
767     {
768       select => [
769         'column1',
770         { count => 'column2' }
771       ],
772       as => [qw/ column1 column2_count /]
773     }
774   );
775
776   my $foo = $rs->first(); # get the first Foo
777
778 If the object against which the search is performed already has an accessor
779 matching a column name specified in C<as>, the value can be retrieved using
780 the accessor as normal:
781
782   my $column1 = $foo->column1();
783
784 If on the other hand an accessor does not exist in the object, you need to
785 use C<get_column> instead:
786
787   my $column2_count = $foo->get_column('column2_count');
788
789 You can create your own accessors if required - see
790 L<DBIx::Class::Manual::Cookbook> for details.
791
792 =head2 join
793
794 Contains a list of relationships that should be joined for this query.  For
795 example:
796
797   # Get CDs by Nine Inch Nails
798   my $rs = $schema->resultset('CD')->search(
799     { 'artist.name' => 'Nine Inch Nails' },
800     { join => 'artist' }
801   );
802
803 Can also contain a hash reference to refer to the other relation's relations.
804 For example:
805
806   package MyApp::Schema::Track;
807   use base qw/DBIx::Class/;
808   __PACKAGE__->table('track');
809   __PACKAGE__->add_columns(qw/trackid cd position title/);
810   __PACKAGE__->set_primary_key('trackid');
811   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
812   1;
813
814   # In your application
815   my $rs = $schema->resultset('Artist')->search(
816     { 'track.title' => 'Teardrop' },
817     {
818       join     => { cd => 'track' },
819       order_by => 'artist.name',
820     }
821   );
822
823 If the same join is supplied twice, it will be aliased to <rel>_2 (and
824 similarly for a third time). For e.g.
825
826   my $rs = $schema->resultset('Artist')->search(
827     { 'cds.title'   => 'Foo',
828       'cds_2.title' => 'Bar' },
829     { join => [ qw/cds cds/ ] });
830
831 will return a set of all artists that have both a cd with title Foo and a cd
832 with title Bar.
833
834 If you want to fetch related objects from other tables as well, see C<prefetch>
835 below.
836
837 =head2 prefetch arrayref/hashref
838
839 Contains one or more relationships that should be fetched along with the main 
840 query (when they are accessed afterwards they will have already been
841 "prefetched").  This is useful for when you know you will need the related
842 objects, because it saves at least one query:
843
844   my $rs = $schema->resultset('Tag')->search(
845     {},
846     {
847       prefetch => {
848         cd => 'artist'
849       }
850     }
851   );
852
853 The initial search results in SQL like the following:
854
855   SELECT tag.*, cd.*, artist.* FROM tag
856   JOIN cd ON tag.cd = cd.cdid
857   JOIN artist ON cd.artist = artist.artistid
858
859 L<DBIx::Class> has no need to go back to the database when we access the
860 C<cd> or C<artist> relationships, which saves us two SQL statements in this
861 case.
862
863 Simple prefetches will be joined automatically, so there is no need
864 for a C<join> attribute in the above search. If you're prefetching to
865 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
866 specify the join as well.
867
868 C<prefetch> can be used with the following relationship types: C<belongs_to>,
869 C<has_one> (or if you're using C<add_relationship>, any relationship declared
870 with an accessor type of 'single' or 'filter').
871
872 =head2 from (arrayref)
873
874 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
875 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
876 clauses.
877
878 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
879 C<join> will usually do what you need and it is strongly recommended that you
880 avoid using C<from> unless you cannot achieve the desired result using C<join>.
881
882 In simple terms, C<from> works as follows:
883
884     [
885         { <alias> => <table>, -join-type => 'inner|left|right' }
886         [] # nested JOIN (optional)
887         { <table.column> = <foreign_table.foreign_key> }
888     ]
889
890     JOIN
891         <alias> <table>
892         [JOIN ...]
893     ON <table.column> = <foreign_table.foreign_key>
894
895 An easy way to follow the examples below is to remember the following:
896
897     Anything inside "[]" is a JOIN
898     Anything inside "{}" is a condition for the enclosing JOIN
899
900 The following examples utilize a "person" table in a family tree application.
901 In order to express parent->child relationships, this table is self-joined:
902
903     # Person->belongs_to('father' => 'Person');
904     # Person->belongs_to('mother' => 'Person');
905
906 C<from> can be used to nest joins. Here we return all children with a father,
907 then search against all mothers of those children:
908
909   $rs = $schema->resultset('Person')->search(
910       {},
911       {
912           alias => 'mother', # alias columns in accordance with "from"
913           from => [
914               { mother => 'person' },
915               [
916                   [
917                       { child => 'person' },
918                       [
919                           { father => 'person' },
920                           { 'father.person_id' => 'child.father_id' }
921                       ]
922                   ],
923                   { 'mother.person_id' => 'child.mother_id' }
924               ],                
925           ]
926       },
927   );
928
929   # Equivalent SQL:
930   # SELECT mother.* FROM person mother
931   # JOIN (
932   #   person child
933   #   JOIN person father
934   #   ON ( father.person_id = child.father_id )
935   # )
936   # ON ( mother.person_id = child.mother_id )
937
938 The type of any join can be controlled manually. To search against only people
939 with a father in the person table, we could explicitly use C<INNER JOIN>:
940
941     $rs = $schema->resultset('Person')->search(
942         {},
943         {
944             alias => 'child', # alias columns in accordance with "from"
945             from => [
946                 { child => 'person' },
947                 [
948                     { father => 'person', -join-type => 'inner' },
949                     { 'father.id' => 'child.father_id' }
950                 ],
951             ]
952         },
953     );
954
955     # Equivalent SQL:
956     # SELECT child.* FROM person child
957     # INNER JOIN person father ON child.father_id = father.id
958
959 =head2 page
960
961 For a paged resultset, specifies which page to retrieve.  Leave unset
962 for an unpaged resultset.
963
964 =head2 rows
965
966 For a paged resultset, how many rows per page:
967
968   rows => 10
969
970 Can also be used to simulate an SQL C<LIMIT>.
971
972 =head2 group_by (arrayref)
973
974 A arrayref of columns to group by. Can include columns of joined tables.
975
976   group_by => [qw/ column1 column2 ... /]
977
978 =head2 distinct
979
980 Set to 1 to group by all columns.
981
982 For more examples of using these attributes, see
983 L<DBIx::Class::Manual::Cookbook>.
984
985 =cut
986
987 1;