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