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 delete $attrs->{as} if $attrs->{columns};
80 $attrs->{columns} ||= [ $source->columns ] unless $attrs->{select};
81 $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @{delete $attrs->{columns}} ]
83 $attrs->{as} ||= [ map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}} ];
84 if (my $include = delete $attrs->{include_columns}) {
85 push(@{$attrs->{select}}, @$include);
86 push(@{$attrs->{as}}, map { m/([^\.]+)$/; $1; } @$include);
88 #use Data::Dumper; warn Dumper(@{$attrs}{qw/select as/});
90 $attrs->{from} ||= [ { $alias => $source->from } ];
91 $attrs->{seen_join} ||= {};
93 if (my $join = delete $attrs->{join}) {
94 foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
95 if (ref $j eq 'HASH') {
96 $seen{$_} = 1 foreach keys %$j;
101 push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}, $attrs->{seen_join}));
104 $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
105 $attrs->{order_by} = [ $attrs->{order_by} ] if $attrs->{order_by} and !ref($attrs->{order_by});
106 $attrs->{order_by} ||= [];
108 my $collapse = $attrs->{collapse} || {};
109 if (my $prefetch = delete $attrs->{prefetch}) {
111 foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
112 if ( ref $p eq 'HASH' ) {
113 foreach my $key (keys %$p) {
114 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
118 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
121 my @prefetch = $source->resolve_prefetch(
122 $p, $attrs->{alias}, {}, \@pre_order, $collapse);
123 push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
124 push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
126 push(@{$attrs->{order_by}}, @pre_order);
128 $attrs->{collapse} = $collapse;
129 # use Data::Dumper; warn Dumper($collapse) if keys %{$collapse};
131 if ($attrs->{page}) {
132 $attrs->{rows} ||= 10;
133 $attrs->{offset} ||= 0;
134 $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
138 result_source => $source,
139 result_class => $attrs->{result_class} || $source->result_class,
140 cond => $attrs->{where},
141 from => $attrs->{from},
142 collapse => $collapse,
144 page => delete $attrs->{page},
152 my @obj = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
153 my $new_rs = $rs->search({ foo => 3 });
155 If you need to pass in additional attributes but no additional condition,
156 call it as C<search(undef, \%attrs);>.
158 # "SELECT foo, bar FROM $class_table"
159 my @all = $class->search(undef, { columns => [qw/foo bar/] });
169 my $attrs = { %{$self->{attrs}} };
170 my $having = delete $attrs->{having};
171 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
172 $attrs = { %$attrs, %{ pop(@_) } };
176 ? ((@_ == 1 || ref $_[0] eq "HASH")
179 ? $self->throw_exception(
180 "Odd number of arguments to search")
183 if (defined $where) {
184 $where = (defined $attrs->{where}
186 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
187 $where, $attrs->{where} ] }
189 $attrs->{where} = $where;
192 if (defined $having) {
193 $having = (defined $attrs->{having}
195 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
196 $having, $attrs->{having} ] }
198 $attrs->{having} = $having;
201 $rs = (ref $self)->new($self->result_source, $attrs);
207 return (wantarray ? $rs->all : $rs);
210 =head2 search_literal
212 my @obj = $rs->search_literal($literal_where_cond, @bind);
213 my $new_rs = $rs->search_literal($literal_where_cond, @bind);
215 Pass a literal chunk of SQL to be added to the conditional part of the
221 my ($self, $cond, @vals) = @_;
222 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
223 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
224 return $self->search(\$cond, $attrs);
229 =head3 Arguments: (@colvalues) | (\%cols, \%attrs?)
231 Finds a row based on its primary key or unique constraint. For example:
233 my $cd = $schema->resultset('CD')->find(5);
235 Also takes an optional C<key> attribute, to search by a specific key or unique
236 constraint. For example:
238 my $cd = $schema->resultset('CD')->find(
240 artist => 'Massive Attack',
241 title => 'Mezzanine',
243 { key => 'artist_title' }
246 See also L</find_or_create> and L</update_or_create>.
251 my ($self, @vals) = @_;
252 my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
254 my @cols = $self->result_source->primary_columns;
255 if (exists $attrs->{key}) {
256 my %uniq = $self->result_source->unique_constraints;
257 $self->( "Unknown key " . $attrs->{key} . " on " . $self->name )
258 unless exists $uniq{$attrs->{key}};
259 @cols = @{ $uniq{$attrs->{key}} };
261 #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
262 $self->throw_exception( "Can't find unless a primary key or unique constraint is defined" )
266 if (ref $vals[0] eq 'HASH') {
267 $query = { %{$vals[0]} };
268 } elsif (@cols == @vals) {
270 @{$query}{@cols} = @vals;
274 foreach (keys %$query) {
276 $query->{$self->{attrs}{alias}.'.'.$_} = delete $query->{$_};
278 #warn Dumper($query);
281 my $rs = $self->search($query,$attrs);
282 return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
284 return keys %{$self->{collapse}} ? $self->search($query)->next : $self->single($query);
288 =head2 search_related
290 $rs->search_related('relname', $cond?, $attrs?);
292 Search the specified relationship. Optionally specify a condition for matching
298 return shift->related_resultset(shift)->search(@_);
303 Returns a storage-driven cursor to the given resultset.
309 my ($attrs) = $self->{attrs};
310 $attrs = { %$attrs };
311 return $self->{cursor}
312 ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
313 $attrs->{where},$attrs);
318 Inflates the first result without creating a cursor
323 my ($self, $extra) = @_;
324 my ($attrs) = $self->{attrs};
325 $attrs = { %$attrs };
327 if (defined $attrs->{where}) {
330 => [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
331 delete $attrs->{where}, $extra ]
334 $attrs->{where} = $extra;
337 my @data = $self->result_source->storage->select_single(
338 $self->{from}, $attrs->{select},
339 $attrs->{where},$attrs);
340 return (@data ? $self->_construct_object(@data) : ());
346 Perform a search, but use C<LIKE> instead of equality as the condition. Note
347 that this is simply a convenience method; you most likely want to use
348 L</search> with specific operators.
350 For more information, see L<DBIx::Class::Manual::Cookbook>.
357 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
360 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
361 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
362 return $class->search($query, { %$attrs });
367 =head3 Arguments: ($first, $last)
369 Returns a subset of elements from the resultset.
374 my ($self, $min, $max) = @_;
375 my $attrs = { %{ $self->{attrs} || {} } };
376 $attrs->{offset} ||= 0;
377 $attrs->{offset} += $min;
378 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
379 my $slice = (ref $self)->new($self->result_source, $attrs);
380 return (wantarray ? $slice->all : $slice);
385 Returns the next element in the resultset (C<undef> is there is none).
387 Can be used to efficiently iterate over records in the resultset:
389 my $rs = $schema->resultset('CD')->search;
390 while (my $cd = $rs->next) {
399 if( @{$cache = $self->{all_cache} || []}) {
400 $self->{all_cache_position} ||= 0;
401 my $obj = $cache->[$self->{all_cache_position}];
402 $self->{all_cache_position}++;
405 if ($self->{attrs}{cache}) {
406 $self->{all_cache_position} = 1;
407 return ($self->all)[0];
409 my @row = (exists $self->{stashed_row}
410 ? @{delete $self->{stashed_row}}
411 : $self->cursor->next);
412 # warn Dumper(\@row); use Data::Dumper;
413 return unless (@row);
414 return $self->_construct_object(@row);
417 sub _construct_object {
418 my ($self, @row) = @_;
419 my @as = @{ $self->{attrs}{as} };
421 my $info = $self->_collapse_result(\@as, \@row);
423 my $new = $self->result_class->inflate_result($self->result_source, @$info);
425 $new = $self->{attrs}{record_filter}->($new)
426 if exists $self->{attrs}{record_filter};
431 sub _collapse_result {
432 my ($self, $as, $row, $prefix) = @_;
437 foreach my $this_as (@$as) {
438 my $val = shift @copy;
439 if (defined $prefix) {
440 if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
442 $remain =~ /^(?:(.*)\.)?([^\.]+)$/;
443 $const{$1||''}{$2} = $val;
446 $this_as =~ /^(?:(.*)\.)?([^\.]+)$/;
447 $const{$1||''}{$2} = $val;
451 my $info = [ {}, {} ];
452 foreach my $key (keys %const) {
455 my @parts = split(/\./, $key);
456 foreach my $p (@parts) {
457 $target = $target->[1]->{$p} ||= [];
459 $target->[0] = $const{$key};
461 $info->[0] = $const{$key};
465 my @collapse = (defined($prefix)
466 ? (map { (m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()); }
467 keys %{$self->{collapse}})
468 : keys %{$self->{collapse}});
470 my ($c) = sort { length $a <=> length $b } @collapse;
472 foreach my $p (split(/\./, $c)) {
473 $target = $target->[1]->{$p} ||= [];
475 my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
476 my @co_key = @{$self->{collapse}{$c_prefix}};
477 my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
478 my $tree = $self->_collapse_result($as, $row, $c_prefix);
481 !defined($tree->[0]->{$_})
482 || $co_check{$_} ne $tree->[0]->{$_}
485 last unless (@raw = $self->cursor->next);
486 $row = $self->{stashed_row} = \@raw;
487 $tree = $self->_collapse_result($as, $row, $c_prefix);
488 #warn Data::Dumper::Dumper($tree, $row);
498 Returns a reference to the result source for this recordset.
505 Performs an SQL C<COUNT> with the same query as the resultset was built
506 with to find the number of elements. If passed arguments, does a search
507 on the resultset and counts the results of that.
509 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
510 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
511 not support C<DISTINCT> with multiple columns. If you are using such a
512 database, you should only use columns from the main table in your C<group_by>
519 return $self->search(@_)->count if @_ && defined $_[0];
520 unless (defined $self->{count}) {
521 return scalar @{ $self->get_cache }
522 if @{ $self->get_cache };
524 my $select = { 'count' => '*' };
525 my $attrs = { %{ $self->{attrs} } };
526 if( $group_by = delete $attrs->{group_by} ) {
527 delete $attrs->{having};
528 my @distinct = (ref $group_by ? @$group_by : ($group_by));
529 # todo: try CONCAT for multi-column pk
530 my @pk = $self->result_source->primary_columns;
531 if( scalar(@pk) == 1 ) {
533 my $alias = $attrs->{alias};
534 my $re = qr/^($alias\.)?$pk$/;
535 foreach my $column ( @distinct) {
536 if( $column =~ $re ) {
537 @distinct = ( $column );
543 $select = { count => { 'distinct' => \@distinct } };
544 #use Data::Dumper; die Dumper $select;
547 $attrs->{select} = $select;
548 $attrs->{as} = [ 'count' ];
549 # offset, order by and page are not needed to count. record_filter is cdbi
550 delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
552 ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
554 return 0 unless $self->{count};
555 my $count = $self->{count};
556 $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
557 $count = $self->{attrs}{rows} if
558 ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
564 Calls L</search_literal> with the passed arguments, then L</count>.
568 sub count_literal { shift->search_literal(@_)->count; }
572 Returns all elements in the resultset. Called implictly if the resultset
573 is returned in list context.
579 return @{ $self->get_cache }
580 if @{ $self->get_cache };
584 if (keys %{$self->{collapse}}) {
585 # Using $self->cursor->all is really just an optimisation.
586 # If we're collapsing has_many prefetches it probably makes
587 # very little difference, and this is cleaner than hacking
588 # _construct_object to survive the approach
590 $self->cursor->reset;
591 while (@row = $self->cursor->next) {
592 push(@obj, $self->_construct_object(@row));
595 @obj = map { $self->_construct_object(@$_); }
599 if( $self->{attrs}->{cache} ) {
600 $self->set_cache( \@obj );
608 Resets the resultset's cursor, so you can iterate through the elements again.
614 $self->{all_cache_position} = 0;
615 $self->cursor->reset;
621 Resets the resultset and returns the first element.
626 return $_[0]->reset->next;
631 =head3 Arguments: (\%values)
633 Sets the specified columns in the resultset to the supplied values.
638 my ($self, $values) = @_;
639 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
640 return $self->result_source->storage->update(
641 $self->result_source->from, $values, $self->{cond});
646 =head3 Arguments: (\%values)
648 Fetches all objects and updates them one at a time. Note that C<update_all>
649 will run cascade triggers while L</update> will not.
654 my ($self, $values) = @_;
655 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
656 foreach my $obj ($self->all) {
657 $obj->set_columns($values)->update;
664 Deletes the contents of the resultset from its result source.
671 $self->throw_exception("Can't delete on resultset with condition unless hash or array")
672 unless (ref($self->{cond}) eq 'HASH' || ref($self->{cond}) eq 'ARRAY');
673 if (ref $self->{cond} eq 'ARRAY') {
674 $del = [ map { my %hash;
675 foreach my $key (keys %{$_}) {
677 $hash{$1} = $_->{$key};
678 }; \%hash; } @{$self->{cond}} ];
679 } elsif ((keys %{$self->{cond}})[0] eq '-and') {
680 $del->{-and} = [ map { my %hash;
681 foreach my $key (keys %{$_}) {
683 $hash{$1} = $_->{$key};
684 }; \%hash; } @{$self->{cond}{-and}} ];
686 foreach my $key (keys %{$self->{cond}}) {
688 $del->{$1} = $self->{cond}{$key};
691 $self->result_source->storage->delete($self->result_source->from, $del);
697 Fetches all objects and deletes them one at a time. Note that C<delete_all>
698 will run cascade triggers while L</delete> will not.
704 $_->delete for $self->all;
710 Returns a L<Data::Page> object for the current resultset. Only makes
711 sense for queries with a C<page> attribute.
717 my $attrs = $self->{attrs};
718 $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
719 $attrs->{rows} ||= 10;
721 return $self->{pager} ||= Data::Page->new(
722 $self->{count}, $attrs->{rows}, $self->{page});
727 =head3 Arguments: ($page_num)
729 Returns a new resultset for the specified page.
734 my ($self, $page) = @_;
735 my $attrs = { %{$self->{attrs}} };
736 $attrs->{page} = $page;
737 return (ref $self)->new($self->result_source, $attrs);
742 =head3 Arguments: (\%vals)
744 Creates a result in the resultset's result class.
749 my ($self, $values) = @_;
750 $self->throw_exception( "new_result needs a hash" )
751 unless (ref $values eq 'HASH');
752 $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
753 if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
755 my $alias = $self->{attrs}{alias};
756 foreach my $key (keys %{$self->{cond}||{}}) {
757 $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
759 my $obj = $self->result_class->new(\%new);
760 $obj->result_source($self->result_source) if $obj->can('result_source');
766 =head3 Arguments: (\%vals)
768 Inserts a record into the resultset and returns the object.
770 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
775 my ($self, $attrs) = @_;
776 $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
777 return $self->new_result($attrs)->insert;
780 =head2 find_or_create
782 =head3 Arguments: (\%vals, \%attrs?)
784 $class->find_or_create({ key => $val, ... });
786 Searches for a record matching the search condition; if it doesn't find one,
787 creates one and returns that instead.
789 my $cd = $schema->resultset('CD')->find_or_create({
791 artist => 'Massive Attack',
792 title => 'Mezzanine',
796 Also takes an optional C<key> attribute, to search by a specific key or unique
797 constraint. For example:
799 my $cd = $schema->resultset('CD')->find_or_create(
801 artist => 'Massive Attack',
802 title => 'Mezzanine',
804 { key => 'artist_title' }
807 See also L</find> and L</update_or_create>.
813 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
814 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
815 my $exists = $self->find($hash, $attrs);
816 return defined($exists) ? $exists : $self->create($hash);
819 =head2 update_or_create
821 $class->update_or_create({ key => $val, ... });
823 First, search for an existing row matching one of the unique constraints
824 (including the primary key) on the source of this resultset. If a row is
825 found, update it with the other given column values. Otherwise, create a new
828 Takes an optional C<key> attribute to search on a specific unique constraint.
831 # In your application
832 my $cd = $schema->resultset('CD')->update_or_create(
834 artist => 'Massive Attack',
835 title => 'Mezzanine',
838 { key => 'artist_title' }
841 If no C<key> is specified, it searches on all unique constraints defined on the
842 source, including the primary key.
844 If the C<key> is specified as C<primary>, search only on the primary key.
846 See also L</find> and L</find_or_create>.
850 sub update_or_create {
853 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
854 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
856 my %unique_constraints = $self->result_source->unique_constraints;
857 my @constraint_names = (exists $attrs->{key}
859 : keys %unique_constraints);
862 foreach my $name (@constraint_names) {
863 my @unique_cols = @{ $unique_constraints{$name} };
865 map { $_ => $hash->{$_} }
866 grep { exists $hash->{$_} }
869 push @unique_hashes, \%unique_hash
870 if (scalar keys %unique_hash == scalar @unique_cols);
874 if (@unique_hashes) {
875 $row = $self->search(\@unique_hashes, { rows => 1 })->first;
877 $row->set_columns($hash);
883 $row = $self->create($hash);
891 Gets the contents of the cache for the resultset.
897 return $self->{all_cache} || [];
902 Sets the contents of the cache for the resultset. Expects an arrayref of objects of the same class as those produced by the resultset.
907 my ( $self, $data ) = @_;
908 $self->throw_exception("set_cache requires an arrayref")
909 if ref $data ne 'ARRAY';
910 my $result_class = $self->result_class;
912 $self->throw_exception("cannot cache object of type '$_', expected '$result_class'")
913 if ref $_ ne $result_class;
915 $self->{all_cache} = $data;
920 Clears the cache for the resultset.
926 $self->set_cache([]);
929 =head2 related_resultset
931 Returns a related resultset for the supplied relationship name.
933 $rs = $rs->related_resultset('foo');
937 sub related_resultset {
938 my ( $self, $rel, @rest ) = @_;
939 $self->{related_resultsets} ||= {};
940 my $resultsets = $self->{related_resultsets};
941 if( !exists $resultsets->{$rel} ) {
942 #warn "fetching related resultset for rel '$rel'";
943 my $rel_obj = $self->result_source->relationship_info($rel);
944 $self->throw_exception(
945 "search_related: result source '" . $self->result_source->name .
946 "' has no such relationship ${rel}")
947 unless $rel_obj; #die Dumper $self->{attrs};
948 my $rs = $self->search(undef, { join => $rel });
949 #if( $self->{attrs}->{cache} ) {
950 # $rs = $self->search(undef);
954 #use Data::Dumper; die Dumper $rs->{attrs};#$rs = $self->search( undef );
955 #use Data::Dumper; warn Dumper $self->{attrs}, Dumper $rs->{attrs};
956 my $alias = (defined $rs->{attrs}{seen_join}{$rel}
957 && $rs->{attrs}{seen_join}{$rel} > 1
958 ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
960 $resultsets->{$rel} =
961 $self->result_source->schema->resultset($rel_obj->{class}
969 return $resultsets->{$rel};
972 =head2 throw_exception
974 See Schema's throw_exception
978 sub throw_exception {
980 $self->result_source->schema->throw_exception(@_);
985 The resultset takes various attributes that modify its behavior. Here's an
990 Which column(s) to order the results by. This is currently passed through
991 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
995 =head3 Arguments: (arrayref)
997 Shortcut to request a particular set of columns to be retrieved. Adds
998 C<me.> onto the start of any column without a C<.> in it and sets C<select>
999 from that, then auto-populates C<as> from C<select> as normal. (You may also
1000 use the C<cols> attribute, as in earlier versions of DBIC.)
1002 =head2 include_columns
1004 =head3 Arguments: (arrayref)
1006 Shortcut to include additional columns in the returned results - for example
1008 { include_columns => ['foo.name'], join => ['foo'] }
1010 would add a 'name' column to the information passed to object inflation
1014 =head3 Arguments: (arrayref)
1016 Indicates which columns should be selected from the storage. You can use
1017 column names, or in the case of RDBMS back ends, function or stored procedure
1020 $rs = $schema->resultset('Foo')->search(
1025 { count => 'column_to_count' },
1026 { sum => 'column_to_sum' }
1031 When you use function/stored procedure names and do not supply an C<as>
1032 attribute, the column names returned are storage-dependent. E.g. MySQL would
1033 return a column named C<count(column_to_count)> in the above example.
1037 =head3 Arguments: (arrayref)
1039 Indicates column names for object inflation. This is used in conjunction with
1040 C<select>, usually when C<select> contains one or more function or stored
1043 $rs = $schema->resultset('Foo')->search(
1048 { count => 'column2' }
1050 as => [qw/ column1 column2_count /]
1054 my $foo = $rs->first(); # get the first Foo
1056 If the object against which the search is performed already has an accessor
1057 matching a column name specified in C<as>, the value can be retrieved using
1058 the accessor as normal:
1060 my $column1 = $foo->column1();
1062 If on the other hand an accessor does not exist in the object, you need to
1063 use C<get_column> instead:
1065 my $column2_count = $foo->get_column('column2_count');
1067 You can create your own accessors if required - see
1068 L<DBIx::Class::Manual::Cookbook> for details.
1072 Contains a list of relationships that should be joined for this query. For
1075 # Get CDs by Nine Inch Nails
1076 my $rs = $schema->resultset('CD')->search(
1077 { 'artist.name' => 'Nine Inch Nails' },
1078 { join => 'artist' }
1081 Can also contain a hash reference to refer to the other relation's relations.
1084 package MyApp::Schema::Track;
1085 use base qw/DBIx::Class/;
1086 __PACKAGE__->table('track');
1087 __PACKAGE__->add_columns(qw/trackid cd position title/);
1088 __PACKAGE__->set_primary_key('trackid');
1089 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1092 # In your application
1093 my $rs = $schema->resultset('Artist')->search(
1094 { 'track.title' => 'Teardrop' },
1096 join => { cd => 'track' },
1097 order_by => 'artist.name',
1101 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1102 similarly for a third time). For e.g.
1104 my $rs = $schema->resultset('Artist')->search(
1105 { 'cds.title' => 'Foo',
1106 'cds_2.title' => 'Bar' },
1107 { join => [ qw/cds cds/ ] });
1109 will return a set of all artists that have both a cd with title Foo and a cd
1112 If you want to fetch related objects from other tables as well, see C<prefetch>
1117 =head3 Arguments: arrayref/hashref
1119 Contains one or more relationships that should be fetched along with the main
1120 query (when they are accessed afterwards they will have already been
1121 "prefetched"). This is useful for when you know you will need the related
1122 objects, because it saves at least one query:
1124 my $rs = $schema->resultset('Tag')->search(
1133 The initial search results in SQL like the following:
1135 SELECT tag.*, cd.*, artist.* FROM tag
1136 JOIN cd ON tag.cd = cd.cdid
1137 JOIN artist ON cd.artist = artist.artistid
1139 L<DBIx::Class> has no need to go back to the database when we access the
1140 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1143 Simple prefetches will be joined automatically, so there is no need
1144 for a C<join> attribute in the above search. If you're prefetching to
1145 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1146 specify the join as well.
1148 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1149 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1150 with an accessor type of 'single' or 'filter').
1154 =head3 Arguments: (arrayref)
1156 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1157 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1160 NOTE: Use this on your own risk. This allows you to shoot off your foot!
1161 C<join> will usually do what you need and it is strongly recommended that you
1162 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1164 In simple terms, C<from> works as follows:
1167 { <alias> => <table>, -join-type => 'inner|left|right' }
1168 [] # nested JOIN (optional)
1169 { <table.column> = <foreign_table.foreign_key> }
1175 ON <table.column> = <foreign_table.foreign_key>
1177 An easy way to follow the examples below is to remember the following:
1179 Anything inside "[]" is a JOIN
1180 Anything inside "{}" is a condition for the enclosing JOIN
1182 The following examples utilize a "person" table in a family tree application.
1183 In order to express parent->child relationships, this table is self-joined:
1185 # Person->belongs_to('father' => 'Person');
1186 # Person->belongs_to('mother' => 'Person');
1188 C<from> can be used to nest joins. Here we return all children with a father,
1189 then search against all mothers of those children:
1191 $rs = $schema->resultset('Person')->search(
1194 alias => 'mother', # alias columns in accordance with "from"
1196 { mother => 'person' },
1199 { child => 'person' },
1201 { father => 'person' },
1202 { 'father.person_id' => 'child.father_id' }
1205 { 'mother.person_id' => 'child.mother_id' }
1212 # SELECT mother.* FROM person mother
1215 # JOIN person father
1216 # ON ( father.person_id = child.father_id )
1218 # ON ( mother.person_id = child.mother_id )
1220 The type of any join can be controlled manually. To search against only people
1221 with a father in the person table, we could explicitly use C<INNER JOIN>:
1223 $rs = $schema->resultset('Person')->search(
1226 alias => 'child', # alias columns in accordance with "from"
1228 { child => 'person' },
1230 { father => 'person', -join-type => 'inner' },
1231 { 'father.id' => 'child.father_id' }
1238 # SELECT child.* FROM person child
1239 # INNER JOIN person father ON child.father_id = father.id
1243 For a paged resultset, specifies which page to retrieve. Leave unset
1244 for an unpaged resultset.
1248 For a paged resultset, how many rows per page:
1252 Can also be used to simulate an SQL C<LIMIT>.
1256 =head3 Arguments: (arrayref)
1258 A arrayref of columns to group by. Can include columns of joined tables.
1260 group_by => [qw/ column1 column2 ... /]
1264 Set to 1 to group by all columns.
1266 For more examples of using these attributes, see
1267 L<DBIx::Class::Manual::Cookbook>.