1 package DBIx::Class::ResultSet;
12 use Scalar::Util qw/weaken/;
14 use DBIx::Class::ResultSetColumn;
15 use base qw/DBIx::Class/;
16 __PACKAGE__->load_components(qw/AccessorGroup/);
17 __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
21 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
25 my $rs = $schema->resultset('User')->search(registered => 1);
26 my @rows = $schema->resultset('CD')->search(year => 2005);
30 The resultset is also known as an iterator. It is responsible for handling
31 queries that may return an arbitrary number of rows, e.g. via L</search>
32 or a C<has_many> relationship.
34 In the examples below, the following table classes are used:
36 package MyApp::Schema::Artist;
37 use base qw/DBIx::Class/;
38 __PACKAGE__->load_components(qw/Core/);
39 __PACKAGE__->table('artist');
40 __PACKAGE__->add_columns(qw/artistid name/);
41 __PACKAGE__->set_primary_key('artistid');
42 __PACKAGE__->has_many(cds => 'MyApp::Schema::CD');
45 package MyApp::Schema::CD;
46 use base qw/DBIx::Class/;
47 __PACKAGE__->load_components(qw/Core/);
48 __PACKAGE__->table('cd');
49 __PACKAGE__->add_columns(qw/cdid artist title year/);
50 __PACKAGE__->set_primary_key('cdid');
51 __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist');
60 =item Arguments: $source, \%$attrs
62 =item Return Value: $rs
66 The resultset constructor. Takes a source object (usually a
67 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
68 L</ATTRIBUTES> below). Does not perform any queries -- these are
69 executed as needed by the other methods.
71 Generally you won't need to construct a resultset manually. You'll
72 automatically get one from e.g. a L</search> called in scalar context:
74 my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
76 IMPORTANT: If called on an object, proxies to new_result instead so
78 my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
80 will return a CD object, not a ResultSet.
86 return $class->new_result(@_) if ref $class;
88 my ($source, $attrs) = @_;
92 $attrs->{rows} ||= 10;
93 $attrs->{offset} ||= 0;
94 $attrs->{offset} += ($attrs->{rows} * ($attrs->{page} - 1));
97 $attrs->{alias} ||= 'me';
100 result_source => $source,
101 result_class => $attrs->{result_class} || $source->result_class,
102 cond => $attrs->{where},
103 # from => $attrs->{from},
104 # collapse => $collapse,
106 page => delete $attrs->{page},
116 =item Arguments: $cond, \%attrs?
118 =item Return Value: $resultset (scalar context), @row_objs (list context)
122 my @cds = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
123 my $new_rs = $cd_rs->search({ year => 2005 });
125 my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
126 # year = 2005 OR year = 2004
128 If you need to pass in additional attributes but no additional condition,
129 call it as C<search(undef, \%attrs)>.
131 # "SELECT name, artistid FROM $artist_table"
132 my @all_artists = $schema->resultset('Artist')->search(undef, {
133 columns => [qw/name artistid/],
140 my $rs = $self->search_rs( @_ );
141 return (wantarray ? $rs->all : $rs);
148 =item Arguments: $cond, \%attrs?
150 =item Return Value: $resultset
154 This method does the same exact thing as search() except it will
155 always return a resultset, even in list context.
162 my $our_attrs = { %{$self->{attrs}} };
163 my $having = delete $our_attrs->{having};
165 $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
167 # merge new attrs into old
168 foreach my $key (qw/join prefetch/) {
169 next unless (exists $attrs->{$key});
170 if (exists $our_attrs->{$key}) {
171 $our_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
173 $our_attrs->{$key} = $attrs->{$key};
175 delete $attrs->{$key};
178 if (exists $our_attrs->{prefetch}) {
179 $our_attrs->{join} = $self->_merge_attr($our_attrs->{join}, $our_attrs->{prefetch}, 1);
182 my $new_attrs = { %{$our_attrs}, %{$attrs} };
184 # merge new where and having into old
186 ? ((@_ == 1 || ref $_[0] eq "HASH")
189 ? $self->throw_exception(
190 "Odd number of arguments to search")
193 if (defined $where) {
194 $new_attrs->{where} = (defined $new_attrs->{where}
196 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
197 $where, $new_attrs->{where} ] }
201 if (defined $having) {
202 $new_attrs->{having} = (defined $new_attrs->{having}
204 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
205 $having, $new_attrs->{having} ] }
209 my $rs = (ref $self)->new($self->result_source, $new_attrs);
210 $rs->{_parent_rs} = $self->{_parent_rs} if ($self->{_parent_rs}); #XXX - hack to pass through parent of related resultsets
212 unless (@_) { # no search, effectively just a clone
213 my $rows = $self->get_cache;
215 $rs->set_cache($rows);
222 =head2 search_literal
226 =item Arguments: $sql_fragment, @bind_values
228 =item Return Value: $resultset (scalar context), @row_objs (list context)
232 my @cds = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
233 my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
235 Pass a literal chunk of SQL to be added to the conditional part of the
241 my ($self, $cond, @vals) = @_;
242 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
243 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
244 return $self->search(\$cond, $attrs);
251 =item Arguments: @values | \%cols, \%attrs?
253 =item Return Value: $row_object
257 Finds a row based on its primary key or unique constraint. For example, to find
258 a row by its primary key:
260 my $cd = $schema->resultset('CD')->find(5);
262 You can also find a row by a specific unique constraint using the C<key>
263 attribute. For example:
265 my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', { key => 'artist_title' });
267 Additionally, you can specify the columns explicitly by name:
269 my $cd = $schema->resultset('CD')->find(
271 artist => 'Massive Attack',
272 title => 'Mezzanine',
274 { key => 'artist_title' }
277 If no C<key> is specified and you explicitly name columns, it searches on all
278 unique constraints defined on the source, including the primary key.
280 If the C<key> is specified as C<primary>, it searches only on the primary key.
282 See also L</find_or_create> and L</update_or_create>. For information on how to
283 declare unique constraints, see
284 L<DBIx::Class::ResultSource/add_unique_constraint>.
290 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
292 # Parse out a hash from input
293 my @cols = exists $attrs->{key}
294 ? $self->result_source->unique_constraint_columns($attrs->{key})
295 : $self->result_source->primary_columns;
298 if (ref $_[0] eq 'HASH') {
299 $hash = { %{$_[0]} };
301 elsif (@_ == @cols) {
303 @{$hash}{@cols} = @_;
306 # For backwards compatibility
310 $self->throw_exception(
311 "Arguments to find must be a hashref or match the number of columns in the "
312 . (exists $attrs->{key} ? "$attrs->{key} unique constraint" : "primary key")
316 # Check the hash we just parsed against our source's unique constraints
317 my @constraint_names = exists $attrs->{key}
319 : $self->result_source->unique_constraint_names;
320 $self->throw_exception(
321 "Can't find unless a primary key or unique constraint is defined"
322 ) unless @constraint_names;
325 foreach my $name (@constraint_names) {
326 my @unique_cols = $self->result_source->unique_constraint_columns($name);
327 my $unique_query = $self->_build_unique_query($hash, \@unique_cols);
329 # Add the ResultSet's alias
330 foreach my $key (grep { ! m/\./ } keys %$unique_query) {
331 $unique_query->{"$self->{attrs}{alias}.$key"} = delete $unique_query->{$key};
334 push @unique_queries, $unique_query if %$unique_query;
337 # Handle cases where the ResultSet already defines the query
338 my $query = @unique_queries ? \@unique_queries : undef;
342 my $rs = $self->search($query, $attrs);
344 return keys %{$rs->{_attrs}->{collapse}} ? $rs->next : $rs->single;
348 return (keys %{$self->{_attrs}->{collapse}})
349 ? $self->search($query)->next
350 : $self->single($query);
354 # _build_unique_query
356 # Constrain the specified query hash based on the specified column names.
358 sub _build_unique_query {
359 my ($self, $query, $unique_cols) = @_;
362 map { $_ => $query->{$_} }
363 grep { exists $query->{$_} }
366 return \%unique_query;
369 =head2 search_related
373 =item Arguments: $cond, \%attrs?
375 =item Return Value: $new_resultset
379 $new_rs = $cd_rs->search_related('artist', {
383 Searches the specified relationship, optionally specifying a condition and
384 attributes for matching records. See L</ATTRIBUTES> for more information.
389 return shift->related_resultset(shift)->search(@_);
396 =item Arguments: none
398 =item Return Value: $cursor
402 Returns a storage-driven cursor to the given resultset. See
403 L<DBIx::Class::Cursor> for more information.
411 my $attrs = { %{$self->{_attrs}} };
412 return $self->{cursor}
413 ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
414 $attrs->{where},$attrs);
421 =item Arguments: $cond?
423 =item Return Value: $row_object?
427 my $cd = $schema->resultset('CD')->single({ year => 2001 });
429 Inflates the first result without creating a cursor if the resultset has
430 any records in it; if not returns nothing. Used by L</find> as an optimisation.
432 Can optionally take an additional condition *only* - this is a fast-code-path
433 method; if you need to add extra joins or similar call ->search and then
434 ->single without a condition on the $rs returned from that.
439 my ($self, $where) = @_;
441 my $attrs = { %{$self->{_attrs}} };
443 if (defined $attrs->{where}) {
446 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
447 $where, delete $attrs->{where} ]
450 $attrs->{where} = $where;
454 my @data = $self->result_source->storage->select_single(
455 $attrs->{from}, $attrs->{select},
456 $attrs->{where},$attrs);
457 return (@data ? $self->_construct_object(@data) : ());
464 =item Arguments: $cond?
466 =item Return Value: $resultsetcolumn
470 my $max_length = $rs->get_column('length')->max;
472 Returns a ResultSetColumn instance for $column based on $self
477 my ($self, $column) = @_;
479 my $new = DBIx::Class::ResultSetColumn->new($self, $column);
487 =item Arguments: $cond, \%attrs?
489 =item Return Value: $resultset (scalar context), @row_objs (list context)
493 # WHERE title LIKE '%blue%'
494 $cd_rs = $rs->search_like({ title => '%blue%'});
496 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
497 that this is simply a convenience method. You most likely want to use
498 L</search> with specific operators.
500 For more information, see L<DBIx::Class::Manual::Cookbook>.
506 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
507 my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
508 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
509 return $class->search($query, { %$attrs });
516 =item Arguments: $first, $last
518 =item Return Value: $resultset (scalar context), @row_objs (list context)
522 Returns a resultset or object list representing a subset of elements from the
523 resultset slice is called on. Indexes are from 0, i.e., to get the first
526 my ($one, $two, $three) = $rs->slice(0, 2);
531 my ($self, $min, $max) = @_;
532 my $attrs = {}; # = { %{ $self->{attrs} || {} } };
533 $attrs->{offset} = $self->{attrs}{offset} || 0;
534 $attrs->{offset} += $min;
535 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
536 return $self->search(undef(), $attrs);
537 #my $slice = (ref $self)->new($self->result_source, $attrs);
538 #return (wantarray ? $slice->all : $slice);
545 =item Arguments: none
547 =item Return Value: $result?
551 Returns the next element in the resultset (C<undef> is there is none).
553 Can be used to efficiently iterate over records in the resultset:
555 my $rs = $schema->resultset('CD')->search;
556 while (my $cd = $rs->next) {
560 Note that you need to store the resultset object, and call C<next> on it.
561 Calling C<< resultset('Table')->next >> repeatedly will always return the
562 first record from the resultset.
568 if (my $cache = $self->get_cache) {
569 $self->{all_cache_position} ||= 0;
570 return $cache->[$self->{all_cache_position}++];
572 if ($self->{attrs}{cache}) {
573 $self->{all_cache_position} = 1;
574 return ($self->all)[0];
576 my @row = (exists $self->{stashed_row} ?
577 @{delete $self->{stashed_row}} :
580 return unless (@row);
581 return $self->_construct_object(@row);
587 return if(exists $self->{_attrs}); #return if _resolve has already been called
589 my $attrs = $self->{attrs};
590 my $source = ($self->{_parent_rs}) ? $self->{_parent_rs} : $self->{result_source};
592 # XXX - lose storable dclone
593 my $record_filter = delete $attrs->{record_filter} if (defined $attrs->{record_filter});
594 $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
595 $attrs->{record_filter} = $record_filter if ($record_filter);
596 $self->{attrs}->{record_filter} = $record_filter if ($record_filter);
598 my $alias = $attrs->{alias};
600 $attrs->{columns} ||= delete $attrs->{cols} if $attrs->{cols};
601 delete $attrs->{as} if $attrs->{columns};
602 $attrs->{columns} ||= [ $self->{result_source}->columns ] unless $attrs->{select};
603 my $select_alias = ($self->{_parent_rs}) ? $self->{attrs}->{_live_join} : $alias;
605 map { m/\./ ? $_ : "${select_alias}.$_" } @{delete $attrs->{columns}}
606 ] if $attrs->{columns};
608 map { m/^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$attrs->{select}}
610 if (my $include = delete $attrs->{include_columns}) {
611 push(@{$attrs->{select}}, @$include);
612 push(@{$attrs->{as}}, map { m/([^.]+)$/; $1; } @$include);
615 $attrs->{from} ||= [ { $alias => $source->from } ];
616 $attrs->{seen_join} ||= {};
618 if (my $join = delete $attrs->{join}) {
619 foreach my $j (ref $join eq 'ARRAY' ? @$join : ($join)) {
620 if (ref $j eq 'HASH') {
621 $seen{$_} = 1 foreach keys %$j;
627 push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}, $attrs->{seen_join}));
629 $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
630 $attrs->{order_by} = [ $attrs->{order_by} ] if
631 $attrs->{order_by} and !ref($attrs->{order_by});
632 $attrs->{order_by} ||= [];
634 my $collapse = $attrs->{collapse} || {};
635 if (my $prefetch = delete $attrs->{prefetch}) {
637 foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) {
638 if ( ref $p eq 'HASH' ) {
639 foreach my $key (keys %$p) {
640 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
644 push(@{$attrs->{from}}, $source->resolve_join($p, $attrs->{alias}))
647 my @prefetch = $source->resolve_prefetch(
648 $p, $attrs->{alias}, {}, \@pre_order, $collapse);
649 push(@{$attrs->{select}}, map { $_->[0] } @prefetch);
650 push(@{$attrs->{as}}, map { $_->[1] } @prefetch);
652 push(@{$attrs->{order_by}}, @pre_order);
654 $attrs->{collapse} = $collapse;
655 $self->{_attrs} = $attrs;
659 my ($self, $a, $b, $is_prefetch) = @_;
662 if (ref $b eq 'HASH' && ref $a eq 'HASH') {
663 foreach my $key (keys %{$b}) {
664 if (exists $a->{$key}) {
665 $a->{$key} = $self->_merge_attr($a->{$key}, $b->{$key}, $is_prefetch);
667 $a->{$key} = delete $b->{$key};
672 $a = [$a] unless (ref $a eq 'ARRAY');
673 $b = [$b] unless (ref $b eq 'ARRAY');
678 foreach my $element (@{$_}) {
679 if (ref $element eq 'HASH') {
680 $hash = $self->_merge_attr($hash, $element, $is_prefetch);
681 } elsif (ref $element eq 'ARRAY') {
682 $array = [@{$array}, @{$element}];
684 if (($b == $_) && $is_prefetch) {
685 $self->_merge_array($array, $element, $is_prefetch);
687 push(@{$array}, $element);
693 if ((keys %{$hash}) && (scalar(@{$array} > 0))) {
694 return [$hash, @{$array}];
696 return (keys %{$hash}) ? $hash : $array;
702 my ($self, $a, $b) = @_;
704 $b = [$b] unless (ref $b eq 'ARRAY');
705 # add elements from @{$b} to @{$a} which aren't already in @{$a}
706 foreach my $b_element (@{$b}) {
707 push(@{$a}, $b_element) unless grep {$b_element eq $_} @{$a};
711 sub _construct_object {
712 my ($self, @row) = @_;
713 my @as = @{ $self->{_attrs}{as} };
715 my $info = $self->_collapse_result(\@as, \@row);
716 my $new = $self->result_class->inflate_result($self->result_source, @$info);
717 $new = $self->{_attrs}{record_filter}->($new)
718 if exists $self->{_attrs}{record_filter};
722 sub _collapse_result {
723 my ($self, $as, $row, $prefix) = @_;
725 my $live_join = $self->{attrs}->{_live_join} ||="";
729 foreach my $this_as (@$as) {
730 my $val = shift @copy;
731 if (defined $prefix) {
732 if ($this_as =~ m/^\Q${prefix}.\E(.+)$/) {
734 $remain =~ /^(?:(.*)\.)?([^.]+)$/;
735 $const{$1||''}{$2} = $val;
738 $this_as =~ /^(?:(.*)\.)?([^.]+)$/;
739 $const{$1||''}{$2} = $val;
743 my $info = [ {}, {} ];
744 foreach my $key (keys %const) {
745 if (length $key && $key ne $live_join) {
747 my @parts = split(/\./, $key);
748 foreach my $p (@parts) {
749 $target = $target->[1]->{$p} ||= [];
751 $target->[0] = $const{$key};
753 $info->[0] = $const{$key};
758 if (defined $prefix) {
760 m/^\Q${prefix}.\E(.+)$/ ? ($1) : ()
761 } keys %{$self->{_attrs}->{collapse}}
763 @collapse = keys %{$self->{_attrs}->{collapse}};
767 my ($c) = sort { length $a <=> length $b } @collapse;
769 foreach my $p (split(/\./, $c)) {
770 $target = $target->[1]->{$p} ||= [];
772 my $c_prefix = (defined($prefix) ? "${prefix}.${c}" : $c);
773 my @co_key = @{$self->{_attrs}->{collapse}{$c_prefix}};
774 my %co_check = map { ($_, $target->[0]->{$_}); } @co_key;
775 my $tree = $self->_collapse_result($as, $row, $c_prefix);
778 !defined($tree->[0]->{$_}) ||
779 $co_check{$_} ne $tree->[0]->{$_}
782 last unless (@raw = $self->cursor->next);
783 $row = $self->{stashed_row} = \@raw;
784 $tree = $self->_collapse_result($as, $row, $c_prefix);
786 @$target = (@final ? @final : [ {}, {} ]);
787 # single empty result to indicate an empty prefetched has_many
796 =item Arguments: $result_source?
798 =item Return Value: $result_source
802 An accessor for the primary ResultSource object from which this ResultSet
812 =item Arguments: $cond, \%attrs??
814 =item Return Value: $count
818 Performs an SQL C<COUNT> with the same query as the resultset was built
819 with to find the number of elements. If passed arguments, does a search
820 on the resultset and counts the results of that.
822 Note: When using C<count> with C<group_by>, L<DBIX::Class> emulates C<GROUP BY>
823 using C<COUNT( DISTINCT( columns ) )>. Some databases (notably SQLite) do
824 not support C<DISTINCT> with multiple columns. If you are using such a
825 database, you should only use columns from the main table in your C<group_by>
832 return $self->search(@_)->count if @_ and defined $_[0];
833 return scalar @{ $self->get_cache } if $self->get_cache;
835 my $count = $self->_count;
836 return 0 unless $count;
838 $count -= $self->{attrs}{offset} if $self->{attrs}{offset};
839 $count = $self->{attrs}{rows} if
840 $self->{attrs}{rows} and $self->{attrs}{rows} < $count;
844 sub _count { # Separated out so pager can get the full count
846 my $select = { count => '*' };
849 my $attrs = { %{ $self->{_attrs} } };
850 if (my $group_by = delete $attrs->{group_by}) {
851 delete $attrs->{having};
852 my @distinct = (ref $group_by ? @$group_by : ($group_by));
853 # todo: try CONCAT for multi-column pk
854 my @pk = $self->result_source->primary_columns;
856 foreach my $column (@distinct) {
857 if ($column =~ qr/^(?:\Q$attrs->{alias}.\E)?$pk[0]$/) {
858 @distinct = ($column);
864 $select = { count => { distinct => \@distinct } };
867 $attrs->{select} = $select;
868 $attrs->{as} = [qw/count/];
870 # offset, order by and page are not needed to count. record_filter is cdbi
871 delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
872 my ($count) = (ref $self)->new($self->result_source, $attrs)->cursor->next;
880 =item Arguments: $sql_fragment, @bind_values
882 =item Return Value: $count
886 Counts the results in a literal query. Equivalent to calling L</search_literal>
887 with the passed arguments, then L</count>.
891 sub count_literal { shift->search_literal(@_)->count; }
897 =item Arguments: none
899 =item Return Value: @objects
903 Returns all elements in the resultset. Called implicitly if the resultset
904 is returned in list context.
910 return @{ $self->get_cache } if $self->get_cache;
914 # TODO: don't call resolve here
916 if (keys %{$self->{_attrs}->{collapse}}) {
917 # if ($self->{attrs}->{prefetch}) {
918 # Using $self->cursor->all is really just an optimisation.
919 # If we're collapsing has_many prefetches it probably makes
920 # very little difference, and this is cleaner than hacking
921 # _construct_object to survive the approach
922 my @row = $self->cursor->next;
924 push(@obj, $self->_construct_object(@row));
925 @row = (exists $self->{stashed_row}
926 ? @{delete $self->{stashed_row}}
927 : $self->cursor->next);
930 @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
933 $self->set_cache(\@obj) if $self->{attrs}{cache};
941 =item Arguments: none
943 =item Return Value: $self
947 Resets the resultset's cursor, so you can iterate through the elements again.
953 delete $self->{_attrs} if (exists $self->{_attrs});
955 $self->{all_cache_position} = 0;
956 $self->cursor->reset;
964 =item Arguments: none
966 =item Return Value: $object?
970 Resets the resultset and returns an object for the first result (if the
971 resultset returns anything).
976 return $_[0]->reset->next;
979 # _cond_for_update_delete
981 # update/delete require the condition to be modified to handle
982 # the differing SQL syntax available. This transforms the $self->{cond}
983 # appropriately, returning the new condition.
985 sub _cond_for_update_delete {
989 if (!ref($self->{cond})) {
990 # No-op. No condition, we're updating/deleting everything
992 elsif (ref $self->{cond} eq 'ARRAY') {
996 foreach my $key (keys %{$_}) {
998 $hash{$1} = $_->{$key};
1004 elsif (ref $self->{cond} eq 'HASH') {
1005 if ((keys %{$self->{cond}})[0] eq '-and') {
1008 my @cond = @{$self->{cond}{-and}};
1009 for (my $i = 0; $i <= @cond - 1; $i++) {
1010 my $entry = $cond[$i];
1013 if (ref $entry eq 'HASH') {
1014 foreach my $key (keys %{$entry}) {
1016 $hash{$1} = $entry->{$key};
1020 $entry =~ /([^.]+)$/;
1021 $hash{$1} = $cond[++$i];
1024 push @{$cond->{-and}}, \%hash;
1028 foreach my $key (keys %{$self->{cond}}) {
1030 $cond->{$1} = $self->{cond}{$key};
1035 $self->throw_exception(
1036 "Can't update/delete on resultset with condition unless hash or array"
1048 =item Arguments: \%values
1050 =item Return Value: $storage_rv
1054 Sets the specified columns in the resultset to the supplied values in a
1055 single query. Return value will be true if the update succeeded or false
1056 if no records were updated; exact type of success value is storage-dependent.
1061 my ($self, $values) = @_;
1062 $self->throw_exception("Values for update must be a hash")
1063 unless ref $values eq 'HASH';
1065 my $cond = $self->_cond_for_update_delete;
1067 return $self->result_source->storage->update(
1068 $self->result_source->from, $values, $cond
1076 =item Arguments: \%values
1078 =item Return Value: 1
1082 Fetches all objects and updates them one at a time. Note that C<update_all>
1083 will run DBIC cascade triggers, while L</update> will not.
1088 my ($self, $values) = @_;
1089 $self->throw_exception("Values for update must be a hash")
1090 unless ref $values eq 'HASH';
1091 foreach my $obj ($self->all) {
1092 $obj->set_columns($values)->update;
1101 =item Arguments: none
1103 =item Return Value: 1
1107 Deletes the contents of the resultset from its result source. Note that this
1108 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1117 my $cond = $self->_cond_for_update_delete;
1119 $self->result_source->storage->delete($self->result_source->from, $cond);
1127 =item Arguments: none
1129 =item Return Value: 1
1133 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1134 will run DBIC cascade triggers, while L</delete> will not.
1140 $_->delete for $self->all;
1148 =item Arguments: none
1150 =item Return Value: $pager
1154 Return Value a L<Data::Page> object for the current resultset. Only makes
1155 sense for queries with a C<page> attribute.
1161 my $attrs = $self->{attrs};
1162 $self->throw_exception("Can't create pager for non-paged rs")
1163 unless $self->{page};
1164 $attrs->{rows} ||= 10;
1165 return $self->{pager} ||= Data::Page->new(
1166 $self->_count, $attrs->{rows}, $self->{page});
1173 =item Arguments: $page_number
1175 =item Return Value: $rs
1179 Returns a resultset for the $page_number page of the resultset on which page
1180 is called, where each page contains a number of rows equal to the 'rows'
1181 attribute set on the resultset (10 by default).
1186 my ($self, $page) = @_;
1187 my $attrs = { %{$self->{attrs}} };
1188 $attrs->{page} = $page;
1189 return (ref $self)->new($self->result_source, $attrs);
1196 =item Arguments: \%vals
1198 =item Return Value: $object
1202 Creates an object in the resultset's result class and returns it.
1207 my ($self, $values) = @_;
1208 $self->throw_exception( "new_result needs a hash" )
1209 unless (ref $values eq 'HASH');
1210 $self->throw_exception(
1211 "Can't abstract implicit construct, condition not a hash"
1212 ) if ($self->{cond} && !(ref $self->{cond} eq 'HASH'));
1214 my $alias = $self->{attrs}{alias};
1215 foreach my $key (keys %{$self->{cond}||{}}) {
1216 $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:\Q${alias}.\E)?([^.]+)$/);
1218 my $obj = $self->result_class->new(\%new);
1219 $obj->result_source($self->result_source) if $obj->can('result_source');
1227 =item Arguments: \%vals, \%attrs?
1229 =item Return Value: $object
1233 Find an existing record from this resultset. If none exists, instantiate a new
1234 result object and return it. The object will not be saved into your storage
1235 until you call L<DBIx::Class::Row/insert> on it.
1237 If you want objects to be saved immediately, use L</find_or_create> instead.
1243 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1244 my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1245 my $exists = $self->find($hash, $attrs);
1246 return defined $exists ? $exists : $self->new_result($hash);
1253 =item Arguments: \%vals
1255 =item Return Value: $object
1259 Inserts a record into the resultset and returns the object representing it.
1261 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
1266 my ($self, $attrs) = @_;
1267 $self->throw_exception( "create needs a hashref" )
1268 unless ref $attrs eq 'HASH';
1269 return $self->new_result($attrs)->insert;
1272 =head2 find_or_create
1276 =item Arguments: \%vals, \%attrs?
1278 =item Return Value: $object
1282 $class->find_or_create({ key => $val, ... });
1284 Searches for a record matching the search condition; if it doesn't find one,
1285 creates one and returns that instead.
1287 my $cd = $schema->resultset('CD')->find_or_create({
1289 artist => 'Massive Attack',
1290 title => 'Mezzanine',
1294 Also takes an optional C<key> attribute, to search by a specific key or unique
1295 constraint. For example:
1297 my $cd = $schema->resultset('CD')->find_or_create(
1299 artist => 'Massive Attack',
1300 title => 'Mezzanine',
1302 { key => 'artist_title' }
1305 See also L</find> and L</update_or_create>. For information on how to declare
1306 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1310 sub find_or_create {
1312 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1313 my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1314 my $exists = $self->find($hash, $attrs);
1315 return defined $exists ? $exists : $self->create($hash);
1318 =head2 update_or_create
1322 =item Arguments: \%col_values, { key => $unique_constraint }?
1324 =item Return Value: $object
1328 $class->update_or_create({ col => $val, ... });
1330 First, searches for an existing row matching one of the unique constraints
1331 (including the primary key) on the source of this resultset. If a row is
1332 found, updates it with the other given column values. Otherwise, creates a new
1335 Takes an optional C<key> attribute to search on a specific unique constraint.
1338 # In your application
1339 my $cd = $schema->resultset('CD')->update_or_create(
1341 artist => 'Massive Attack',
1342 title => 'Mezzanine',
1345 { key => 'artist_title' }
1348 If no C<key> is specified, it searches on all unique constraints defined on the
1349 source, including the primary key.
1351 If the C<key> is specified as C<primary>, it searches only on the primary key.
1353 See also L</find> and L</find_or_create>. For information on how to declare
1354 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
1358 sub update_or_create {
1360 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
1361 my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
1363 my $row = $self->find($hash, $attrs);
1365 $row->update($hash);
1369 return $self->create($hash);
1376 =item Arguments: none
1378 =item Return Value: \@cache_objects?
1382 Gets the contents of the cache for the resultset, if the cache is set.
1394 =item Arguments: \@cache_objects
1396 =item Return Value: \@cache_objects
1400 Sets the contents of the cache for the resultset. Expects an arrayref
1401 of objects of the same class as those produced by the resultset. Note that
1402 if the cache is set the resultset will return the cached objects rather
1403 than re-querying the database even if the cache attr is not set.
1408 my ( $self, $data ) = @_;
1409 $self->throw_exception("set_cache requires an arrayref")
1410 if defined($data) && (ref $data ne 'ARRAY');
1411 $self->{all_cache} = $data;
1418 =item Arguments: none
1420 =item Return Value: []
1424 Clears the cache for the resultset.
1429 shift->set_cache(undef);
1432 =head2 related_resultset
1436 =item Arguments: $relationship_name
1438 =item Return Value: $resultset
1442 Returns a related resultset for the supplied relationship name.
1444 $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
1448 sub related_resultset {
1449 my ( $self, $rel ) = @_;
1451 $self->{related_resultsets} ||= {};
1452 return $self->{related_resultsets}{$rel} ||= do {
1453 #warn "fetching related resultset for rel '$rel' " . $self->result_source->{name};
1454 my $rel_obj = $self->result_source->relationship_info($rel);
1455 $self->throw_exception(
1456 "search_related: result source '" . $self->result_source->name .
1457 "' has no such relationship ${rel}")
1458 unless $rel_obj; #die Dumper $self->{attrs};
1460 my $rs = $self->result_source->schema->resultset($rel_obj->{class}
1462 { %{$self->{attrs}},
1466 _live_join => $rel }
1469 # keep reference of the original resultset
1470 $rs->{_parent_rs} = $self->result_source;
1475 =head2 throw_exception
1477 See L<DBIx::Class::Schema/throw_exception> for details.
1481 sub throw_exception {
1483 $self->result_source->schema->throw_exception(@_);
1486 # XXX: FIXME: Attributes docs need clearing up
1490 The resultset takes various attributes that modify its behavior. Here's an
1497 =item Value: ($order_by | \@order_by)
1501 Which column(s) to order the results by. This is currently passed
1502 through directly to SQL, so you can give e.g. C<year DESC> for a
1503 descending order on the column `year'.
1509 =item Value: \@columns
1513 Shortcut to request a particular set of columns to be retrieved. Adds
1514 C<me.> onto the start of any column without a C<.> in it and sets C<select>
1515 from that, then auto-populates C<as> from C<select> as normal. (You may also
1516 use the C<cols> attribute, as in earlier versions of DBIC.)
1518 =head2 include_columns
1522 =item Value: \@columns
1526 Shortcut to include additional columns in the returned results - for example
1528 $schema->resultset('CD')->search(undef, {
1529 include_columns => ['artist.name'],
1533 would return all CDs and include a 'name' column to the information
1534 passed to object inflation
1540 =item Value: \@select_columns
1544 Indicates which columns should be selected from the storage. You can use
1545 column names, or in the case of RDBMS back ends, function or stored procedure
1548 $rs = $schema->resultset('Employee')->search(undef, {
1551 { count => 'employeeid' },
1556 When you use function/stored procedure names and do not supply an C<as>
1557 attribute, the column names returned are storage-dependent. E.g. MySQL would
1558 return a column named C<count(employeeid)> in the above example.
1564 =item Value: \@inflation_names
1568 Indicates column names for object inflation. This is used in conjunction with
1569 C<select>, usually when C<select> contains one or more function or stored
1572 $rs = $schema->resultset('Employee')->search(undef, {
1575 { count => 'employeeid' }
1577 as => ['name', 'employee_count'],
1580 my $employee = $rs->first(); # get the first Employee
1582 If the object against which the search is performed already has an accessor
1583 matching a column name specified in C<as>, the value can be retrieved using
1584 the accessor as normal:
1586 my $name = $employee->name();
1588 If on the other hand an accessor does not exist in the object, you need to
1589 use C<get_column> instead:
1591 my $employee_count = $employee->get_column('employee_count');
1593 You can create your own accessors if required - see
1594 L<DBIx::Class::Manual::Cookbook> for details.
1596 Please note: This will NOT insert an C<AS employee_count> into the SQL statement
1597 produced, it is used for internal access only. Thus attempting to use the accessor
1598 in an C<order_by> clause or similar will fail misrably.
1604 =item Value: ($rel_name | \@rel_names | \%rel_names)
1608 Contains a list of relationships that should be joined for this query. For
1611 # Get CDs by Nine Inch Nails
1612 my $rs = $schema->resultset('CD')->search(
1613 { 'artist.name' => 'Nine Inch Nails' },
1614 { join => 'artist' }
1617 Can also contain a hash reference to refer to the other relation's relations.
1620 package MyApp::Schema::Track;
1621 use base qw/DBIx::Class/;
1622 __PACKAGE__->table('track');
1623 __PACKAGE__->add_columns(qw/trackid cd position title/);
1624 __PACKAGE__->set_primary_key('trackid');
1625 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
1628 # In your application
1629 my $rs = $schema->resultset('Artist')->search(
1630 { 'track.title' => 'Teardrop' },
1632 join => { cd => 'track' },
1633 order_by => 'artist.name',
1637 If the same join is supplied twice, it will be aliased to <rel>_2 (and
1638 similarly for a third time). For e.g.
1640 my $rs = $schema->resultset('Artist')->search({
1641 'cds.title' => 'Down to Earth',
1642 'cds_2.title' => 'Popular',
1644 join => [ qw/cds cds/ ],
1647 will return a set of all artists that have both a cd with title 'Down
1648 to Earth' and a cd with title 'Popular'.
1650 If you want to fetch related objects from other tables as well, see C<prefetch>
1657 =item Value: ($rel_name | \@rel_names | \%rel_names)
1661 Contains one or more relationships that should be fetched along with the main
1662 query (when they are accessed afterwards they will have already been
1663 "prefetched"). This is useful for when you know you will need the related
1664 objects, because it saves at least one query:
1666 my $rs = $schema->resultset('Tag')->search(
1675 The initial search results in SQL like the following:
1677 SELECT tag.*, cd.*, artist.* FROM tag
1678 JOIN cd ON tag.cd = cd.cdid
1679 JOIN artist ON cd.artist = artist.artistid
1681 L<DBIx::Class> has no need to go back to the database when we access the
1682 C<cd> or C<artist> relationships, which saves us two SQL statements in this
1685 Simple prefetches will be joined automatically, so there is no need
1686 for a C<join> attribute in the above search. If you're prefetching to
1687 depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
1688 specify the join as well.
1690 C<prefetch> can be used with the following relationship types: C<belongs_to>,
1691 C<has_one> (or if you're using C<add_relationship>, any relationship declared
1692 with an accessor type of 'single' or 'filter').
1702 Makes the resultset paged and specifies the page to retrieve. Effectively
1703 identical to creating a non-pages resultset and then calling ->page($page)
1714 Specifes the maximum number of rows for direct retrieval or the number of
1715 rows per page if the page attribute or method is used.
1721 =item Value: \@columns
1725 A arrayref of columns to group by. Can include columns of joined tables.
1727 group_by => [qw/ column1 column2 ... /]
1733 =item Value: $condition
1737 HAVING is a select statement attribute that is applied between GROUP BY and
1738 ORDER BY. It is applied to the after the grouping calculations have been
1741 having => { 'count(employee)' => { '>=', 100 } }
1747 =item Value: (0 | 1)
1751 Set to 1 to group by all columns.
1755 Set to 1 to cache search results. This prevents extra SQL queries if you
1756 revisit rows in your ResultSet:
1758 my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
1760 while( my $artist = $resultset->next ) {
1764 $rs->first; # without cache, this would issue a query
1766 By default, searches are not cached.
1768 For more examples of using these attributes, see
1769 L<DBIx::Class::Manual::Cookbook>.
1775 =item Value: \@from_clause
1779 The C<from> attribute gives you manual control over the C<FROM> clause of SQL
1780 statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN>
1783 NOTE: Use this on your own risk. This allows you to shoot off your foot!
1785 C<join> will usually do what you need and it is strongly recommended that you
1786 avoid using C<from> unless you cannot achieve the desired result using C<join>.
1787 And we really do mean "cannot", not just tried and failed. Attempting to use
1788 this because you're having problems with C<join> is like trying to use x86
1789 ASM because you've got a syntax error in your C. Trust us on this.
1791 Now, if you're still really, really sure you need to use this (and if you're
1792 not 100% sure, ask the mailing list first), here's an explanation of how this
1795 The syntax is as follows -
1798 { <alias1> => <table1> },
1800 { <alias2> => <table2>, -join_type => 'inner|left|right' },
1801 [], # nested JOIN (optional)
1802 { <table1.column1> => <table2.column2>, ... (more conditions) },
1804 # More of the above [ ] may follow for additional joins
1811 ON <table1.column1> = <table2.column2>
1812 <more joins may follow>
1814 An easy way to follow the examples below is to remember the following:
1816 Anything inside "[]" is a JOIN
1817 Anything inside "{}" is a condition for the enclosing JOIN
1819 The following examples utilize a "person" table in a family tree application.
1820 In order to express parent->child relationships, this table is self-joined:
1822 # Person->belongs_to('father' => 'Person');
1823 # Person->belongs_to('mother' => 'Person');
1825 C<from> can be used to nest joins. Here we return all children with a father,
1826 then search against all mothers of those children:
1828 $rs = $schema->resultset('Person')->search(
1831 alias => 'mother', # alias columns in accordance with "from"
1833 { mother => 'person' },
1836 { child => 'person' },
1838 { father => 'person' },
1839 { 'father.person_id' => 'child.father_id' }
1842 { 'mother.person_id' => 'child.mother_id' }
1849 # SELECT mother.* FROM person mother
1852 # JOIN person father
1853 # ON ( father.person_id = child.father_id )
1855 # ON ( mother.person_id = child.mother_id )
1857 The type of any join can be controlled manually. To search against only people
1858 with a father in the person table, we could explicitly use C<INNER JOIN>:
1860 $rs = $schema->resultset('Person')->search(
1863 alias => 'child', # alias columns in accordance with "from"
1865 { child => 'person' },
1867 { father => 'person', -join_type => 'inner' },
1868 { 'father.id' => 'child.father_id' }
1875 # SELECT child.* FROM person child
1876 # INNER JOIN person father ON child.father_id = father.id