1 package DBIx::Class::ResultSet;
12 use base qw/DBIx::Class/;
13 __PACKAGE__->load_components(qw/AccessorGroup/);
14 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
18 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
22 my $rs = $schema->resultset('User')->search(registered => 1);
23 my @rows = $schema->resultset('Foo')->search(bar => 'baz');
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.
31 In the examples below, the following table classes are used:
33 package MyApp::Schema::Artist;
34 use base qw/DBIx::Class/;
35 __PACKAGE__->load_components(qw/Core/);
36 __PACKAGE__->table('artist');
37 __PACKAGE__->add_columns(qw/artistid name/);
38 __PACKAGE__->set_primary_key('artistid');
39 __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
42 package MyApp::Schema::CD;
43 use base qw/DBIx::Class/;
44 __PACKAGE__->load_components(qw/Core/);
45 __PACKAGE__->table('cd');
46 __PACKAGE__->add_columns(qw/cdid artist title year/);
47 __PACKAGE__->set_primary_key('cdid');
48 __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
55 =head3 Arguments: ($source, \%$attrs)
57 The resultset constructor. Takes a source object (usually a
58 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see L</ATTRIBUTES>
59 below). Does not perform any queries -- these are executed as needed by the
62 Generally you won't need to construct a resultset manually. You'll
63 automatically get one from e.g. a L</search> called in scalar context:
65 my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
71 return $class->new_result(@_) if ref $class;
73 my ($source, $attrs) = @_;
74 #use Data::Dumper; warn Dumper($attrs);
75 $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
76 my $alias = ($attrs->{alias} ||= 'me');
78 $attrs->{columns} ||= delete $attrs->{cols} if $attrs->{cols};
79 $attrs->{columns} ||= [ $source->columns ] unless $attrs->{select};
80 if ($attrs->{columns}) {
82 $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}} ];
84 $attrs->{as} ||= [ map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}} ];
85 if (my $include = delete $attrs->{include_columns}) {
86 push(@{$attrs->{select}}, @$include);
87 push(@{$attrs->{as}}, map { m/([^\.]+)$/; $1; } @$include);
89 #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
91 $attrs->{from} ||= [ { $alias => $source->from } ];
92 $attrs->{seen_join} ||= {};
94 if (my $join = delete $attrs->{join}) {
95 foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
96 if (ref $j eq 'HASH') {
97 $seen{$_} = 1 foreach keys %$j;
102 push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}, $attrs->{seen_join}));
105 $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
106 $attrs->{order_by} = [ $attrs->{order_by} ] if !ref($attrs->{order_by});
107 $attrs->{order_by} ||= [];
109 my $collapse = $attrs->{collapse} || {};
110 if (my $prefetch = delete $attrs->{prefetch}) {
112 foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
113 if ( ref $p eq 'HASH' ) {
114 foreach my $key (keys %$p) {
115 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
119 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
122 my @prefetch = $source->resolve_prefetch(
123 $p, $attrs->{alias}, {}, \@pre_order, $collapse);
124 push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
125 push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
127 push(@{$attrs->{order_by}}, @pre_order);
129 $attrs->{collapse} = $collapse;
130 # use Data::Dumper; warn Dumper($collapse) if keys %{$collapse};
132 if ($attrs->{page}) {
133 $attrs->{rows} ||= 10;
134 $attrs->{offset} ||= 0;
135 $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
139 result_source => $source,
140 result_class => $attrs->{result_class} || $source->result_class,
141 cond => $attrs->{where},
142 from => $attrs->{from},
143 collapse => $collapse,
145 page => delete $attrs->{page},
153 my @obj = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
154 my $new_rs = $rs->search({ foo => 3 });
156 If you need to pass in additional attributes but no additional condition,
157 call it as C<search(undef, \%attrs);>.
159 # "SELECT foo, bar FROM $class_table"
160 my @all = $class->search(undef, { columns => [qw/foo bar/] });
170 my $attrs = { %{$self->{attrs}} };
171 my $having = delete $attrs->{having};
172 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
173 $attrs = { %$attrs, %{ pop(@_) } };
177 ? ((@_ == 1 || ref $_[0] eq "HASH")
180 ? $self->throw_exception(
181 "Odd number of arguments to search")
184 if (defined $where) {
185 $where = (defined $attrs->{where}
187 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
188 $where, $attrs->{where} ] }
190 $attrs->{where} = $where;
193 if (defined $having) {
194 $having = (defined $attrs->{having}
196 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
197 $having, $attrs->{having} ] }
199 $attrs->{having} = $having;
202 $rs = (ref $self)->new($self->result_source, $attrs);
208 return (wantarray ? $rs->all : $rs);
211 =head2 search_literal
213 my @obj = $rs->search_literal($literal_where_cond, @bind);
214 my $new_rs = $rs->search_literal($literal_where_cond, @bind);
216 Pass a literal chunk of SQL to be added to the conditional part of the
222 my ($self, $cond, @vals) = @_;
223 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
224 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
225 return $self->search(\$cond, $attrs);
230 =head3 Arguments: (@colvalues) | (\%cols, \%attrs?)
232 Finds a row based on its primary key or unique constraint. For example:
234 my $cd = $schema->resultset('CD')->find(5);
236 Also takes an optional C<key> attribute, to search by a specific key or unique
237 constraint. For example:
239 my $cd = $schema->resultset('CD')->find(
241 artist => 'Massive Attack',
242 title => 'Mezzanine',
244 { key => 'artist_title' }
247 See also L</find_or_create> and L</update_or_create>.
252 my ($self, @vals) = @_;
253 my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
255 my @cols = $self->result_source->primary_columns;
256 if (exists $attrs->{key}) {
257 my %uniq = $self->result_source->unique_constraints;
258 $self->( "Unknown key " . $attrs->{key} . " on " . $self->name )
259 unless exists $uniq{$attrs->{key}};
260 @cols = @{ $uniq{$attrs->{key}} };
262 #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
263 $self->throw_exception( "Can't find unless a primary key or unique constraint is defined" )
267 if (ref $vals[0] eq 'HASH') {
268 $query = { %{$vals[0]} };
269 } elsif (@cols == @vals) {
271 @{$query}{@cols} = @vals;
275 foreach (keys %$query) {
277 $query->{$self->{attrs}{alias}.'.'.$_} = delete $query->{$_};
279 #warn Dumper($query);
282 my $rs = $self->search($query,$attrs);
283 return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
285 return keys %{$self->{collapse}} ? $self->search($query)->next : $self->single($query);
289 =head2 search_related
291 $rs->search_related('relname', $cond?, $attrs?);
293 Search the specified relationship. Optionally specify a condition for matching
299 return shift->related_resultset(shift)->search(@_);
304 Returns a storage-driven cursor to the given resultset.
310 my ($attrs) = $self->{attrs};
311 $attrs = { %$attrs };
312 return $self->{cursor}
313 ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
314 $attrs->{where},$attrs);
319 Inflates the first result without creating a cursor
324 my ($self, $extra) = @_;
325 my ($attrs) = $self->{attrs};
326 $attrs = { %$attrs };
328 if (defined $attrs->{where}) {
331 => [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
332 delete $attrs->{where}, $extra ]
335 $attrs->{where} = $extra;
338 my @data = $self->result_source->storage->select_single(
339 $self->{from}, $attrs->{select},
340 $attrs->{where},$attrs);
341 return (@data ? $self->_construct_object(@data) : ());
347 Perform a search, but use C<LIKE> instead of equality as the condition. Note
348 that this is simply a convenience method; you most likely want to use
349 L</search> with specific operators.
351 For more information, see L<DBIx::Class::Manual::Cookbook>.
358 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
361 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
362 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
363 return $class->search($query, { %$attrs });
368 =head3 Arguments: ($first, $last)
370 Returns a subset of elements from the resultset.
375 my ($self, $min, $max) = @_;
376 my $attrs = { %{ $self->{attrs} || {} } };
377 $attrs->{offset} ||= 0;
378 $attrs->{offset} += $min;
379 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
380 my $slice = (ref $self)->new($self->result_source, $attrs);
381 return (wantarray ? $slice->all : $slice);
386 Returns the next element in the resultset (C<undef> is there is none).
388 Can be used to efficiently iterate over records in the resultset:
390 my $rs = $schema->resultset('CD')->search;
391 while (my $cd = $rs->next) {
400 if( @{$cache = $self->{all_cache} || []}) {
401 $self->{all_cache_position} ||= 0;
402 my $obj = $cache->[$self->{all_cache_position}];
403 $self->{all_cache_position}++;
406 if ($self->{attrs}{cache}) {
407 $self->{all_cache_position} = 1;
408 return ($self->all)[0];
410 my @row = (exists $self->{stashed_row}
411 ? @{delete $self->{stashed_row}}
412 : $self->cursor->next);
413 # warn Dumper(\@row); use Data::Dumper;
414 return unless (@row);
415 return $self->_construct_object(@row);
418 sub _construct_object {
419 my ($self, @row) = @_;
420 my @as = @{ $self->{attrs}{as} };
422 my $info = $self->_collapse_result(\@as, \@row);
424 my $new = $self->result_class->inflate_result($self->result_source, @$info);
426 $new = $self->{attrs}{record_filter}->($new)
427 if exists $self->{attrs}{record_filter};
432 sub _collapse_result {
433 my ($self, $as, $row, $prefix) = @_;
438 foreach my $this_as (@$as) {
439 my $val = shift @copy;
440 if (defined $prefix) {
441 if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
443 $remain =~ /^(?:(.*)\.)?([^\.]+)$/;
444 $const{$1||''}{$2} = $val;
447 $this_as =~ /^(?:(.*)\.)?([^\.]+)$/;
448 $const{$1||''}{$2} = $val;
452 my $info = [ {}, {} ];
453 foreach my $key (keys %const) {
456 my @parts = split(/\./, $key);
457 foreach my $p (@parts) {
458 $target = $target->[1]->{$p} ||= [];
460 $target->[0] = $const{$key};
462 $info->[0] = $const{$key};
466 my @collapse = (defined($prefix)
467 ? (map { (m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()); }
468 keys %{$self->{collapse}})
469 : keys %{$self->{collapse}});
471 my ($c) = sort { length $a <=> length $b } @collapse;
473 foreach my $p (split(/\./, $c)) {
474 $target = $target->[1]->{$p} ||= [];
476 my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
477 my @co_key = @{$self->{collapse}{$c_prefix}};
478 my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
479 my $tree = $self->_collapse_result($as, $row, $c_prefix);
482 !defined($tree->[0]->{$_})
483 || $co_check{$_} ne $tree->[0]->{$_}
486 last unless (@raw = $self->cursor->next);
487 $row = $self->{stashed_row} = \@raw;
488 $tree = $self->_collapse_result($as, $row, $c_prefix);
489 #warn Data::Dumper::Dumper($tree, $row);
499 Returns a reference to the result source for this recordset.
506 Performs an SQL C<COUNT> with the same query as the resultset was built
507 with to find the number of elements. If passed arguments, does a search
508 on the resultset and counts the results of that.
510 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
511 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
512 not support C<DISTINCT> with multiple columns. If you are using such a
513 database, you should only use columns from the main table in your C<group_by>
520 return $self->search(@_)->count if @_ && defined $_[0];
521 unless (defined $self->{count}) {
522 return scalar @{ $self->get_cache }
523 if @{ $self->get_cache };
525 my $select = { 'count' => '*' };
526 my $attrs = { %{ $self->{attrs} } };
527 if( $group_by = delete $attrs->{group_by} ) {
528 delete $attrs->{having};
529 my @distinct = (ref $group_by ? @$group_by : ($group_by));
530 # todo: try CONCAT for multi-column pk
531 my @pk = $self->result_source->primary_columns;
532 if( scalar(@pk) == 1 ) {
534 my $alias = $attrs->{alias};
535 my $re = qr/^($alias\.)?$pk$/;
536 foreach my $column ( @distinct) {
537 if( $column =~ $re ) {
538 @distinct = ( $column );
544 $select = { count => { 'distinct' => \@distinct } };
545 #use Data::Dumper; die Dumper $select;
548 $attrs->{select} = $select;
549 $attrs->{as} = [ 'count' ];
550 # offset, order by and page are not needed to count. record_filter is cdbi
551 delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
553 ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
555 return 0 unless $self->{count};
556 my $count = $self->{count};
557 $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
558 $count = $self->{attrs}{rows} if
559 ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
565 Calls L</search_literal> with the passed arguments, then L</count>.
569 sub count_literal { shift->search_literal(@_)->count; }
573 Returns all elements in the resultset. Called implictly if the resultset
574 is returned in list context.
580 return @{ $self->get_cache }
581 if @{ $self->get_cache };
585 if (keys %{$self->{collapse}}) {
586 # Using $self->cursor->all is really just an optimisation.
587 # If we're collapsing has_many prefetches it probably makes
588 # very little difference, and this is cleaner than hacking
589 # _construct_object to survive the approach
591 $self->cursor->reset;
592 while (@row = $self->cursor->next) {
593 push(@obj, $self->_construct_object(@row));
596 @obj = map { $self->_construct_object(@$_); }
600 if( $self->{attrs}->{cache} ) {
601 $self->set_cache( \@obj );
609 Resets the resultset's cursor, so you can iterate through the elements again.
615 $self->{all_cache_position} = 0;
616 $self->cursor->reset;
622 Resets the resultset and returns the first element.
627 return $_[0]->reset->next;
632 =head3 Arguments: (\%values)
634 Sets the specified columns in the resultset to the supplied values.
639 my ($self, $values) = @_;
640 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
641 return $self->result_source->storage->update(
642 $self->result_source->from, $values, $self->{cond});
647 =head3 Arguments: (\%values)
649 Fetches all objects and updates them one at a time. Note that C<update_all>
650 will run cascade triggers while L</update> will not.
655 my ($self, $values) = @_;
656 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
657 foreach my $obj ($self->all) {
658 $obj->set_columns($values)->update;
665 Deletes the contents of the resultset from its result source.
672 $self->throw_exception("Can't delete on resultset with condition unless hash or array")
673 unless (ref($self->{cond}) eq 'HASH' || ref($self->{cond}) eq 'ARRAY');
674 if (ref $self->{cond} eq 'ARRAY') {
675 $del = [ map { my %hash;
676 foreach my $key (keys %{$_}) {
678 $hash{$1} = $_->{$key};
679 }; \%hash; } @{$self->{cond}} ];
680 } elsif ((keys %{$self->{cond}})[0] eq '-and') {
681 $del->{-and} = [ map { my %hash;
682 foreach my $key (keys %{$_}) {
684 $hash{$1} = $_->{$key};
685 }; \%hash; } @{$self->{cond}{-and}} ];
687 foreach my $key (keys %{$self->{cond}}) {
689 $del->{$1} = $self->{cond}{$key};
692 $self->result_source->storage->delete($self->result_source->from, $del);
698 Fetches all objects and deletes them one at a time. Note that C<delete_all>
699 will run cascade triggers while L</delete> will not.
705 $_->delete for $self->all;
711 Returns a L<Data::Page> object for the current resultset. Only makes
712 sense for queries with a C<page> attribute.
718 my $attrs = $self->{attrs};
719 $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
720 $attrs->{rows} ||= 10;
722 return $self->{pager} ||= Data::Page->new(
723 $self->{count}, $attrs->{rows}, $self->{page});
728 =head3 Arguments: ($page_num)
730 Returns a new resultset for the specified page.
735 my ($self, $page) = @_;
736 my $attrs = { %{$self->{attrs}} };
737 $attrs->{page} = $page;
738 return (ref $self)->new($self->result_source, $attrs);
743 =head3 Arguments: (\%vals)
745 Creates a result in the resultset's result class.
750 my ($self, $values) = @_;
751 $self->throw_exception( "new_result needs a hash" )
752 unless (ref $values eq 'HASH');
753 $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
754 if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
756 my $alias = $self->{attrs}{alias};
757 foreach my $key (keys %{$self->{cond}||{}}) {
758 $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
760 my $obj = $self->result_class->new(\%new);
761 $obj->result_source($self->result_source) if $obj->can('result_source');
767 =head3 Arguments: (\%vals)
769 Inserts a record into the resultset and returns the object.
771 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
776 my ($self, $attrs) = @_;
777 $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
778 return $self->new_result($attrs)->insert;
781 =head2 find_or_create
783 =head3 Arguments: (\%vals, \%attrs?)
785 $class->find_or_create({ key => $val, ... });
787 Searches for a record matching the search condition; if it doesn't find one,
788 creates one and returns that instead.
790 my $cd = $schema->resultset('CD')->find_or_create({
792 artist => 'Massive Attack',
793 title => 'Mezzanine',
797 Also takes an optional C<key> attribute, to search by a specific key or unique
798 constraint. For example:
800 my $cd = $schema->resultset('CD')->find_or_create(
802 artist => 'Massive Attack',
803 title => 'Mezzanine',
805 { key => 'artist_title' }
808 See also L</find> and L</update_or_create>.
814 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
815 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
816 my $exists = $self->find($hash, $attrs);
817 return defined($exists) ? $exists : $self->create($hash);
820 =head2 update_or_create
822 $class->update_or_create({ key => $val, ... });
824 First, search for an existing row matching one of the unique constraints
825 (including the primary key) on the source of this resultset. If a row is
826 found, update it with the other given column values. Otherwise, create a new
829 Takes an optional C<key> attribute to search on a specific unique constraint.
832 # In your application
833 my $cd = $schema->resultset('CD')->update_or_create(
835 artist => 'Massive Attack',
836 title => 'Mezzanine',
839 { key => 'artist_title' }
842 If no C<key> is specified, it searches on all unique constraints defined on the
843 source, including the primary key.
845 If the C<key> is specified as C<primary>, search only on the primary key.
847 See also L</find> and L</find_or_create>.
851 sub update_or_create {
854 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
855 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
857 my %unique_constraints = $self->result_source->unique_constraints;
858 my @constraint_names = (exists $attrs->{key}
860 : keys %unique_constraints);
863 foreach my $name (@constraint_names) {
864 my @unique_cols = @{ $unique_constraints{$name} };
866 map { $_ => $hash->{$_} }
867 grep { exists $hash->{$_} }
870 push @unique_hashes, \%unique_hash
871 if (scalar keys %unique_hash == scalar @unique_cols);
875 if (@unique_hashes) {
876 $row = $self->search(\@unique_hashes, { rows => 1 })->first;
878 $row->set_columns($hash);
884 $row = $self->create($hash);
892 Gets the contents of the cache for the resultset.
898 return $self->{all_cache} || [];
903 Sets the contents of the cache for the resultset. Expects an arrayref of objects of the same class as those produced by the resultset.
908 my ( $self, $data ) = @_;
909 $self->throw_exception("set_cache requires an arrayref")
910 if ref $data ne 'ARRAY';
911 my $result_class = $self->result_class;
913 $self->throw_exception("cannot cache object of type '$_', expected '$result_class'")
914 if ref $_ ne $result_class;
916 $self->{all_cache} = $data;
921 Clears the cache for the resultset.
927 $self->set_cache([]);
930 =head2 related_resultset
932 Returns a related resultset for the supplied relationship name.
934 $rs = $rs->related_resultset('foo');
938 sub related_resultset {
939 my ( $self, $rel, @rest ) = @_;
940 $self->{related_resultsets} ||= {};
941 my $resultsets = $self->{related_resultsets};
942 if( !exists $resultsets->{$rel} ) {
943 #warn "fetching related resultset for rel '$rel'";
944 my $rel_obj = $self->result_source->relationship_info($rel);
945 $self->throw_exception(
946 "search_related: result source '" . $self->result_source->name .
947 "' has no such relationship ${rel}")
948 unless $rel_obj; #die Dumper $self->{attrs};
949 my $rs = $self->search(undef, { join => $rel });
950 #if( $self->{attrs}->{cache} ) {
951 # $rs = $self->search(undef);
955 #use Data::Dumper; die Dumper $rs->{attrs};#$rs = $self->search( undef );
956 #use Data::Dumper; warn Dumper $self->{attrs}, Dumper $rs->{attrs};
957 my $alias = (defined $rs->{attrs}{seen_join}{$rel}
958 && $rs->{attrs}{seen_join}{$rel} > 1
959 ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
961 $resultsets->{$rel} =
962 $self->result_source->schema->resultset($rel_obj->{class}
970 return $resultsets->{$rel};
973 =head2 throw_exception
975 See Schema's throw_exception
979 sub throw_exception {
981 $self->result_source->schema->throw_exception(@_);
986 The resultset takes various attributes that modify its behavior. Here's an
991 Which column(s) to order the results by. This is currently passed through
992 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
996 =head3 Arguments: (arrayref)
998 Shortcut to request a particular set of columns to be retrieved. Adds
999 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1000 from that, then auto-populates C<as> from C<select> as normal. (You may also
1001 use the C<cols> attribute, as in earlier versions of DBIC.)
1003 =head2 include_columns
1005 =head3 Arguments: (arrayref)
1007 Shortcut to include additional columns in the returned results - for example
1009 { include_columns => ['foo.name'], join => ['foo'] }
1011 would add a 'name' column to the information passed to object inflation
1015 =head3 Arguments: (arrayref)
1017 Indicates which columns should be selected from the storage. You can use
1018 column names, or in the case of RDBMS back ends, function or stored procedure
1021 $rs = $schema->resultset('Foo')->search(
1026 { count => 'column_to_count' },
1027 { sum => 'column_to_sum' }
1032 When you use function/stored procedure names and do not supply an C<as>
1033 attribute, the column names returned are storage-dependent. E.g. MySQL would
1034 return a column named C<count(column_to_count)> in the above example.
1038 =head3 Arguments: (arrayref)
1040 Indicates column names for object inflation. This is used in conjunction with
1041 C<select>, usually when C<select> contains one or more function or stored
1044 $rs = $schema->resultset('Foo')->search(
1049 { count => 'column2' }
1051 as => [qw/ column1 column2_count /]
1055 my $foo = $rs->first(); # get the first Foo
1057 If the object against which the search is performed already has an accessor
1058 matching a column name specified in C<as>, the value can be retrieved using
1059 the accessor as normal:
1061 my $column1 = $foo->column1();
1063 If on the other hand an accessor does not exist in the object, you need to
1064 use C<get_column> instead:
1066 my $column2_count = $foo->get_column('column2_count');
1068 You can create your own accessors if required - see
1069 L<DBIx::Class::Manual::Cookbook> for details.
1073 Contains a list of relationships that should be joined for this query. For
1076 # Get CDs by Nine Inch Nails
1077 my $rs = $schema->resultset('CD')->search(
1078 { 'artist.name' => 'Nine Inch Nails' },
1079 { join => 'artist' }
1082 Can also contain a hash reference to refer to the other relation's relations.
1085 package MyApp::Schema::Track;
1086 use base qw/DBIx::Class/;
1087 __PACKAGE__->table('track');
1088 __PACKAGE__->add_columns(qw/trackid cd position title/);
1089 __PACKAGE__->set_primary_key('trackid');
1090 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1093 # In your application
1094 my $rs = $schema->resultset('Artist')->search(
1095 { 'track.title' => 'Teardrop' },
1097 join => { cd => 'track' },
1098 order_by => 'artist.name',
1102 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1103 similarly for a third time). For e.g.
1105 my $rs = $schema->resultset('Artist')->search(
1106 { 'cds.title' => 'Foo',
1107 'cds_2.title' => 'Bar' },
1108 { join => [ qw/cds cds/ ] });
1110 will return a set of all artists that have both a cd with title Foo and a cd
1113 If you want to fetch related objects from other tables as well, see C<prefetch>
1118 =head3 Arguments: arrayref/hashref
1120 Contains one or more relationships that should be fetched along with the main
1121 query (when they are accessed afterwards they will have already been
1122 "prefetched"). This is useful for when you know you will need the related
1123 objects, because it saves at least one query:
1125 my $rs = $schema->resultset('Tag')->search(
1134 The initial search results in SQL like the following:
1136 SELECT tag.*, cd.*, artist.* FROM tag
1137 JOIN cd ON tag.cd = cd.cdid
1138 JOIN artist ON cd.artist = artist.artistid
1140 L<DBIx::Class> has no need to go back to the database when we access the
1141 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1144 Simple prefetches will be joined automatically, so there is no need
1145 for a C<join> attribute in the above search. If you're prefetching to
1146 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1147 specify the join as well.
1149 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1150 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1151 with an accessor type of 'single' or 'filter').
1155 =head3 Arguments: (arrayref)
1157 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1158 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1161 NOTE: Use this on your own risk. This allows you to shoot off your foot!
1162 C<join> will usually do what you need and it is strongly recommended that you
1163 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1165 In simple terms, C<from> works as follows:
1168 { <alias> => <table>, -join-type => 'inner|left|right' }
1169 [] # nested JOIN (optional)
1170 { <table.column> = <foreign_table.foreign_key> }
1176 ON <table.column> = <foreign_table.foreign_key>
1178 An easy way to follow the examples below is to remember the following:
1180 Anything inside "[]" is a JOIN
1181 Anything inside "{}" is a condition for the enclosing JOIN
1183 The following examples utilize a "person" table in a family tree application.
1184 In order to express parent->child relationships, this table is self-joined:
1186 # Person->belongs_to('father' => 'Person');
1187 # Person->belongs_to('mother' => 'Person');
1189 C<from> can be used to nest joins. Here we return all children with a father,
1190 then search against all mothers of those children:
1192 $rs = $schema->resultset('Person')->search(
1195 alias => 'mother', # alias columns in accordance with "from"
1197 { mother => 'person' },
1200 { child => 'person' },
1202 { father => 'person' },
1203 { 'father.person_id' => 'child.father_id' }
1206 { 'mother.person_id' => 'child.mother_id' }
1213 # SELECT mother.* FROM person mother
1216 # JOIN person father
1217 # ON ( father.person_id = child.father_id )
1219 # ON ( mother.person_id = child.mother_id )
1221 The type of any join can be controlled manually. To search against only people
1222 with a father in the person table, we could explicitly use C<INNER JOIN>:
1224 $rs = $schema->resultset('Person')->search(
1227 alias => 'child', # alias columns in accordance with "from"
1229 { child => 'person' },
1231 { father => 'person', -join-type => 'inner' },
1232 { 'father.id' => 'child.father_id' }
1239 # SELECT child.* FROM person child
1240 # INNER JOIN person father ON child.father_id = father.id
1244 For a paged resultset, specifies which page to retrieve. Leave unset
1245 for an unpaged resultset.
1249 For a paged resultset, how many rows per page:
1253 Can also be used to simulate an SQL C<LIMIT>.
1257 =head3 Arguments: (arrayref)
1259 A arrayref of columns to group by. Can include columns of joined tables.
1261 group_by => [qw/ column1 column2 ... /]
1265 Set to 1 to group by all columns.
1267 For more examples of using these attributes, see
1268 L<DBIx::Class::Manual::Cookbook>.