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