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