prepared for release.
[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 = (ref $group_by ?  @$group_by : ($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   my $del = {};
514   $self->throw_exception("Can't delete on resultset with condition unless hash or array")
515     unless (ref($self->{cond}) eq 'HASH' || ref($self->{cond}) eq 'ARRAY');
516   if (ref $self->{cond} eq 'ARRAY') {
517     $del = [ map { my %hash;
518       foreach my $key (keys %{$_}) {
519         $key =~ /([^\.]+)$/;
520         $hash{$1} = $_->{$key};
521       }; \%hash; } @{$self->{cond}} ];
522   } elsif ((keys %{$self->{cond}})[0] eq '-and') {
523     $del->{-and} = [ map { my %hash;
524       foreach my $key (keys %{$_}) {
525         $key =~ /([^\.]+)$/;
526         $hash{$1} = $_->{$key};
527       }; \%hash; } @{$self->{cond}{-and}} ];
528   } else {
529     foreach my $key (keys %{$self->{cond}}) {
530       $key =~ /([^\.]+)$/;
531       $del->{$1} = $self->{cond}{$key};
532     }
533   }
534   $self->result_source->storage->delete($self->result_source->from, $del);
535   return 1;
536 }
537
538 =head2 delete_all
539
540 Fetches all objects and deletes them one at a time.  Note that C<delete_all>
541 will run cascade triggers while L</delete> will not.
542
543 =cut
544
545 sub delete_all {
546   my ($self) = @_;
547   $_->delete for $self->all;
548   return 1;
549 }
550
551 =head2 pager
552
553 Returns a L<Data::Page> object for the current resultset. Only makes
554 sense for queries with a C<page> attribute.
555
556 =cut
557
558 sub pager {
559   my ($self) = @_;
560   my $attrs = $self->{attrs};
561   $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
562   $attrs->{rows} ||= 10;
563   $self->count;
564   return $self->{pager} ||= Data::Page->new(
565     $self->{count}, $attrs->{rows}, $self->{page});
566 }
567
568 =head2 page($page_num)
569
570 Returns a new resultset for the specified page.
571
572 =cut
573
574 sub page {
575   my ($self, $page) = @_;
576   my $attrs = { %{$self->{attrs}} };
577   $attrs->{page} = $page;
578   return (ref $self)->new($self->result_source, $attrs);
579 }
580
581 =head2 new_result(\%vals)
582
583 Creates a result in the resultset's result class.
584
585 =cut
586
587 sub new_result {
588   my ($self, $values) = @_;
589   $self->throw_exception( "new_result needs a hash" )
590     unless (ref $values eq 'HASH');
591   $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
592     if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
593   my %new = %$values;
594   my $alias = $self->{attrs}{alias};
595   foreach my $key (keys %{$self->{cond}||{}}) {
596     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
597   }
598   my $obj = $self->result_source->result_class->new(\%new);
599   $obj->result_source($self->result_source) if $obj->can('result_source');
600   $obj;
601 }
602
603 =head2 create(\%vals)
604
605 Inserts a record into the resultset and returns the object.
606
607 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
608
609 =cut
610
611 sub create {
612   my ($self, $attrs) = @_;
613   $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
614   return $self->new_result($attrs)->insert;
615 }
616
617 =head2 find_or_create(\%vals, \%attrs?)
618
619   $class->find_or_create({ key => $val, ... });
620
621 Searches for a record matching the search condition; if it doesn't find one,    
622 creates one and returns that instead.                                       
623
624   my $cd = $schema->resultset('CD')->find_or_create({
625     cdid   => 5,
626     artist => 'Massive Attack',
627     title  => 'Mezzanine',
628     year   => 2005,
629   });
630
631 Also takes an optional C<key> attribute, to search by a specific key or unique
632 constraint. For example:
633
634   my $cd = $schema->resultset('CD')->find_or_create(
635     {
636       artist => 'Massive Attack',
637       title  => 'Mezzanine',
638     },
639     { key => 'artist_title' }
640   );
641
642 See also L</find> and L</update_or_create>.
643
644 =cut
645
646 sub find_or_create {
647   my $self     = shift;
648   my $attrs    = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
649   my $hash     = ref $_[0] eq "HASH" ? shift : {@_};
650   my $exists   = $self->find($hash, $attrs);
651   return defined($exists) ? $exists : $self->create($hash);
652 }
653
654 =head2 update_or_create
655
656   $class->update_or_create({ key => $val, ... });
657
658 First, search for an existing row matching one of the unique constraints
659 (including the primary key) on the source of this resultset.  If a row is
660 found, update it with the other given column values.  Otherwise, create a new
661 row.
662
663 Takes an optional C<key> attribute to search on a specific unique constraint.
664 For example:
665
666   # In your application
667   my $cd = $schema->resultset('CD')->update_or_create(
668     {
669       artist => 'Massive Attack',
670       title  => 'Mezzanine',
671       year   => 1998,
672     },
673     { key => 'artist_title' }
674   );
675
676 If no C<key> is specified, it searches on all unique constraints defined on the
677 source, including the primary key.
678
679 If the C<key> is specified as C<primary>, search only on the primary key.
680
681 See also L</find> and L</find_or_create>.
682
683 =cut
684
685 sub update_or_create {
686   my $self = shift;
687
688   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
689   my $hash  = ref $_[0] eq "HASH" ? shift : {@_};
690
691   my %unique_constraints = $self->result_source->unique_constraints;
692   my @constraint_names   = (exists $attrs->{key}
693                             ? ($attrs->{key})
694                             : keys %unique_constraints);
695
696   my @unique_hashes;
697   foreach my $name (@constraint_names) {
698     my @unique_cols = @{ $unique_constraints{$name} };
699     my %unique_hash =
700       map  { $_ => $hash->{$_} }
701       grep { exists $hash->{$_} }
702       @unique_cols;
703
704     push @unique_hashes, \%unique_hash
705       if (scalar keys %unique_hash == scalar @unique_cols);
706   }
707
708   my $row;
709   if (@unique_hashes) {
710     $row = $self->search(\@unique_hashes, { rows => 1 })->first;
711     if ($row) {
712       $row->set_columns($hash);
713       $row->update;
714     }
715   }
716
717   unless ($row) {
718     $row = $self->create($hash);
719   }
720
721   return $row;
722 }
723
724 =head2 throw_exception
725
726 See Schema's throw_exception
727
728 =cut
729
730 sub throw_exception {
731   my $self=shift;
732   $self->result_source->schema->throw_exception(@_);
733 }
734
735 =head1 ATTRIBUTES
736
737 The resultset takes various attributes that modify its behavior. Here's an
738 overview of them:
739
740 =head2 order_by
741
742 Which column(s) to order the results by. This is currently passed through
743 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
744
745 =head2 cols (arrayref)
746
747 Shortcut to request a particular set of columns to be retrieved.  Adds
748 C<me.> onto the start of any column without a C<.> in it and sets C<select>
749 from that, then auto-populates C<as> from C<select> as normal.
750
751 =head2 include_columns (arrayref)
752
753 Shortcut to include additional columns in the returned results - for example
754
755   { include_columns => ['foo.name'], join => ['foo'] }
756
757 would add a 'name' column to the information passed to object inflation
758
759 =head2 select (arrayref)
760
761 Indicates which columns should be selected from the storage. You can use
762 column names, or in the case of RDBMS back ends, function or stored procedure
763 names:
764
765   $rs = $schema->resultset('Foo')->search(
766     {},
767     {
768       select => [
769         'column_name',
770         { count => 'column_to_count' },
771         { sum => 'column_to_sum' }
772       ]
773     }
774   );
775
776 When you use function/stored procedure names and do not supply an C<as>
777 attribute, the column names returned are storage-dependent. E.g. MySQL would
778 return a column named C<count(column_to_count)> in the above example.
779
780 =head2 as (arrayref)
781
782 Indicates column names for object inflation. This is used in conjunction with
783 C<select>, usually when C<select> contains one or more function or stored
784 procedure names:
785
786   $rs = $schema->resultset('Foo')->search(
787     {},
788     {
789       select => [
790         'column1',
791         { count => 'column2' }
792       ],
793       as => [qw/ column1 column2_count /]
794     }
795   );
796
797   my $foo = $rs->first(); # get the first Foo
798
799 If the object against which the search is performed already has an accessor
800 matching a column name specified in C<as>, the value can be retrieved using
801 the accessor as normal:
802
803   my $column1 = $foo->column1();
804
805 If on the other hand an accessor does not exist in the object, you need to
806 use C<get_column> instead:
807
808   my $column2_count = $foo->get_column('column2_count');
809
810 You can create your own accessors if required - see
811 L<DBIx::Class::Manual::Cookbook> for details.
812
813 =head2 join
814
815 Contains a list of relationships that should be joined for this query.  For
816 example:
817
818   # Get CDs by Nine Inch Nails
819   my $rs = $schema->resultset('CD')->search(
820     { 'artist.name' => 'Nine Inch Nails' },
821     { join => 'artist' }
822   );
823
824 Can also contain a hash reference to refer to the other relation's relations.
825 For example:
826
827   package MyApp::Schema::Track;
828   use base qw/DBIx::Class/;
829   __PACKAGE__->table('track');
830   __PACKAGE__->add_columns(qw/trackid cd position title/);
831   __PACKAGE__->set_primary_key('trackid');
832   __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
833   1;
834
835   # In your application
836   my $rs = $schema->resultset('Artist')->search(
837     { 'track.title' => 'Teardrop' },
838     {
839       join     => { cd => 'track' },
840       order_by => 'artist.name',
841     }
842   );
843
844 If the same join is supplied twice, it will be aliased to <rel>_2 (and
845 similarly for a third time). For e.g.
846
847   my $rs = $schema->resultset('Artist')->search(
848     { 'cds.title'   => 'Foo',
849       'cds_2.title' => 'Bar' },
850     { join => [ qw/cds cds/ ] });
851
852 will return a set of all artists that have both a cd with title Foo and a cd
853 with title Bar.
854
855 If you want to fetch related objects from other tables as well, see C<prefetch>
856 below.
857
858 =head2 prefetch arrayref/hashref
859
860 Contains one or more relationships that should be fetched along with the main 
861 query (when they are accessed afterwards they will have already been
862 "prefetched").  This is useful for when you know you will need the related
863 objects, because it saves at least one query:
864
865   my $rs = $schema->resultset('Tag')->search(
866     {},
867     {
868       prefetch => {
869         cd => 'artist'
870       }
871     }
872   );
873
874 The initial search results in SQL like the following:
875
876   SELECT tag.*, cd.*, artist.* FROM tag
877   JOIN cd ON tag.cd = cd.cdid
878   JOIN artist ON cd.artist = artist.artistid
879
880 L<DBIx::Class> has no need to go back to the database when we access the
881 C<cd> or C<artist> relationships, which saves us two SQL statements in this
882 case.
883
884 Simple prefetches will be joined automatically, so there is no need
885 for a C<join> attribute in the above search. If you're prefetching to
886 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
887 specify the join as well.
888
889 C<prefetch> can be used with the following relationship types: C<belongs_to>,
890 C<has_one> (or if you're using C<add_relationship>, any relationship declared
891 with an accessor type of 'single' or 'filter').
892
893 =head2 from (arrayref)
894
895 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
896 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
897 clauses.
898
899 NOTE: Use this on your own risk.  This allows you to shoot off your foot!
900 C<join> will usually do what you need and it is strongly recommended that you
901 avoid using C<from> unless you cannot achieve the desired result using C<join>.
902
903 In simple terms, C<from> works as follows:
904
905     [
906         { <alias> => <table>, -join-type => 'inner|left|right' }
907         [] # nested JOIN (optional)
908         { <table.column> = <foreign_table.foreign_key> }
909     ]
910
911     JOIN
912         <alias> <table>
913         [JOIN ...]
914     ON <table.column> = <foreign_table.foreign_key>
915
916 An easy way to follow the examples below is to remember the following:
917
918     Anything inside "[]" is a JOIN
919     Anything inside "{}" is a condition for the enclosing JOIN
920
921 The following examples utilize a "person" table in a family tree application.
922 In order to express parent->child relationships, this table is self-joined:
923
924     # Person->belongs_to('father' => 'Person');
925     # Person->belongs_to('mother' => 'Person');
926
927 C<from> can be used to nest joins. Here we return all children with a father,
928 then search against all mothers of those children:
929
930   $rs = $schema->resultset('Person')->search(
931       {},
932       {
933           alias => 'mother', # alias columns in accordance with "from"
934           from => [
935               { mother => 'person' },
936               [
937                   [
938                       { child => 'person' },
939                       [
940                           { father => 'person' },
941                           { 'father.person_id' => 'child.father_id' }
942                       ]
943                   ],
944                   { 'mother.person_id' => 'child.mother_id' }
945               ],                
946           ]
947       },
948   );
949
950   # Equivalent SQL:
951   # SELECT mother.* FROM person mother
952   # JOIN (
953   #   person child
954   #   JOIN person father
955   #   ON ( father.person_id = child.father_id )
956   # )
957   # ON ( mother.person_id = child.mother_id )
958
959 The type of any join can be controlled manually. To search against only people
960 with a father in the person table, we could explicitly use C<INNER JOIN>:
961
962     $rs = $schema->resultset('Person')->search(
963         {},
964         {
965             alias => 'child', # alias columns in accordance with "from"
966             from => [
967                 { child => 'person' },
968                 [
969                     { father => 'person', -join-type => 'inner' },
970                     { 'father.id' => 'child.father_id' }
971                 ],
972             ]
973         },
974     );
975
976     # Equivalent SQL:
977     # SELECT child.* FROM person child
978     # INNER JOIN person father ON child.father_id = father.id
979
980 =head2 page
981
982 For a paged resultset, specifies which page to retrieve.  Leave unset
983 for an unpaged resultset.
984
985 =head2 rows
986
987 For a paged resultset, how many rows per page:
988
989   rows => 10
990
991 Can also be used to simulate an SQL C<LIMIT>.
992
993 =head2 group_by (arrayref)
994
995 A arrayref of columns to group by. Can include columns of joined tables.
996
997   group_by => [qw/ column1 column2 ... /]
998
999 =head2 distinct
1000
1001 Set to 1 to group by all columns.
1002
1003 For more examples of using these attributes, see
1004 L<DBIx::Class::Manual::Cookbook>.
1005
1006 =cut
1007
1008 1;