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;
72 my ($source, $attrs) = @_;
73 #use Data::Dumper; warn Dumper($attrs);
74 $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
76 my $alias = ($attrs->{alias} ||= 'me');
77 if ($attrs->{cols} || !$attrs->{select}) {
78 delete $attrs->{as} if $attrs->{cols};
79 my @cols = ($attrs->{cols}
80 ? @{delete $attrs->{cols}}
82 $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @cols ];
84 $attrs->{as} ||= [ map { m/^$alias\.(.*)$/ ? $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/});
90 $attrs->{from} ||= [ { $alias => $source->from } ];
91 $attrs->{seen_join} ||= {};
92 if (my $join = delete $attrs->{join}) {
93 foreach my $j (ref $join eq 'ARRAY'
94 ? (@{$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}));
103 $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
105 $attrs->{order_by} = [ $attrs->{order_by} ]
106 if $attrs->{order_by} && !ref($attrs->{order_by});
107 $attrs->{order_by} ||= [];
111 if (my $prefetch = delete $attrs->{prefetch}) {
113 foreach my $p (ref $prefetch eq 'ARRAY'
114 ? (@{$prefetch}) : ($prefetch)) {
115 if( ref $p eq 'HASH' ) {
116 foreach my $key (keys %$p) {
117 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
122 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
125 my @prefetch = $source->resolve_prefetch(
126 $p, $attrs->{alias}, {}, \@pre_order, $collapse);
128 push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
129 push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
131 push(@{$attrs->{order_by}}, @pre_order);
134 if ($attrs->{page}) {
135 $attrs->{rows} ||= 10;
136 $attrs->{offset} ||= 0;
137 $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
140 #if (keys %{$collapse}) {
141 # use Data::Dumper; warn Dumper($collapse);
145 result_source => $source,
146 result_class => $attrs->{result_class} || $source->result_class,
147 cond => $attrs->{where},
148 from => $attrs->{from},
149 collapse => $collapse,
151 page => delete $attrs->{page},
154 bless ($new, $class);
160 my @obj = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
161 my $new_rs = $rs->search({ foo => 3 });
163 If you need to pass in additional attributes but no additional condition,
164 call it as C<search({}, \%attrs);>.
166 # "SELECT foo, bar FROM $class_table"
167 my @all = $class->search({}, { cols => [qw/foo bar/] });
177 my $attrs = { %{$self->{attrs}} };
178 my $having = delete $attrs->{having};
179 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
180 $attrs = { %$attrs, %{ pop(@_) } };
184 ? ((@_ == 1 || ref $_[0] eq "HASH")
187 ? $self->throw_exception(
188 "Odd number of arguments to search")
191 if (defined $where) {
192 $where = (defined $attrs->{where}
194 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
195 $where, $attrs->{where} ] }
197 $attrs->{where} = $where;
200 if (defined $having) {
201 $having = (defined $attrs->{having}
203 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
204 $having, $attrs->{having} ] }
206 $attrs->{having} = $having;
209 $rs = (ref $self)->new($self->result_source, $attrs);
215 return (wantarray ? $rs->all : $rs);
218 =head2 search_literal
220 my @obj = $rs->search_literal($literal_where_cond, @bind);
221 my $new_rs = $rs->search_literal($literal_where_cond, @bind);
223 Pass a literal chunk of SQL to be added to the conditional part of the
229 my ($self, $cond, @vals) = @_;
230 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
231 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
232 return $self->search(\$cond, $attrs);
237 =head3 Arguments: (@colvalues) | (\%cols, \%attrs?)
239 Finds a row based on its primary key or unique constraint. For example:
241 my $cd = $schema->resultset('CD')->find(5);
243 Also takes an optional C<key> attribute, to search by a specific key or unique
244 constraint. For example:
246 my $cd = $schema->resultset('CD')->find(
248 artist => 'Massive Attack',
249 title => 'Mezzanine',
251 { key => 'artist_title' }
254 See also L</find_or_create> and L</update_or_create>.
259 my ($self, @vals) = @_;
260 my $attrs = (@vals > 1 && ref $vals[$#vals] eq 'HASH' ? pop(@vals) : {});
262 my @cols = $self->result_source->primary_columns;
263 if (exists $attrs->{key}) {
264 my %uniq = $self->result_source->unique_constraints;
265 $self->( "Unknown key " . $attrs->{key} . " on " . $self->name )
266 unless exists $uniq{$attrs->{key}};
267 @cols = @{ $uniq{$attrs->{key}} };
269 #use Data::Dumper; warn Dumper($attrs, @vals, @cols);
270 $self->throw_exception( "Can't find unless a primary key or unique constraint is defined" )
274 if (ref $vals[0] eq 'HASH') {
275 $query = { %{$vals[0]} };
276 } elsif (@cols == @vals) {
278 @{$query}{@cols} = @vals;
282 foreach (keys %$query) {
284 $query->{$self->{attrs}{alias}.'.'.$_} = delete $query->{$_};
286 #warn Dumper($query);
289 my $rs = $self->search($query,$attrs);
290 return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
292 return keys %{$self->{collapse}} ? $self->search($query)->next : $self->single($query);
296 =head2 search_related
298 $rs->search_related('relname', $cond?, $attrs?);
300 Search the specified relationship. Optionally specify a condition for matching
306 return shift->related_resultset(shift)->search(@_);
311 Returns a storage-driven cursor to the given resultset.
317 my ($attrs) = $self->{attrs};
318 $attrs = { %$attrs };
319 return $self->{cursor}
320 ||= $self->result_source->storage->select($self->{from}, $attrs->{select},
321 $attrs->{where},$attrs);
326 Inflates the first result without creating a cursor
331 my ($self, $extra) = @_;
332 my ($attrs) = $self->{attrs};
333 $attrs = { %$attrs };
335 if (defined $attrs->{where}) {
338 => [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
339 delete $attrs->{where}, $extra ]
342 $attrs->{where} = $extra;
345 my @data = $self->result_source->storage->select_single(
346 $self->{from}, $attrs->{select},
347 $attrs->{where},$attrs);
348 return (@data ? $self->_construct_object(@data) : ());
354 Perform a search, but use C<LIKE> instead of equality as the condition. Note
355 that this is simply a convenience method; you most likely want to use
356 L</search> with specific operators.
358 For more information, see L<DBIx::Class::Manual::Cookbook>.
365 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
368 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
369 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
370 return $class->search($query, { %$attrs });
375 =head3 Arguments: ($first, $last)
377 Returns a subset of elements from the resultset.
382 my ($self, $min, $max) = @_;
383 my $attrs = { %{ $self->{attrs} || {} } };
384 $attrs->{offset} ||= 0;
385 $attrs->{offset} += $min;
386 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
387 my $slice = (ref $self)->new($self->result_source, $attrs);
388 return (wantarray ? $slice->all : $slice);
393 Returns the next element in the resultset (C<undef> is there is none).
395 Can be used to efficiently iterate over records in the resultset:
397 my $rs = $schema->resultset('CD')->search({});
398 while (my $cd = $rs->next) {
407 if( @{$cache = $self->{all_cache} || []}) {
408 $self->{all_cache_position} ||= 0;
409 my $obj = $cache->[$self->{all_cache_position}];
410 $self->{all_cache_position}++;
413 if ($self->{attrs}{cache}) {
414 $self->{all_cache_position} = 1;
415 return ($self->all)[0];
417 my @row = (exists $self->{stashed_row}
418 ? @{delete $self->{stashed_row}}
419 : $self->cursor->next);
420 # warn Dumper(\@row); use Data::Dumper;
421 return unless (@row);
422 return $self->_construct_object(@row);
425 sub _construct_object {
426 my ($self, @row) = @_;
427 my @as = @{ $self->{attrs}{as} };
429 my $info = $self->_collapse_result(\@as, \@row);
431 my $new = $self->result_class->inflate_result($self->result_source, @$info);
433 $new = $self->{attrs}{record_filter}->($new)
434 if exists $self->{attrs}{record_filter};
439 sub _collapse_result {
440 my ($self, $as, $row, $prefix) = @_;
445 foreach my $this_as (@$as) {
446 my $val = shift @copy;
447 if (defined $prefix) {
448 if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
450 $remain =~ /^(?:(.*)\.)?([^\.]+)$/;
451 $const{$1||''}{$2} = $val;
454 $this_as =~ /^(?:(.*)\.)?([^\.]+)$/;
455 $const{$1||''}{$2} = $val;
459 my $info = [ {}, {} ];
460 foreach my $key (keys %const) {
463 my @parts = split(/\./, $key);
464 foreach my $p (@parts) {
465 $target = $target->[1]->{$p} ||= [];
467 $target->[0] = $const{$key};
469 $info->[0] = $const{$key};
473 my @collapse = (defined($prefix)
474 ? (map { (m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()); }
475 keys %{$self->{collapse}})
476 : keys %{$self->{collapse}});
478 my ($c) = sort { length $a <=> length $b } @collapse;
480 foreach my $p (split(/\./, $c)) {
481 $target = $target->[1]->{$p} ||= [];
483 my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
484 my @co_key = @{$self->{collapse}{$c_prefix}};
485 my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
486 my $tree = $self->_collapse_result($as, $row, $c_prefix);
489 !defined($tree->[0]->{$_})
490 || $co_check{$_} ne $tree->[0]->{$_}
493 last unless (@raw = $self->cursor->next);
494 $row = $self->{stashed_row} = \@raw;
495 $tree = $self->_collapse_result($as, $row, $c_prefix);
496 #warn Data::Dumper::Dumper($tree, $row);
506 Returns a reference to the result source for this recordset.
513 Performs an SQL C<COUNT> with the same query as the resultset was built
514 with to find the number of elements. If passed arguments, does a search
515 on the resultset and counts the results of that.
517 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
518 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
519 not support C<DISTINCT> with multiple columns. If you are using such a
520 database, you should only use columns from the main table in your C<group_by>
527 return $self->search(@_)->count if @_ && defined $_[0];
528 unless (defined $self->{count}) {
529 return scalar @{ $self->get_cache }
530 if @{ $self->get_cache };
532 my $select = { 'count' => '*' };
533 my $attrs = { %{ $self->{attrs} } };
534 if( $group_by = delete $attrs->{group_by} ) {
535 delete $attrs->{having};
536 my @distinct = (ref $group_by ? @$group_by : ($group_by));
537 # todo: try CONCAT for multi-column pk
538 my @pk = $self->result_source->primary_columns;
539 if( scalar(@pk) == 1 ) {
541 my $alias = $attrs->{alias};
542 my $re = qr/^($alias\.)?$pk$/;
543 foreach my $column ( @distinct) {
544 if( $column =~ $re ) {
545 @distinct = ( $column );
551 $select = { count => { 'distinct' => \@distinct } };
552 #use Data::Dumper; die Dumper $select;
555 $attrs->{select} = $select;
556 $attrs->{as} = [ 'count' ];
557 # offset, order by and page are not needed to count. record_filter is cdbi
558 delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
560 ($self->{count}) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
562 return 0 unless $self->{count};
563 my $count = $self->{count};
564 $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
565 $count = $self->{attrs}{rows} if
566 ($self->{attrs}{rows} && $self->{attrs}{rows} < $count);
572 Calls L</search_literal> with the passed arguments, then L</count>.
576 sub count_literal { shift->search_literal(@_)->count; }
580 Returns all elements in the resultset. Called implictly if the resultset
581 is returned in list context.
587 return @{ $self->get_cache }
588 if @{ $self->get_cache };
592 if (keys %{$self->{collapse}}) {
593 # Using $self->cursor->all is really just an optimisation.
594 # If we're collapsing has_many prefetches it probably makes
595 # very little difference, and this is cleaner than hacking
596 # _construct_object to survive the approach
598 $self->cursor->reset;
599 while (@row = $self->cursor->next) {
600 push(@obj, $self->_construct_object(@row));
603 @obj = map { $self->_construct_object(@$_); }
607 if( $self->{attrs}->{cache} ) {
608 $self->set_cache( \@obj );
616 Resets the resultset's cursor, so you can iterate through the elements again.
622 $self->{all_cache_position} = 0;
623 $self->cursor->reset;
629 Resets the resultset and returns the first element.
634 return $_[0]->reset->next;
639 =head3 Arguments: (\%values)
641 Sets the specified columns in the resultset to the supplied values.
646 my ($self, $values) = @_;
647 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
648 return $self->result_source->storage->update(
649 $self->result_source->from, $values, $self->{cond});
654 =head3 Arguments: (\%values)
656 Fetches all objects and updates them one at a time. Note that C<update_all>
657 will run cascade triggers while L</update> will not.
662 my ($self, $values) = @_;
663 $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH';
664 foreach my $obj ($self->all) {
665 $obj->set_columns($values)->update;
672 Deletes the contents of the resultset from its result source.
679 $self->throw_exception("Can't delete on resultset with condition unless hash or array")
680 unless (ref($self->{cond}) eq 'HASH' || ref($self->{cond}) eq 'ARRAY');
681 if (ref $self->{cond} eq 'ARRAY') {
682 $del = [ map { my %hash;
683 foreach my $key (keys %{$_}) {
685 $hash{$1} = $_->{$key};
686 }; \%hash; } @{$self->{cond}} ];
687 } elsif ((keys %{$self->{cond}})[0] eq '-and') {
688 $del->{-and} = [ map { my %hash;
689 foreach my $key (keys %{$_}) {
691 $hash{$1} = $_->{$key};
692 }; \%hash; } @{$self->{cond}{-and}} ];
694 foreach my $key (keys %{$self->{cond}}) {
696 $del->{$1} = $self->{cond}{$key};
699 $self->result_source->storage->delete($self->result_source->from, $del);
705 Fetches all objects and deletes them one at a time. Note that C<delete_all>
706 will run cascade triggers while L</delete> will not.
712 $_->delete for $self->all;
718 Returns a L<Data::Page> object for the current resultset. Only makes
719 sense for queries with a C<page> attribute.
725 my $attrs = $self->{attrs};
726 $self->throw_exception("Can't create pager for non-paged rs") unless $self->{page};
727 $attrs->{rows} ||= 10;
729 return $self->{pager} ||= Data::Page->new(
730 $self->{count}, $attrs->{rows}, $self->{page});
735 =head3 Arguments: ($page_num)
737 Returns a new resultset for the specified page.
742 my ($self, $page) = @_;
743 my $attrs = { %{$self->{attrs}} };
744 $attrs->{page} = $page;
745 return (ref $self)->new($self->result_source, $attrs);
750 =head3 Arguments: (\%vals)
752 Creates a result in the resultset's result class.
757 my ($self, $values) = @_;
758 $self->throw_exception( "new_result needs a hash" )
759 unless (ref $values eq 'HASH');
760 $self->throw_exception( "Can't abstract implicit construct, condition not a hash" )
761 if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
763 my $alias = $self->{attrs}{alias};
764 foreach my $key (keys %{$self->{cond}||{}}) {
765 $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
767 my $obj = $self->result_class->new(\%new);
768 $obj->result_source($self->result_source) if $obj->can('result_source');
774 =head3 Arguments: (\%vals)
776 Inserts a record into the resultset and returns the object.
778 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
783 my ($self, $attrs) = @_;
784 $self->throw_exception( "create needs a hashref" ) unless ref $attrs eq 'HASH';
785 return $self->new_result($attrs)->insert;
788 =head2 find_or_create
790 =head3 Arguments: (\%vals, \%attrs?)
792 $class->find_or_create({ key => $val, ... });
794 Searches for a record matching the search condition; if it doesn't find one,
795 creates one and returns that instead.
797 my $cd = $schema->resultset('CD')->find_or_create({
799 artist => 'Massive Attack',
800 title => 'Mezzanine',
804 Also takes an optional C<key> attribute, to search by a specific key or unique
805 constraint. For example:
807 my $cd = $schema->resultset('CD')->find_or_create(
809 artist => 'Massive Attack',
810 title => 'Mezzanine',
812 { key => 'artist_title' }
815 See also L</find> and L</update_or_create>.
821 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
822 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
823 my $exists = $self->find($hash, $attrs);
824 return defined($exists) ? $exists : $self->create($hash);
827 =head2 update_or_create
829 $class->update_or_create({ key => $val, ... });
831 First, search for an existing row matching one of the unique constraints
832 (including the primary key) on the source of this resultset. If a row is
833 found, update it with the other given column values. Otherwise, create a new
836 Takes an optional C<key> attribute to search on a specific unique constraint.
839 # In your application
840 my $cd = $schema->resultset('CD')->update_or_create(
842 artist => 'Massive Attack',
843 title => 'Mezzanine',
846 { key => 'artist_title' }
849 If no C<key> is specified, it searches on all unique constraints defined on the
850 source, including the primary key.
852 If the C<key> is specified as C<primary>, search only on the primary key.
854 See also L</find> and L</find_or_create>.
858 sub update_or_create {
861 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
862 my $hash = ref $_[0] eq "HASH" ? shift : {@_};
864 my %unique_constraints = $self->result_source->unique_constraints;
865 my @constraint_names = (exists $attrs->{key}
867 : keys %unique_constraints);
870 foreach my $name (@constraint_names) {
871 my @unique_cols = @{ $unique_constraints{$name} };
873 map { $_ => $hash->{$_} }
874 grep { exists $hash->{$_} }
877 push @unique_hashes, \%unique_hash
878 if (scalar keys %unique_hash == scalar @unique_cols);
882 if (@unique_hashes) {
883 $row = $self->search(\@unique_hashes, { rows => 1 })->first;
885 $row->set_columns($hash);
891 $row = $self->create($hash);
899 Gets the contents of the cache for the resultset.
905 return $self->{all_cache} || [];
910 Sets the contents of the cache for the resultset. Expects an arrayref of objects of the same class as those produced by the resultset.
915 my ( $self, $data ) = @_;
916 $self->throw_exception("set_cache requires an arrayref")
917 if ref $data ne 'ARRAY';
918 my $result_class = $self->result_class;
920 $self->throw_exception("cannot cache object of type '$_', expected '$result_class'")
921 if ref $_ ne $result_class;
923 $self->{all_cache} = $data;
928 Clears the cache for the resultset.
934 $self->set_cache([]);
937 =head2 related_resultset
939 Returns a related resultset for the supplied relationship name.
941 $rs = $rs->related_resultset('foo');
945 sub related_resultset {
946 my ( $self, $rel, @rest ) = @_;
947 $self->{related_resultsets} ||= {};
948 my $resultsets = $self->{related_resultsets};
949 if( !exists $resultsets->{$rel} ) {
950 #warn "fetching related resultset for rel '$rel'";
951 my $rel_obj = $self->result_source->relationship_info($rel);
952 $self->throw_exception(
953 "search_related: result source '" . $self->result_source->name .
954 "' has no such relationship ${rel}")
955 unless $rel_obj; #die Dumper $self->{attrs};
956 my $rs = $self->search(undef, { join => $rel });
957 #if( $self->{attrs}->{cache} ) {
958 # $rs = $self->search(undef);
962 #use Data::Dumper; die Dumper $rs->{attrs};#$rs = $self->search( undef );
963 #use Data::Dumper; warn Dumper $self->{attrs}, Dumper $rs->{attrs};
964 my $alias = (defined $rs->{attrs}{seen_join}{$rel}
965 && $rs->{attrs}{seen_join}{$rel} > 1
966 ? join('_', $rel, $rs->{attrs}{seen_join}{$rel})
968 $resultsets->{$rel} =
969 $self->result_source->schema->resultset($rel_obj->{class}
977 return $resultsets->{$rel};
980 =head2 throw_exception
982 See Schema's throw_exception
986 sub throw_exception {
988 $self->result_source->schema->throw_exception(@_);
993 The resultset takes various attributes that modify its behavior. Here's an
998 Which column(s) to order the results by. This is currently passed through
999 directly to SQL, so you can give e.g. C<foo DESC> for a descending order.
1003 =head3 Arguments: (arrayref)
1005 Shortcut to request a particular set of columns to be retrieved. Adds
1006 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1007 from that, then auto-populates C<as> from C<select> as normal.
1009 =head2 include_columns
1011 =head3 Arguments: (arrayref)
1013 Shortcut to include additional columns in the returned results - for example
1015 { include_columns => ['foo.name'], join => ['foo'] }
1017 would add a 'name' column to the information passed to object inflation
1021 =head3 Arguments: (arrayref)
1023 Indicates which columns should be selected from the storage. You can use
1024 column names, or in the case of RDBMS back ends, function or stored procedure
1027 $rs = $schema->resultset('Foo')->search(
1032 { count => 'column_to_count' },
1033 { sum => 'column_to_sum' }
1038 When you use function/stored procedure names and do not supply an C<as>
1039 attribute, the column names returned are storage-dependent. E.g. MySQL would
1040 return a column named C<count(column_to_count)> in the above example.
1044 =head3 Arguments: (arrayref)
1046 Indicates column names for object inflation. This is used in conjunction with
1047 C<select>, usually when C<select> contains one or more function or stored
1050 $rs = $schema->resultset('Foo')->search(
1055 { count => 'column2' }
1057 as => [qw/ column1 column2_count /]
1061 my $foo = $rs->first(); # get the first Foo
1063 If the object against which the search is performed already has an accessor
1064 matching a column name specified in C<as>, the value can be retrieved using
1065 the accessor as normal:
1067 my $column1 = $foo->column1();
1069 If on the other hand an accessor does not exist in the object, you need to
1070 use C<get_column> instead:
1072 my $column2_count = $foo->get_column('column2_count');
1074 You can create your own accessors if required - see
1075 L<DBIx::Class::Manual::Cookbook> for details.
1079 Contains a list of relationships that should be joined for this query. For
1082 # Get CDs by Nine Inch Nails
1083 my $rs = $schema->resultset('CD')->search(
1084 { 'artist.name' => 'Nine Inch Nails' },
1085 { join => 'artist' }
1088 Can also contain a hash reference to refer to the other relation's relations.
1091 package MyApp::Schema::Track;
1092 use base qw/DBIx::Class/;
1093 __PACKAGE__->table('track');
1094 __PACKAGE__->add_columns(qw/trackid cd position title/);
1095 __PACKAGE__->set_primary_key('trackid');
1096 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1099 # In your application
1100 my $rs = $schema->resultset('Artist')->search(
1101 { 'track.title' => 'Teardrop' },
1103 join => { cd => 'track' },
1104 order_by => 'artist.name',
1108 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1109 similarly for a third time). For e.g.
1111 my $rs = $schema->resultset('Artist')->search(
1112 { 'cds.title' => 'Foo',
1113 'cds_2.title' => 'Bar' },
1114 { join => [ qw/cds cds/ ] });
1116 will return a set of all artists that have both a cd with title Foo and a cd
1119 If you want to fetch related objects from other tables as well, see C<prefetch>
1124 =head3 Arguments: arrayref/hashref
1126 Contains one or more relationships that should be fetched along with the main
1127 query (when they are accessed afterwards they will have already been
1128 "prefetched"). This is useful for when you know you will need the related
1129 objects, because it saves at least one query:
1131 my $rs = $schema->resultset('Tag')->search(
1140 The initial search results in SQL like the following:
1142 SELECT tag.*, cd.*, artist.* FROM tag
1143 JOIN cd ON tag.cd = cd.cdid
1144 JOIN artist ON cd.artist = artist.artistid
1146 L<DBIx::Class> has no need to go back to the database when we access the
1147 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1150 Simple prefetches will be joined automatically, so there is no need
1151 for a C<join> attribute in the above search. If you're prefetching to
1152 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1153 specify the join as well.
1155 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1156 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1157 with an accessor type of 'single' or 'filter').
1161 =head3 Arguments: (arrayref)
1163 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1164 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1167 NOTE: Use this on your own risk. This allows you to shoot off your foot!
1168 C<join> will usually do what you need and it is strongly recommended that you
1169 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1171 In simple terms, C<from> works as follows:
1174 { <alias> => <table>, -join-type => 'inner|left|right' }
1175 [] # nested JOIN (optional)
1176 { <table.column> = <foreign_table.foreign_key> }
1182 ON <table.column> = <foreign_table.foreign_key>
1184 An easy way to follow the examples below is to remember the following:
1186 Anything inside "[]" is a JOIN
1187 Anything inside "{}" is a condition for the enclosing JOIN
1189 The following examples utilize a "person" table in a family tree application.
1190 In order to express parent->child relationships, this table is self-joined:
1192 # Person->belongs_to('father' => 'Person');
1193 # Person->belongs_to('mother' => 'Person');
1195 C<from> can be used to nest joins. Here we return all children with a father,
1196 then search against all mothers of those children:
1198 $rs = $schema->resultset('Person')->search(
1201 alias => 'mother', # alias columns in accordance with "from"
1203 { mother => 'person' },
1206 { child => 'person' },
1208 { father => 'person' },
1209 { 'father.person_id' => 'child.father_id' }
1212 { 'mother.person_id' => 'child.mother_id' }
1219 # SELECT mother.* FROM person mother
1222 # JOIN person father
1223 # ON ( father.person_id = child.father_id )
1225 # ON ( mother.person_id = child.mother_id )
1227 The type of any join can be controlled manually. To search against only people
1228 with a father in the person table, we could explicitly use C<INNER JOIN>:
1230 $rs = $schema->resultset('Person')->search(
1233 alias => 'child', # alias columns in accordance with "from"
1235 { child => 'person' },
1237 { father => 'person', -join-type => 'inner' },
1238 { 'father.id' => 'child.father_id' }
1245 # SELECT child.* FROM person child
1246 # INNER JOIN person father ON child.father_id = father.id
1250 For a paged resultset, specifies which page to retrieve. Leave unset
1251 for an unpaged resultset.
1255 For a paged resultset, how many rows per page:
1259 Can also be used to simulate an SQL C<LIMIT>.
1263 =head3 Arguments: (arrayref)
1265 A arrayref of columns to group by. Can include columns of joined tables.
1267 group_by => [qw/ column1 column2 ... /]
1271 Set to 1 to group by all columns.
1273 For more examples of using these attributes, see
1274 L<DBIx::Class::Manual::Cookbook>.