1 package DBIx::Class::ResultSet;
9 use Carp::Clan qw/^DBIx::Class/;
10 use DBIx::Class::Exception;
13 use DBIx::Class::ResultSetColumn;
14 use DBIx::Class::ResultSourceHandle;
17 use base qw/DBIx::Class/;
19 __PACKAGE__->mk_group_accessors('simple' => qw/_result_class _source_handle/);
23 DBIx::Class::ResultSet - Represents a query used for fetching a set of results.
27 my $users_rs = $schema->resultset('User');
28 my $registered_users_rs = $schema->resultset('User')->search({ registered => 1 });
29 my @cds_in_2005 = $schema->resultset('CD')->search({ year => 2005 })->all();
33 A ResultSet is an object which stores a set of conditions representing
34 a query. It is the backbone of DBIx::Class (i.e. the really
35 important/useful bit).
37 No SQL is executed on the database when a ResultSet is created, it
38 just stores all the conditions needed to create the query.
40 A basic ResultSet representing the data of an entire table is returned
41 by calling C<resultset> on a L<DBIx::Class::Schema> and passing in a
42 L<Source|DBIx::Class::Manual::Glossary/Source> name.
44 my $users_rs = $schema->resultset('User');
46 A new ResultSet is returned from calling L</search> on an existing
47 ResultSet. The new one will contain all the conditions of the
48 original, plus any new conditions added in the C<search> call.
50 A ResultSet also incorporates an implicit iterator. L</next> and L</reset>
51 can be used to walk through all the L<DBIx::Class::Row>s the ResultSet
54 The query that the ResultSet represents is B<only> executed against
55 the database when these methods are called:
56 L</find> L</next> L</all> L</first> L</single> L</count>
60 =head2 Chaining resultsets
62 Let's say you've got a query that needs to be run to return some data
63 to the user. But, you have an authorization system in place that
64 prevents certain users from seeing certain information. So, you want
65 to construct the basic query in one method, but add constraints to it in
70 my $request = $self->get_request; # Get a request object somehow.
71 my $schema = $self->get_schema; # Get the DBIC schema object somehow.
73 my $cd_rs = $schema->resultset('CD')->search({
74 title => $request->param('title'),
75 year => $request->param('year'),
78 $self->apply_security_policy( $cd_rs );
83 sub apply_security_policy {
92 =head3 Resolving conditions and attributes
94 When a resultset is chained from another resultset, conditions and
95 attributes with the same keys need resolving.
97 L</join>, L</prefetch>, L</+select>, L</+as> attributes are merged
98 into the existing ones from the original resultset.
100 The L</where>, L</having> attribute, and any search conditions are
101 merged with an SQL C<AND> to the existing condition from the original
104 All other attributes are overridden by any new ones supplied in the
107 =head2 Multiple queries
109 Since a resultset just defines a query, you can do all sorts of
110 things with it with the same object.
112 # Don't hit the DB yet.
113 my $cd_rs = $schema->resultset('CD')->search({
114 title => 'something',
118 # Each of these hits the DB individually.
119 my $count = $cd_rs->count;
120 my $most_recent = $cd_rs->get_column('date_released')->max();
121 my @records = $cd_rs->all;
123 And it's not just limited to SELECT statements.
129 $cd_rs->create({ artist => 'Fred' });
131 Which is the same as:
133 $schema->resultset('CD')->create({
134 title => 'something',
139 See: L</search>, L</count>, L</get_column>, L</all>, L</create>.
143 If a resultset is used in a numeric context it returns the L</count>.
144 However, if it is used in a booleand context it is always true. So if
145 you want to check if a resultset has any results use C<if $rs != 0>.
146 C<if $rs> will always be true.
154 =item Arguments: $source, \%$attrs
156 =item Return Value: $rs
160 The resultset constructor. Takes a source object (usually a
161 L<DBIx::Class::ResultSourceProxy::Table>) and an attribute hash (see
162 L</ATTRIBUTES> below). Does not perform any queries -- these are
163 executed as needed by the other methods.
165 Generally you won't need to construct a resultset manually. You'll
166 automatically get one from e.g. a L</search> called in scalar context:
168 my $rs = $schema->resultset('CD')->search({ title => '100th Window' });
170 IMPORTANT: If called on an object, proxies to new_result instead so
172 my $cd = $schema->resultset('CD')->new({ title => 'Spoon' });
174 will return a CD object, not a ResultSet.
180 return $class->new_result(@_) if ref $class;
182 my ($source, $attrs) = @_;
183 $source = $source->handle
184 unless $source->isa('DBIx::Class::ResultSourceHandle');
185 $attrs = { %{$attrs||{}} };
187 if ($attrs->{page}) {
188 $attrs->{rows} ||= 10;
191 $attrs->{alias} ||= 'me';
193 # Creation of {} and bless separated to mitigate RH perl bug
194 # see https://bugzilla.redhat.com/show_bug.cgi?id=196836
196 _source_handle => $source,
197 cond => $attrs->{where},
206 $attrs->{result_class} || $source->resolve->result_class
216 =item Arguments: $cond, \%attrs?
218 =item Return Value: $resultset (scalar context), @row_objs (list context)
222 my @cds = $cd_rs->search({ year => 2001 }); # "... WHERE year = 2001"
223 my $new_rs = $cd_rs->search({ year => 2005 });
225 my $new_rs = $cd_rs->search([ { year => 2005 }, { year => 2004 } ]);
226 # year = 2005 OR year = 2004
228 If you need to pass in additional attributes but no additional condition,
229 call it as C<search(undef, \%attrs)>.
231 # "SELECT name, artistid FROM $artist_table"
232 my @all_artists = $schema->resultset('Artist')->search(undef, {
233 columns => [qw/name artistid/],
236 For a list of attributes that can be passed to C<search>, see
237 L</ATTRIBUTES>. For more examples of using this function, see
238 L<Searching|DBIx::Class::Manual::Cookbook/Searching>. For a complete
239 documentation for the first argument, see L<SQL::Abstract>.
241 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
247 my $rs = $self->search_rs( @_ );
248 return (wantarray ? $rs->all : $rs);
255 =item Arguments: $cond, \%attrs?
257 =item Return Value: $resultset
261 This method does the same exact thing as search() except it will
262 always return a resultset, even in list context.
269 # Special-case handling for (undef, undef).
270 if ( @_ == 2 && !defined $_[1] && !defined $_[0] ) {
275 $attrs = pop(@_) if @_ > 1 and ref $_[$#_] eq 'HASH';
276 my $our_attrs = { %{$self->{attrs}} };
277 my $having = delete $our_attrs->{having};
278 my $where = delete $our_attrs->{where};
282 my %safe = (alias => 1, cache => 1);
285 (@_ && defined($_[0])) # @_ == () or (undef)
287 (keys %$attrs # empty attrs or only 'safe' attrs
288 && List::Util::first { !$safe{$_} } keys %$attrs)
290 # no search, effectively just a clone
291 $rows = $self->get_cache;
294 my $new_attrs = { %{$our_attrs}, %{$attrs} };
296 # merge new attrs into inherited
297 foreach my $key (qw/join prefetch +select +as bind/) {
298 next unless exists $attrs->{$key};
299 $new_attrs->{$key} = $self->_merge_attr($our_attrs->{$key}, $attrs->{$key});
304 (@_ == 1 || ref $_[0] eq "HASH")
306 (ref $_[0] eq 'HASH')
308 (keys %{ $_[0] } > 0)
316 ? $self->throw_exception("Odd number of arguments to search")
323 if (defined $where) {
324 $new_attrs->{where} = (
325 defined $new_attrs->{where}
328 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
329 } $where, $new_attrs->{where}
336 $new_attrs->{where} = (
337 defined $new_attrs->{where}
340 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
341 } $cond, $new_attrs->{where}
347 if (defined $having) {
348 $new_attrs->{having} = (
349 defined $new_attrs->{having}
352 ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_
353 } $having, $new_attrs->{having}
359 my $rs = (ref $self)->new($self->result_source, $new_attrs);
361 $rs->set_cache($rows) if ($rows);
366 =head2 search_literal
370 =item Arguments: $sql_fragment, @bind_values
372 =item Return Value: $resultset (scalar context), @row_objs (list context)
376 my @cds = $cd_rs->search_literal('year = ? AND title = ?', qw/2001 Reload/);
377 my $newrs = $artist_rs->search_literal('name = ?', 'Metallica');
379 Pass a literal chunk of SQL to be added to the conditional part of the
382 CAVEAT: C<search_literal> is provided for Class::DBI compatibility and should
383 only be used in that context. C<search_literal> is a convenience method.
384 It is equivalent to calling $schema->search(\[]), but if you want to ensure
385 columns are bound correctly, use C<search>.
387 Example of how to use C<search> instead of C<search_literal>
389 my @cds = $cd_rs->search_literal('cdid = ? AND (artist = ? OR artist = ?)', (2, 1, 2));
390 my @cds = $cd_rs->search(\[ 'cdid = ? AND (artist = ? OR artist = ?)', [ 'cdid', 2 ], [ 'artist', 1 ], [ 'artist', 2 ] ]);
393 See L<DBIx::Class::Manual::Cookbook/Searching> and
394 L<DBIx::Class::Manual::FAQ/Searching> for searching techniques that do not
395 require C<search_literal>.
400 my ($self, $sql, @bind) = @_;
402 if ( @bind && ref($bind[-1]) eq 'HASH' ) {
405 return $self->search(\[ $sql, map [ __DUMMY__ => $_ ], @bind ], ($attr || () ));
412 =item Arguments: @values | \%cols, \%attrs?
414 =item Return Value: $row_object | undef
418 Finds a row based on its primary key or unique constraint. For example, to find
419 a row by its primary key:
421 my $cd = $schema->resultset('CD')->find(5);
423 You can also find a row by a specific unique constraint using the C<key>
424 attribute. For example:
426 my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', {
427 key => 'cd_artist_title'
430 Additionally, you can specify the columns explicitly by name:
432 my $cd = $schema->resultset('CD')->find(
434 artist => 'Massive Attack',
435 title => 'Mezzanine',
437 { key => 'cd_artist_title' }
440 If the C<key> is specified as C<primary>, it searches only on the primary key.
442 If no C<key> is specified, it searches on all unique constraints defined on the
443 source for which column data is provided, including the primary key.
445 If your table does not have a primary key, you B<must> provide a value for the
446 C<key> attribute matching one of the unique constraints on the source.
448 In addition to C<key>, L</find> recognizes and applies standard
449 L<resultset attributes|/ATTRIBUTES> in the same way as L</search> does.
451 Note: If your query does not return only one row, a warning is generated:
453 Query returned more than one row
455 See also L</find_or_create> and L</update_or_create>. For information on how to
456 declare unique constraints, see
457 L<DBIx::Class::ResultSource/add_unique_constraint>.
463 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
465 # Default to the primary key, but allow a specific key
466 my @cols = exists $attrs->{key}
467 ? $self->result_source->unique_constraint_columns($attrs->{key})
468 : $self->result_source->primary_columns;
469 $self->throw_exception(
470 "Can't find unless a primary key is defined or unique constraint is specified"
473 # Parse out a hashref from input
475 if (ref $_[0] eq 'HASH') {
476 $input_query = { %{$_[0]} };
478 elsif (@_ == @cols) {
480 @{$input_query}{@cols} = @_;
483 # Compatibility: Allow e.g. find(id => $value)
484 carp "Find by key => value deprecated; please use a hashref instead";
488 my (%related, $info);
490 KEY: foreach my $key (keys %$input_query) {
491 if (ref($input_query->{$key})
492 && ($info = $self->result_source->relationship_info($key))) {
493 my $val = delete $input_query->{$key};
494 next KEY if (ref($val) eq 'ARRAY'); # has_many for multi_create
495 my $rel_q = $self->result_source->_resolve_condition(
496 $info->{cond}, $val, $key
498 die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY';
499 @related{keys %$rel_q} = values %$rel_q;
502 if (my @keys = keys %related) {
503 @{$input_query}{@keys} = values %related;
507 # Build the final query: Default to the disjunction of the unique queries,
508 # but allow the input query in case the ResultSet defines the query or the
509 # user is abusing find
510 my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias};
512 if (exists $attrs->{key}) {
513 my @unique_cols = $self->result_source->unique_constraint_columns($attrs->{key});
514 my $unique_query = $self->_build_unique_query($input_query, \@unique_cols);
515 $query = $self->_add_alias($unique_query, $alias);
517 elsif ($self->{attrs}{accessor} and $self->{attrs}{accessor} eq 'single') {
518 # This means that we got here after a merger of relationship conditions
519 # in ::Relationship::Base::search_related (the row method), and furthermore
520 # the relationship is of the 'single' type. This means that the condition
521 # provided by the relationship (already attached to $self) is sufficient,
522 # as there can be only one row in the databse that would satisfy the
526 my @unique_queries = $self->_unique_queries($input_query, $attrs);
527 $query = @unique_queries
528 ? [ map { $self->_add_alias($_, $alias) } @unique_queries ]
529 : $self->_add_alias($input_query, $alias);
533 my $rs = $self->search ($query, {result_class => $self->result_class, %$attrs});
534 if (keys %{$rs->_resolved_attrs->{collapse}}) {
536 carp "Query returned more than one row" if $rs->next;
546 # Add the specified alias to the specified query hash. A copy is made so the
547 # original query is not modified.
550 my ($self, $query, $alias) = @_;
552 my %aliased = %$query;
553 foreach my $col (grep { ! m/\./ } keys %aliased) {
554 $aliased{"$alias.$col"} = delete $aliased{$col};
562 # Build a list of queries which satisfy unique constraints.
564 sub _unique_queries {
565 my ($self, $query, $attrs) = @_;
567 my @constraint_names = exists $attrs->{key}
569 : $self->result_source->unique_constraint_names;
571 my $where = $self->_collapse_cond($self->{attrs}{where} || {});
572 my $num_where = scalar keys %$where;
574 my (@unique_queries, %seen_column_combinations);
575 foreach my $name (@constraint_names) {
576 my @constraint_cols = $self->result_source->unique_constraint_columns($name);
578 my $constraint_sig = join "\x00", sort @constraint_cols;
579 next if $seen_column_combinations{$constraint_sig}++;
581 my $unique_query = $self->_build_unique_query($query, \@constraint_cols);
583 my $num_cols = scalar @constraint_cols;
584 my $num_query = scalar keys %$unique_query;
586 my $total = $num_query + $num_where;
587 if ($num_query && ($num_query == $num_cols || $total == $num_cols)) {
588 # The query is either unique on its own or is unique in combination with
589 # the existing where clause
590 push @unique_queries, $unique_query;
594 return @unique_queries;
597 # _build_unique_query
599 # Constrain the specified query hash based on the specified column names.
601 sub _build_unique_query {
602 my ($self, $query, $unique_cols) = @_;
605 map { $_ => $query->{$_} }
606 grep { exists $query->{$_} }
611 =head2 search_related
615 =item Arguments: $rel, $cond, \%attrs?
617 =item Return Value: $new_resultset
621 $new_rs = $cd_rs->search_related('artist', {
625 Searches the specified relationship, optionally specifying a condition and
626 attributes for matching records. See L</ATTRIBUTES> for more information.
631 return shift->related_resultset(shift)->search(@_);
634 =head2 search_related_rs
636 This method works exactly the same as search_related, except that
637 it guarantees a restultset, even in list context.
641 sub search_related_rs {
642 return shift->related_resultset(shift)->search_rs(@_);
649 =item Arguments: none
651 =item Return Value: $cursor
655 Returns a storage-driven cursor to the given resultset. See
656 L<DBIx::Class::Cursor> for more information.
663 my $attrs = $self->_resolved_attrs_copy;
665 return $self->{cursor}
666 ||= $self->result_source->storage->select($attrs->{from}, $attrs->{select},
667 $attrs->{where},$attrs);
674 =item Arguments: $cond?
676 =item Return Value: $row_object?
680 my $cd = $schema->resultset('CD')->single({ year => 2001 });
682 Inflates the first result without creating a cursor if the resultset has
683 any records in it; if not returns nothing. Used by L</find> as a lean version of
686 While this method can take an optional search condition (just like L</search>)
687 being a fast-code-path it does not recognize search attributes. If you need to
688 add extra joins or similar, call L</search> and then chain-call L</single> on the
689 L<DBIx::Class::ResultSet> returned.
695 As of 0.08100, this method enforces the assumption that the preceeding
696 query returns only one row. If more than one row is returned, you will receive
699 Query returned more than one row
701 In this case, you should be using L</next> or L</find> instead, or if you really
702 know what you are doing, use the L</rows> attribute to explicitly limit the size
705 This method will also throw an exception if it is called on a resultset prefetching
706 has_many, as such a prefetch implies fetching multiple rows from the database in
707 order to assemble the resulting object.
714 my ($self, $where) = @_;
716 $self->throw_exception('single() only takes search conditions, no attributes. You want ->search( $cond, $attrs )->single()');
719 my $attrs = $self->_resolved_attrs_copy;
721 if (keys %{$attrs->{collapse}}) {
722 $self->throw_exception(
723 'single() can not be used on resultsets prefetching has_many. Use find( \%cond ) or next() instead'
728 if (defined $attrs->{where}) {
731 [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
732 $where, delete $attrs->{where} ]
735 $attrs->{where} = $where;
739 # XXX: Disabled since it doesn't infer uniqueness in all cases
740 # unless ($self->_is_unique_query($attrs->{where})) {
741 # carp "Query not guaranteed to return a single row"
742 # . "; please declare your unique constraints or use search instead";
745 my @data = $self->result_source->storage->select_single(
746 $attrs->{from}, $attrs->{select},
747 $attrs->{where}, $attrs
750 return (@data ? ($self->_construct_object(@data))[0] : undef);
756 # Try to determine if the specified query is guaranteed to be unique, based on
757 # the declared unique constraints.
759 sub _is_unique_query {
760 my ($self, $query) = @_;
762 my $collapsed = $self->_collapse_query($query);
763 my $alias = $self->{attrs}{alias};
765 foreach my $name ($self->result_source->unique_constraint_names) {
766 my @unique_cols = map {
768 } $self->result_source->unique_constraint_columns($name);
770 # Count the values for each unique column
771 my %seen = map { $_ => 0 } @unique_cols;
773 foreach my $key (keys %$collapsed) {
774 my $aliased = $key =~ /\./ ? $key : "$alias.$key";
775 next unless exists $seen{$aliased}; # Additional constraints are okay
776 $seen{$aliased} = scalar keys %{ $collapsed->{$key} };
779 # If we get 0 or more than 1 value for a column, it's not necessarily unique
780 return 1 unless grep { $_ != 1 } values %seen;
788 # Recursively collapse the query, accumulating values for each column.
790 sub _collapse_query {
791 my ($self, $query, $collapsed) = @_;
795 if (ref $query eq 'ARRAY') {
796 foreach my $subquery (@$query) {
797 next unless ref $subquery; # -or
798 $collapsed = $self->_collapse_query($subquery, $collapsed);
801 elsif (ref $query eq 'HASH') {
802 if (keys %$query and (keys %$query)[0] eq '-and') {
803 foreach my $subquery (@{$query->{-and}}) {
804 $collapsed = $self->_collapse_query($subquery, $collapsed);
808 foreach my $col (keys %$query) {
809 my $value = $query->{$col};
810 $collapsed->{$col}{$value}++;
822 =item Arguments: $cond?
824 =item Return Value: $resultsetcolumn
828 my $max_length = $rs->get_column('length')->max;
830 Returns a L<DBIx::Class::ResultSetColumn> instance for a column of the ResultSet.
835 my ($self, $column) = @_;
836 my $new = DBIx::Class::ResultSetColumn->new($self, $column);
844 =item Arguments: $cond, \%attrs?
846 =item Return Value: $resultset (scalar context), @row_objs (list context)
850 # WHERE title LIKE '%blue%'
851 $cd_rs = $rs->search_like({ title => '%blue%'});
853 Performs a search, but uses C<LIKE> instead of C<=> as the condition. Note
854 that this is simply a convenience method retained for ex Class::DBI users.
855 You most likely want to use L</search> with specific operators.
857 For more information, see L<DBIx::Class::Manual::Cookbook>.
859 This method is deprecated and will be removed in 0.09. Use L</search()>
860 instead. An example conversion is:
862 ->search_like({ foo => 'bar' });
866 ->search({ foo => { like => 'bar' } });
873 'search_like() is deprecated and will be removed in DBIC version 0.09.'
874 .' Instead use ->search({ x => { -like => "y%" } })'
875 .' (note the outer pair of {}s - they are important!)'
877 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
878 my $query = ref $_[0] eq 'HASH' ? { %{shift()} }: {@_};
879 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
880 return $class->search($query, { %$attrs });
887 =item Arguments: $first, $last
889 =item Return Value: $resultset (scalar context), @row_objs (list context)
893 Returns a resultset or object list representing a subset of elements from the
894 resultset slice is called on. Indexes are from 0, i.e., to get the first
897 my ($one, $two, $three) = $rs->slice(0, 2);
902 my ($self, $min, $max) = @_;
903 my $attrs = {}; # = { %{ $self->{attrs} || {} } };
904 $attrs->{offset} = $self->{attrs}{offset} || 0;
905 $attrs->{offset} += $min;
906 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
907 return $self->search(undef(), $attrs);
908 #my $slice = (ref $self)->new($self->result_source, $attrs);
909 #return (wantarray ? $slice->all : $slice);
916 =item Arguments: none
918 =item Return Value: $result?
922 Returns the next element in the resultset (C<undef> is there is none).
924 Can be used to efficiently iterate over records in the resultset:
926 my $rs = $schema->resultset('CD')->search;
927 while (my $cd = $rs->next) {
931 Note that you need to store the resultset object, and call C<next> on it.
932 Calling C<< resultset('Table')->next >> repeatedly will always return the
933 first record from the resultset.
939 if (my $cache = $self->get_cache) {
940 $self->{all_cache_position} ||= 0;
941 return $cache->[$self->{all_cache_position}++];
943 if ($self->{attrs}{cache}) {
944 $self->{all_cache_position} = 1;
945 return ($self->all)[0];
947 if ($self->{stashed_objects}) {
948 my $obj = shift(@{$self->{stashed_objects}});
949 delete $self->{stashed_objects} unless @{$self->{stashed_objects}};
953 exists $self->{stashed_row}
954 ? @{delete $self->{stashed_row}}
955 : $self->cursor->next
957 return undef unless (@row);
958 my ($row, @more) = $self->_construct_object(@row);
959 $self->{stashed_objects} = \@more if @more;
963 sub _construct_object {
964 my ($self, @row) = @_;
966 my $info = $self->_collapse_result($self->{_attrs}{as}, \@row)
968 my @new = $self->result_class->inflate_result($self->result_source, @$info);
969 @new = $self->{_attrs}{record_filter}->(@new)
970 if exists $self->{_attrs}{record_filter};
974 sub _collapse_result {
975 my ($self, $as_proto, $row) = @_;
979 # 'foo' => [ undef, 'foo' ]
980 # 'foo.bar' => [ 'foo', 'bar' ]
981 # 'foo.bar.baz' => [ 'foo.bar', 'baz' ]
983 my @construct_as = map { [ (/^(?:(.*)\.)?([^.]+)$/) ] } @$as_proto;
985 my %collapse = %{$self->{_attrs}{collapse}||{}};
989 # if we're doing collapsing (has_many prefetch) we need to grab records
990 # until the PK changes, so fill @pri_index. if not, we leave it empty so
991 # we know we don't have to bother.
993 # the reason for not using the collapse stuff directly is because if you
994 # had for e.g. two artists in a row with no cds, the collapse info for
995 # both would be NULL (undef) so you'd lose the second artist
997 # store just the index so we can check the array positions from the row
998 # without having to contruct the full hash
1000 if (keys %collapse) {
1001 my %pri = map { ($_ => 1) } $self->result_source->primary_columns;
1002 foreach my $i (0 .. $#construct_as) {
1003 next if defined($construct_as[$i][0]); # only self table
1004 if (delete $pri{$construct_as[$i][1]}) {
1005 push(@pri_index, $i);
1007 last unless keys %pri; # short circuit (Johnny Five Is Alive!)
1011 # no need to do an if, it'll be empty if @pri_index is empty anyway
1013 my %pri_vals = map { ($_ => $copy[$_]) } @pri_index;
1017 do { # no need to check anything at the front, we always want the first row
1021 foreach my $this_as (@construct_as) {
1022 $const{$this_as->[0]||''}{$this_as->[1]} = shift(@copy);
1025 push(@const_rows, \%const);
1027 } until ( # no pri_index => no collapse => drop straight out
1030 do { # get another row, stash it, drop out if different PK
1032 @copy = $self->cursor->next;
1033 $self->{stashed_row} = \@copy;
1035 # last thing in do block, counts as true if anything doesn't match
1037 # check xor defined first for NULL vs. NOT NULL then if one is
1038 # defined the other must be so check string equality
1041 (defined $pri_vals{$_} ^ defined $copy[$_])
1042 || (defined $pri_vals{$_} && ($pri_vals{$_} ne $copy[$_]))
1047 my $alias = $self->{attrs}{alias};
1054 foreach my $const (@const_rows) {
1055 scalar @const_keys or do {
1056 @const_keys = sort { length($a) <=> length($b) } keys %$const;
1058 foreach my $key (@const_keys) {
1061 my @parts = split(/\./, $key);
1063 my $data = $const->{$key};
1064 foreach my $p (@parts) {
1065 $target = $target->[1]->{$p} ||= [];
1067 if ($cur eq ".${key}" && (my @ckey = @{$collapse{$cur}||[]})) {
1068 # collapsing at this point and on final part
1069 my $pos = $collapse_pos{$cur};
1070 CK: foreach my $ck (@ckey) {
1071 if (!defined $pos->{$ck} || $pos->{$ck} ne $data->{$ck}) {
1072 $collapse_pos{$cur} = $data;
1073 delete @collapse_pos{ # clear all positioning for sub-entries
1074 grep { m/^\Q${cur}.\E/ } keys %collapse_pos
1081 if (exists $collapse{$cur}) {
1082 $target = $target->[-1];
1085 $target->[0] = $data;
1087 $info->[0] = $const->{$key};
1095 =head2 result_source
1099 =item Arguments: $result_source?
1101 =item Return Value: $result_source
1105 An accessor for the primary ResultSource object from which this ResultSet
1112 =item Arguments: $result_class?
1114 =item Return Value: $result_class
1118 An accessor for the class to use when creating row objects. Defaults to
1119 C<< result_source->result_class >> - which in most cases is the name of the
1120 L<"table"|DBIx::Class::Manual::Glossary/"ResultSource"> class.
1122 Note that changing the result_class will also remove any components
1123 that were originally loaded in the source class via
1124 L<DBIx::Class::ResultSource/load_components>. Any overloaded methods
1125 in the original source class will not run.
1130 my ($self, $result_class) = @_;
1131 if ($result_class) {
1132 $self->ensure_class_loaded($result_class);
1133 $self->_result_class($result_class);
1135 $self->_result_class;
1142 =item Arguments: $cond, \%attrs??
1144 =item Return Value: $count
1148 Performs an SQL C<COUNT> with the same query as the resultset was built
1149 with to find the number of elements. Passing arguments is equivalent to
1150 C<< $rs->search ($cond, \%attrs)->count >>
1156 return $self->search(@_)->count if @_ and defined $_[0];
1157 return scalar @{ $self->get_cache } if $self->get_cache;
1159 my $attrs = $self->_resolved_attrs_copy;
1161 # this is a little optimization - it is faster to do the limit
1162 # adjustments in software, instead of a subquery
1163 my $rows = delete $attrs->{rows};
1164 my $offset = delete $attrs->{offset};
1167 if ($self->_has_resolved_attr (qw/collapse group_by/)) {
1168 $crs = $self->_count_subq_rs ($attrs);
1171 $crs = $self->_count_rs ($attrs);
1173 my $count = $crs->next;
1175 $count -= $offset if $offset;
1176 $count = $rows if $rows and $rows < $count;
1177 $count = 0 if ($count < 0);
1186 =item Arguments: $cond, \%attrs??
1188 =item Return Value: $count_rs
1192 Same as L</count> but returns a L<DBIx::Class::ResultSetColumn> object.
1193 This can be very handy for subqueries:
1195 ->search( { amount => $some_rs->count_rs->as_query } )
1197 As with regular resultsets the SQL query will be executed only after
1198 the resultset is accessed via L</next> or L</all>. That would return
1199 the same single value obtainable via L</count>.
1205 return $self->search(@_)->count_rs if @_;
1207 # this may look like a lack of abstraction (count() does about the same)
1208 # but in fact an _rs *must* use a subquery for the limits, as the
1209 # software based limiting can not be ported if this $rs is to be used
1210 # in a subquery itself (i.e. ->as_query)
1211 if ($self->_has_resolved_attr (qw/collapse group_by offset rows/)) {
1212 return $self->_count_subq_rs;
1215 return $self->_count_rs;
1220 # returns a ResultSetColumn object tied to the count query
1223 my ($self, $attrs) = @_;
1225 my $rsrc = $self->result_source;
1226 $attrs ||= $self->_resolved_attrs;
1228 my $tmp_attrs = { %$attrs };
1230 # take off any limits, record_filter is cdbi, and no point of ordering a count
1231 delete $tmp_attrs->{$_} for (qw/select as rows offset order_by record_filter/);
1233 # overwrite the selector (supplied by the storage)
1234 $tmp_attrs->{select} = $rsrc->storage->_count_select ($rsrc, $tmp_attrs);
1235 $tmp_attrs->{as} = 'count';
1237 my $tmp_rs = $rsrc->resultset_class->new($rsrc, $tmp_attrs)->get_column ('count');
1243 # same as above but uses a subquery
1245 sub _count_subq_rs {
1246 my ($self, $attrs) = @_;
1248 my $rsrc = $self->result_source;
1249 $attrs ||= $self->_resolved_attrs_copy;
1251 my $sub_attrs = { %$attrs };
1253 # extra selectors do not go in the subquery and there is no point of ordering it
1254 delete $sub_attrs->{$_} for qw/collapse select _prefetch_select as order_by/;
1256 # if we multi-prefetch we group_by primary keys only as this is what we would
1257 # get out of the rs via ->next/->all. We *DO WANT* to clobber old group_by regardless
1258 if ( keys %{$attrs->{collapse}} ) {
1259 $sub_attrs->{group_by} = [ map { "$attrs->{alias}.$_" } ($rsrc->primary_columns) ]
1262 $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs);
1264 # this is so that the query can be simplified e.g.
1265 # * ordering can be thrown away in things like Top limit
1266 $sub_attrs->{-for_count_only} = 1;
1268 my $sub_rs = $rsrc->resultset_class->new ($rsrc, $sub_attrs);
1271 -alias => 'count_subq',
1272 -source_handle => $rsrc->handle,
1273 count_subq => $sub_rs->as_query,
1276 # the subquery replaces this
1277 delete $attrs->{$_} for qw/where bind collapse group_by having having_bind rows offset/;
1279 return $self->_count_rs ($attrs);
1286 =head2 count_literal
1290 =item Arguments: $sql_fragment, @bind_values
1292 =item Return Value: $count
1296 Counts the results in a literal query. Equivalent to calling L</search_literal>
1297 with the passed arguments, then L</count>.
1301 sub count_literal { shift->search_literal(@_)->count; }
1307 =item Arguments: none
1309 =item Return Value: @objects
1313 Returns all elements in the resultset. Called implicitly if the resultset
1314 is returned in list context.
1321 $self->throw_exception("all() doesn't take any arguments, you probably wanted ->search(...)->all()");
1324 return @{ $self->get_cache } if $self->get_cache;
1328 if (keys %{$self->_resolved_attrs->{collapse}}) {
1329 # Using $self->cursor->all is really just an optimisation.
1330 # If we're collapsing has_many prefetches it probably makes
1331 # very little difference, and this is cleaner than hacking
1332 # _construct_object to survive the approach
1333 $self->cursor->reset;
1334 my @row = $self->cursor->next;
1336 push(@obj, $self->_construct_object(@row));
1337 @row = (exists $self->{stashed_row}
1338 ? @{delete $self->{stashed_row}}
1339 : $self->cursor->next);
1342 @obj = map { $self->_construct_object(@$_) } $self->cursor->all;
1345 $self->set_cache(\@obj) if $self->{attrs}{cache};
1354 =item Arguments: none
1356 =item Return Value: $self
1360 Resets the resultset's cursor, so you can iterate through the elements again.
1361 Implicitly resets the storage cursor, so a subsequent L</next> will trigger
1368 delete $self->{_attrs} if exists $self->{_attrs};
1369 $self->{all_cache_position} = 0;
1370 $self->cursor->reset;
1378 =item Arguments: none
1380 =item Return Value: $object?
1384 Resets the resultset and returns an object for the first result (if the
1385 resultset returns anything).
1390 return $_[0]->reset->next;
1396 # Determines whether and what type of subquery is required for the $rs operation.
1397 # If grouping is necessary either supplies its own, or verifies the current one
1398 # After all is done delegates to the proper storage method.
1400 sub _rs_update_delete {
1401 my ($self, $op, $values) = @_;
1403 my $rsrc = $self->result_source;
1405 # if a condition exists we need to strip all table qualifiers
1406 # if this is not possible we'll force a subquery below
1407 my $cond = $rsrc->schema->storage->_strip_cond_qualifiers ($self->{cond});
1409 my $needs_group_by_subq = $self->_has_resolved_attr (qw/collapse group_by -join/);
1410 my $needs_subq = $needs_group_by_subq || (not defined $cond) || $self->_has_resolved_attr(qw/row offset/);
1412 if ($needs_group_by_subq or $needs_subq) {
1414 # make a new $rs selecting only the PKs (that's all we really need)
1415 my $attrs = $self->_resolved_attrs_copy;
1417 delete $attrs->{$_} for qw/collapse select as/;
1418 $attrs->{columns} = [ map { "$attrs->{alias}.$_" } ($self->result_source->primary_columns) ];
1420 if ($needs_group_by_subq) {
1421 # make sure no group_by was supplied, or if there is one - make sure it matches
1422 # the columns compiled above perfectly. Anything else can not be sanely executed
1423 # on most databases so croak right then and there
1425 if (my $g = $attrs->{group_by}) {
1426 my @current_group_by = map
1427 { $_ =~ /\./ ? $_ : "$attrs->{alias}.$_" }
1432 join ("\x00", sort @current_group_by)
1434 join ("\x00", sort @{$attrs->{columns}} )
1436 $self->throw_exception (
1437 "You have just attempted a $op operation on a resultset which does group_by"
1438 . ' on columns other than the primary keys, while DBIC internally needs to retrieve'
1439 . ' the primary keys in a subselect. All sane RDBMS engines do not support this'
1440 . ' kind of queries. Please retry the operation with a modified group_by or'
1441 . ' without using one at all.'
1446 $attrs->{group_by} = $attrs->{columns};
1450 my $subrs = (ref $self)->new($rsrc, $attrs);
1452 return $self->result_source->storage->_subq_update_delete($subrs, $op, $values);
1455 return $rsrc->storage->$op(
1457 $op eq 'update' ? $values : (),
1467 =item Arguments: \%values
1469 =item Return Value: $storage_rv
1473 Sets the specified columns in the resultset to the supplied values in a
1474 single query. Return value will be true if the update succeeded or false
1475 if no records were updated; exact type of success value is storage-dependent.
1480 my ($self, $values) = @_;
1481 $self->throw_exception('Values for update must be a hash')
1482 unless ref $values eq 'HASH';
1484 return $self->_rs_update_delete ('update', $values);
1491 =item Arguments: \%values
1493 =item Return Value: 1
1497 Fetches all objects and updates them one at a time. Note that C<update_all>
1498 will run DBIC cascade triggers, while L</update> will not.
1503 my ($self, $values) = @_;
1504 $self->throw_exception('Values for update_all must be a hash')
1505 unless ref $values eq 'HASH';
1506 foreach my $obj ($self->all) {
1507 $obj->set_columns($values)->update;
1516 =item Arguments: none
1518 =item Return Value: $storage_rv
1522 Deletes the contents of the resultset from its result source. Note that this
1523 will not run DBIC cascade triggers. See L</delete_all> if you need triggers
1524 to run. See also L<DBIx::Class::Row/delete>.
1526 Return value will be the amount of rows deleted; exact type of return value
1527 is storage-dependent.
1533 $self->throw_exception('delete does not accept any arguments')
1536 return $self->_rs_update_delete ('delete');
1543 =item Arguments: none
1545 =item Return Value: 1
1549 Fetches all objects and deletes them one at a time. Note that C<delete_all>
1550 will run DBIC cascade triggers, while L</delete> will not.
1556 $self->throw_exception('delete_all does not accept any arguments')
1559 $_->delete for $self->all;
1567 =item Arguments: \@data;
1571 Accepts either an arrayref of hashrefs or alternatively an arrayref of arrayrefs.
1572 For the arrayref of hashrefs style each hashref should be a structure suitable
1573 forsubmitting to a $resultset->create(...) method.
1575 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
1576 to insert the data, as this is a faster method.
1578 Otherwise, each set of data is inserted into the database using
1579 L<DBIx::Class::ResultSet/create>, and the resulting objects are
1580 accumulated into an array. The array itself, or an array reference
1581 is returned depending on scalar or list context.
1583 Example: Assuming an Artist Class that has many CDs Classes relating:
1585 my $Artist_rs = $schema->resultset("Artist");
1587 ## Void Context Example
1588 $Artist_rs->populate([
1589 { artistid => 4, name => 'Manufactured Crap', cds => [
1590 { title => 'My First CD', year => 2006 },
1591 { title => 'Yet More Tweeny-Pop crap', year => 2007 },
1594 { artistid => 5, name => 'Angsty-Whiny Girl', cds => [
1595 { title => 'My parents sold me to a record company' ,year => 2005 },
1596 { title => 'Why Am I So Ugly?', year => 2006 },
1597 { title => 'I Got Surgery and am now Popular', year => 2007 }
1602 ## Array Context Example
1603 my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([
1604 { name => "Artist One"},
1605 { name => "Artist Two"},
1606 { name => "Artist Three", cds=> [
1607 { title => "First CD", year => 2007},
1608 { title => "Second CD", year => 2008},
1612 print $ArtistOne->name; ## response is 'Artist One'
1613 print $ArtistThree->cds->count ## reponse is '2'
1615 For the arrayref of arrayrefs style, the first element should be a list of the
1616 fieldsnames to which the remaining elements are rows being inserted. For
1619 $Arstist_rs->populate([
1620 [qw/artistid name/],
1621 [100, 'A Formally Unknown Singer'],
1622 [101, 'A singer that jumped the shark two albums ago'],
1623 [102, 'An actually cool singer.'],
1626 Please note an important effect on your data when choosing between void and
1627 wantarray context. Since void context goes straight to C<insert_bulk> in
1628 L<DBIx::Class::Storage::DBI> this will skip any component that is overriding
1629 C<insert>. So if you are using something like L<DBIx-Class-UUIDColumns> to
1630 create primary keys for you, you will find that your PKs are empty. In this
1631 case you will have to use the wantarray context in order to create those
1639 # cruft placed in standalone method
1640 my $data = $self->_normalize_populate_args(@_);
1642 if(defined wantarray) {
1644 foreach my $item (@$data) {
1645 push(@created, $self->create($item));
1647 return wantarray ? @created : \@created;
1649 my $first = $data->[0];
1651 # if a column is a registered relationship, and is a non-blessed hash/array, consider
1652 # it relationship data
1653 my (@rels, @columns);
1654 for (keys %$first) {
1655 my $ref = ref $first->{$_};
1656 $self->result_source->has_relationship($_) && ($ref eq 'ARRAY' or $ref eq 'HASH')
1662 my @pks = $self->result_source->primary_columns;
1664 ## do the belongs_to relationships
1665 foreach my $index (0..$#$data) {
1667 # delegate to create() for any dataset without primary keys with specified relationships
1668 if (grep { !defined $data->[$index]->{$_} } @pks ) {
1670 if (grep { ref $data->[$index]{$r} eq $_ } qw/HASH ARRAY/) { # a related set must be a HASH or AoH
1671 my @ret = $self->populate($data);
1677 foreach my $rel (@rels) {
1678 next unless ref $data->[$index]->{$rel} eq "HASH";
1679 my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
1680 my ($reverse) = keys %{$self->result_source->reverse_relationship_info($rel)};
1681 my $related = $result->result_source->_resolve_condition(
1682 $result->result_source->relationship_info($reverse)->{cond},
1687 delete $data->[$index]->{$rel};
1688 $data->[$index] = {%{$data->[$index]}, %$related};
1690 push @columns, keys %$related if $index == 0;
1694 ## inherit the data locked in the conditions of the resultset
1695 my ($rs_data) = $self->_merge_cond_with_data({});
1696 delete @{$rs_data}{@columns};
1697 my @inherit_cols = keys %$rs_data;
1698 my @inherit_data = values %$rs_data;
1700 ## do bulk insert on current row
1701 $self->result_source->storage->insert_bulk(
1702 $self->result_source,
1703 [@columns, @inherit_cols],
1704 [ map { [ @$_{@columns}, @inherit_data ] } @$data ],
1707 ## do the has_many relationships
1708 foreach my $item (@$data) {
1710 foreach my $rel (@rels) {
1711 next unless $item->{$rel} && ref $item->{$rel} eq "ARRAY";
1713 my $parent = $self->find({map { $_ => $item->{$_} } @pks})
1714 || $self->throw_exception('Cannot find the relating object.');
1716 my $child = $parent->$rel;
1718 my $related = $child->result_source->_resolve_condition(
1719 $parent->result_source->relationship_info($rel)->{cond},
1724 my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel});
1725 my @populate = map { {%$_, %$related} } @rows_to_add;
1727 $child->populate( \@populate );
1734 # populate() argumnets went over several incarnations
1735 # What we ultimately support is AoH
1736 sub _normalize_populate_args {
1737 my ($self, $arg) = @_;
1739 if (ref $arg eq 'ARRAY') {
1740 if (ref $arg->[0] eq 'HASH') {
1743 elsif (ref $arg->[0] eq 'ARRAY') {
1745 my @colnames = @{$arg->[0]};
1746 foreach my $values (@{$arg}[1 .. $#$arg]) {
1747 push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
1753 $self->throw_exception('Populate expects an arrayref of hashrefs or arrayref of arrayrefs');
1760 =item Arguments: none
1762 =item Return Value: $pager
1766 Return Value a L<Data::Page> object for the current resultset. Only makes
1767 sense for queries with a C<page> attribute.
1769 To get the full count of entries for a paged resultset, call
1770 C<total_entries> on the L<Data::Page> object.
1777 return $self->{pager} if $self->{pager};
1779 my $attrs = $self->{attrs};
1780 $self->throw_exception("Can't create pager for non-paged rs")
1781 unless $self->{attrs}{page};
1782 $attrs->{rows} ||= 10;
1784 # throw away the paging flags and re-run the count (possibly
1785 # with a subselect) to get the real total count
1786 my $count_attrs = { %$attrs };
1787 delete $count_attrs->{$_} for qw/rows offset page pager/;
1788 my $total_count = (ref $self)->new($self->result_source, $count_attrs)->count;
1790 return $self->{pager} = Data::Page->new(
1793 $self->{attrs}{page}
1801 =item Arguments: $page_number
1803 =item Return Value: $rs
1807 Returns a resultset for the $page_number page of the resultset on which page
1808 is called, where each page contains a number of rows equal to the 'rows'
1809 attribute set on the resultset (10 by default).
1814 my ($self, $page) = @_;
1815 return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
1822 =item Arguments: \%vals
1824 =item Return Value: $rowobject
1828 Creates a new row object in the resultset's result class and returns
1829 it. The row is not inserted into the database at this point, call
1830 L<DBIx::Class::Row/insert> to do that. Calling L<DBIx::Class::Row/in_storage>
1831 will tell you whether the row object has been inserted or not.
1833 Passes the hashref of input on to L<DBIx::Class::Row/new>.
1838 my ($self, $values) = @_;
1839 $self->throw_exception( "new_result needs a hash" )
1840 unless (ref $values eq 'HASH');
1842 my ($merged_cond, $cols_from_relations) = $self->_merge_cond_with_data($values);
1846 @$cols_from_relations
1847 ? (-cols_from_relations => $cols_from_relations)
1849 -source_handle => $self->_source_handle,
1850 -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
1853 return $self->result_class->new(\%new);
1856 # _merge_cond_with_data
1858 # Takes a simple hash of K/V data and returns its copy merged with the
1859 # condition already present on the resultset. Additionally returns an
1860 # arrayref of value/condition names, which were inferred from related
1861 # objects (this is needed for in-memory related objects)
1862 sub _merge_cond_with_data {
1863 my ($self, $data) = @_;
1865 my (%new_data, @cols_from_relations);
1867 my $alias = $self->{attrs}{alias};
1869 if (! defined $self->{cond}) {
1870 # just massage $data below
1872 elsif ($self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
1873 %new_data = %{ $self->{attrs}{related_objects} || {} }; # nothing might have been inserted yet
1874 @cols_from_relations = keys %new_data;
1876 elsif (ref $self->{cond} ne 'HASH') {
1877 $self->throw_exception(
1878 "Can't abstract implicit construct, resultset condition not a hash"
1882 # precendence must be given to passed values over values inherited from
1883 # the cond, so the order here is important.
1884 my $collapsed_cond = $self->_collapse_cond($self->{cond});
1885 my %implied = %{$self->_remove_alias($collapsed_cond, $alias)};
1887 while ( my($col, $value) = each %implied ) {
1888 if (ref($value) eq 'HASH' && keys(%$value) && (keys %$value)[0] eq '=') {
1889 $new_data{$col} = $value->{'='};
1892 $new_data{$col} = $value if $self->_is_deterministic_value($value);
1898 %{ $self->_remove_alias($data, $alias) },
1901 return (\%new_data, \@cols_from_relations);
1904 # _is_deterministic_value
1906 # Make an effor to strip non-deterministic values from the condition,
1907 # to make sure new_result chokes less
1909 sub _is_deterministic_value {
1912 my $ref_type = ref $value;
1913 return 1 if $ref_type eq '' || $ref_type eq 'SCALAR';
1914 return 1 if Scalar::Util::blessed($value);
1918 # _has_resolved_attr
1920 # determines if the resultset defines at least one
1921 # of the attributes supplied
1923 # used to determine if a subquery is neccessary
1925 # supports some virtual attributes:
1927 # This will scan for any joins being present on the resultset.
1928 # It is not a mere key-search but a deep inspection of {from}
1931 sub _has_resolved_attr {
1932 my ($self, @attr_names) = @_;
1934 my $attrs = $self->_resolved_attrs;
1938 for my $n (@attr_names) {
1939 if (grep { $n eq $_ } (qw/-join/) ) {
1940 $extra_checks{$n}++;
1944 my $attr = $attrs->{$n};
1946 next if not defined $attr;
1948 if (ref $attr eq 'HASH') {
1949 return 1 if keys %$attr;
1951 elsif (ref $attr eq 'ARRAY') {
1959 # a resolved join is expressed as a multi-level from
1961 $extra_checks{-join}
1963 ref $attrs->{from} eq 'ARRAY'
1965 @{$attrs->{from}} > 1
1973 # Recursively collapse the condition.
1975 sub _collapse_cond {
1976 my ($self, $cond, $collapsed) = @_;
1980 if (ref $cond eq 'ARRAY') {
1981 foreach my $subcond (@$cond) {
1982 next unless ref $subcond; # -or
1983 $collapsed = $self->_collapse_cond($subcond, $collapsed);
1986 elsif (ref $cond eq 'HASH') {
1987 if (keys %$cond and (keys %$cond)[0] eq '-and') {
1988 foreach my $subcond (@{$cond->{-and}}) {
1989 $collapsed = $self->_collapse_cond($subcond, $collapsed);
1993 foreach my $col (keys %$cond) {
1994 my $value = $cond->{$col};
1995 $collapsed->{$col} = $value;
2005 # Remove the specified alias from the specified query hash. A copy is made so
2006 # the original query is not modified.
2009 my ($self, $query, $alias) = @_;
2011 my %orig = %{ $query || {} };
2014 foreach my $key (keys %orig) {
2016 $unaliased{$key} = $orig{$key};
2019 $unaliased{$1} = $orig{$key}
2020 if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
2030 =item Arguments: none
2032 =item Return Value: \[ $sql, @bind ]
2036 Returns the SQL query and bind vars associated with the invocant.
2038 This is generally used as the RHS for a subquery.
2045 my $attrs = $self->_resolved_attrs_copy;
2050 # my ($sql, \@bind, \%dbi_bind_attrs) = _select_args_to_query (...)
2051 # $sql also has no wrapping parenthesis in list ctx
2053 my $sqlbind = $self->result_source->storage
2054 ->_select_args_to_query ($attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs);
2063 =item Arguments: \%vals, \%attrs?
2065 =item Return Value: $rowobject
2069 my $artist = $schema->resultset('Artist')->find_or_new(
2070 { artist => 'fred' }, { key => 'artists' });
2072 $cd->cd_to_producer->find_or_new({ producer => $producer },
2073 { key => 'primary });
2075 Find an existing record from this resultset, based on its primary
2076 key, or a unique constraint. If none exists, instantiate a new result
2077 object and return it. The object will not be saved into your storage
2078 until you call L<DBIx::Class::Row/insert> on it.
2080 You most likely want this method when looking for existing rows using
2081 a unique constraint that is not the primary key, or looking for
2084 If you want objects to be saved immediately, use L</find_or_create>
2087 B<Note>: Take care when using C<find_or_new> with a table having
2088 columns with default values that you intend to be automatically
2089 supplied by the database (e.g. an auto_increment primary key column).
2090 In normal usage, the value of such columns should NOT be included at
2091 all in the call to C<find_or_new>, even when set to C<undef>.
2097 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
2098 my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
2099 if (keys %$hash and my $row = $self->find($hash, $attrs) ) {
2102 return $self->new_result($hash);
2109 =item Arguments: \%vals
2111 =item Return Value: a L<DBIx::Class::Row> $object
2115 Attempt to create a single new row or a row with multiple related rows
2116 in the table represented by the resultset (and related tables). This
2117 will not check for duplicate rows before inserting, use
2118 L</find_or_create> to do that.
2120 To create one row for this resultset, pass a hashref of key/value
2121 pairs representing the columns of the table and the values you wish to
2122 store. If the appropriate relationships are set up, foreign key fields
2123 can also be passed an object representing the foreign row, and the
2124 value will be set to its primary key.
2126 To create related objects, pass a hashref of related-object column values
2127 B<keyed on the relationship name>. If the relationship is of type C<multi>
2128 (L<DBIx::Class::Relationship/has_many>) - pass an arrayref of hashrefs.
2129 The process will correctly identify columns holding foreign keys, and will
2130 transparrently populate them from the keys of the corresponding relation.
2131 This can be applied recursively, and will work correctly for a structure
2132 with an arbitrary depth and width, as long as the relationships actually
2133 exists and the correct column data has been supplied.
2136 Instead of hashrefs of plain related data (key/value pairs), you may
2137 also pass new or inserted objects. New objects (not inserted yet, see
2138 L</new>), will be inserted into their appropriate tables.
2140 Effectively a shortcut for C<< ->new_result(\%vals)->insert >>.
2142 Example of creating a new row.
2144 $person_rs->create({
2145 name=>"Some Person",
2146 email=>"somebody@someplace.com"
2149 Example of creating a new row and also creating rows in a related C<has_many>
2150 or C<has_one> resultset. Note Arrayref.
2153 { artistid => 4, name => 'Manufactured Crap', cds => [
2154 { title => 'My First CD', year => 2006 },
2155 { title => 'Yet More Tweeny-Pop crap', year => 2007 },
2160 Example of creating a new row and also creating a row in a related
2161 C<belongs_to>resultset. Note Hashref.
2164 title=>"Music for Silly Walks",
2167 name=>"Silly Musician",
2175 When subclassing ResultSet never attempt to override this method. Since
2176 it is a simple shortcut for C<< $self->new_result($attrs)->insert >>, a
2177 lot of the internals simply never call it, so your override will be
2178 bypassed more often than not. Override either L<new|DBIx::Class::Row/new>
2179 or L<insert|DBIx::Class::Row/insert> depending on how early in the
2180 L</create> process you need to intervene.
2187 my ($self, $attrs) = @_;
2188 $self->throw_exception( "create needs a hashref" )
2189 unless ref $attrs eq 'HASH';
2190 return $self->new_result($attrs)->insert;
2193 =head2 find_or_create
2197 =item Arguments: \%vals, \%attrs?
2199 =item Return Value: $rowobject
2203 $cd->cd_to_producer->find_or_create({ producer => $producer },
2204 { key => 'primary' });
2206 Tries to find a record based on its primary key or unique constraints; if none
2207 is found, creates one and returns that instead.
2209 my $cd = $schema->resultset('CD')->find_or_create({
2211 artist => 'Massive Attack',
2212 title => 'Mezzanine',
2216 Also takes an optional C<key> attribute, to search by a specific key or unique
2217 constraint. For example:
2219 my $cd = $schema->resultset('CD')->find_or_create(
2221 artist => 'Massive Attack',
2222 title => 'Mezzanine',
2224 { key => 'cd_artist_title' }
2227 B<Note>: Because find_or_create() reads from the database and then
2228 possibly inserts based on the result, this method is subject to a race
2229 condition. Another process could create a record in the table after
2230 the find has completed and before the create has started. To avoid
2231 this problem, use find_or_create() inside a transaction.
2233 B<Note>: Take care when using C<find_or_create> with a table having
2234 columns with default values that you intend to be automatically
2235 supplied by the database (e.g. an auto_increment primary key column).
2236 In normal usage, the value of such columns should NOT be included at
2237 all in the call to C<find_or_create>, even when set to C<undef>.
2239 See also L</find> and L</update_or_create>. For information on how to declare
2240 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
2244 sub find_or_create {
2246 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
2247 my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
2248 if (keys %$hash and my $row = $self->find($hash, $attrs) ) {
2251 return $self->create($hash);
2254 =head2 update_or_create
2258 =item Arguments: \%col_values, { key => $unique_constraint }?
2260 =item Return Value: $rowobject
2264 $resultset->update_or_create({ col => $val, ... });
2266 First, searches for an existing row matching one of the unique constraints
2267 (including the primary key) on the source of this resultset. If a row is
2268 found, updates it with the other given column values. Otherwise, creates a new
2271 Takes an optional C<key> attribute to search on a specific unique constraint.
2274 # In your application
2275 my $cd = $schema->resultset('CD')->update_or_create(
2277 artist => 'Massive Attack',
2278 title => 'Mezzanine',
2281 { key => 'cd_artist_title' }
2284 $cd->cd_to_producer->update_or_create({
2285 producer => $producer,
2292 If no C<key> is specified, it searches on all unique constraints defined on the
2293 source, including the primary key.
2295 If the C<key> is specified as C<primary>, it searches only on the primary key.
2297 See also L</find> and L</find_or_create>. For information on how to declare
2298 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
2300 B<Note>: Take care when using C<update_or_create> with a table having
2301 columns with default values that you intend to be automatically
2302 supplied by the database (e.g. an auto_increment primary key column).
2303 In normal usage, the value of such columns should NOT be included at
2304 all in the call to C<update_or_create>, even when set to C<undef>.
2308 sub update_or_create {
2310 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
2311 my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
2313 my $row = $self->find($cond, $attrs);
2315 $row->update($cond);
2319 return $self->create($cond);
2322 =head2 update_or_new
2326 =item Arguments: \%col_values, { key => $unique_constraint }?
2328 =item Return Value: $rowobject
2332 $resultset->update_or_new({ col => $val, ... });
2334 First, searches for an existing row matching one of the unique constraints
2335 (including the primary key) on the source of this resultset. If a row is
2336 found, updates it with the other given column values. Otherwise, instantiate
2337 a new result object and return it. The object will not be saved into your storage
2338 until you call L<DBIx::Class::Row/insert> on it.
2340 Takes an optional C<key> attribute to search on a specific unique constraint.
2343 # In your application
2344 my $cd = $schema->resultset('CD')->update_or_new(
2346 artist => 'Massive Attack',
2347 title => 'Mezzanine',
2350 { key => 'cd_artist_title' }
2353 if ($cd->in_storage) {
2354 # the cd was updated
2357 # the cd is not yet in the database, let's insert it
2361 B<Note>: Take care when using C<update_or_new> with a table having
2362 columns with default values that you intend to be automatically
2363 supplied by the database (e.g. an auto_increment primary key column).
2364 In normal usage, the value of such columns should NOT be included at
2365 all in the call to C<update_or_new>, even when set to C<undef>.
2367 See also L</find>, L</find_or_create> and L</find_or_new>.
2373 my $attrs = ( @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {} );
2374 my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
2376 my $row = $self->find( $cond, $attrs );
2377 if ( defined $row ) {
2378 $row->update($cond);
2382 return $self->new_result($cond);
2389 =item Arguments: none
2391 =item Return Value: \@cache_objects?
2395 Gets the contents of the cache for the resultset, if the cache is set.
2397 The cache is populated either by using the L</prefetch> attribute to
2398 L</search> or by calling L</set_cache>.
2410 =item Arguments: \@cache_objects
2412 =item Return Value: \@cache_objects
2416 Sets the contents of the cache for the resultset. Expects an arrayref
2417 of objects of the same class as those produced by the resultset. Note that
2418 if the cache is set the resultset will return the cached objects rather
2419 than re-querying the database even if the cache attr is not set.
2421 The contents of the cache can also be populated by using the
2422 L</prefetch> attribute to L</search>.
2427 my ( $self, $data ) = @_;
2428 $self->throw_exception("set_cache requires an arrayref")
2429 if defined($data) && (ref $data ne 'ARRAY');
2430 $self->{all_cache} = $data;
2437 =item Arguments: none
2439 =item Return Value: []
2443 Clears the cache for the resultset.
2448 shift->set_cache(undef);
2455 =item Arguments: none
2457 =item Return Value: true, if the resultset has been paginated
2465 return !!$self->{attrs}{page};
2468 =head2 related_resultset
2472 =item Arguments: $relationship_name
2474 =item Return Value: $resultset
2478 Returns a related resultset for the supplied relationship name.
2480 $artist_rs = $schema->resultset('CD')->related_resultset('Artist');
2484 sub related_resultset {
2485 my ($self, $rel) = @_;
2487 $self->{related_resultsets} ||= {};
2488 return $self->{related_resultsets}{$rel} ||= do {
2489 my $rsrc = $self->result_source;
2490 my $rel_info = $rsrc->relationship_info($rel);
2492 $self->throw_exception(
2493 "search_related: result source '" . $rsrc->source_name .
2494 "' has no such relationship $rel")
2497 my $attrs = $self->_chain_relationship($rel);
2499 my $join_count = $attrs->{seen_join}{$rel};
2501 my $alias = $self->result_source->storage
2502 ->relname_to_table_alias($rel, $join_count);
2504 # since this is search_related, and we already slid the select window inwards
2505 # (the select/as attrs were deleted in the beginning), we need to flip all
2506 # left joins to inner, so we get the expected results
2507 # read the comment on top of the actual function to see what this does
2508 $attrs->{from} = $rsrc->schema->storage->_straight_join_to_node ($attrs->{from}, $alias);
2511 #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
2512 delete @{$attrs}{qw(result_class alias)};
2516 if (my $cache = $self->get_cache) {
2517 if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
2518 $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
2523 my $rel_source = $rsrc->related_source($rel);
2527 # The reason we do this now instead of passing the alias to the
2528 # search_rs below is that if you wrap/overload resultset on the
2529 # source you need to know what alias it's -going- to have for things
2530 # to work sanely (e.g. RestrictWithObject wants to be able to add
2531 # extra query restrictions, and these may need to be $alias.)
2533 my $rel_attrs = $rel_source->resultset_attributes;
2534 local $rel_attrs->{alias} = $alias;
2536 $rel_source->resultset
2540 where => $attrs->{where},
2543 $new->set_cache($new_cache) if $new_cache;
2548 =head2 current_source_alias
2552 =item Arguments: none
2554 =item Return Value: $source_alias
2558 Returns the current table alias for the result source this resultset is built
2559 on, that will be used in the SQL query. Usually it is C<me>.
2561 Currently the source alias that refers to the result set returned by a
2562 L</search>/L</find> family method depends on how you got to the resultset: it's
2563 C<me> by default, but eg. L</search_related> aliases it to the related result
2564 source name (and keeps C<me> referring to the original result set). The long
2565 term goal is to make L<DBIx::Class> always alias the current resultset as C<me>
2566 (and make this method unnecessary).
2568 Thus it's currently necessary to use this method in predefined queries (see
2569 L<DBIx::Class::Manual::Cookbook/Predefined searches>) when referring to the
2570 source alias of the current result set:
2572 # in a result set class
2574 my ($self, $user) = @_;
2576 my $me = $self->current_source_alias;
2578 return $self->search(
2579 "$me.modified" => $user->id,
2585 sub current_source_alias {
2588 return ($self->{attrs} || {})->{alias} || 'me';
2591 # This code is called by search_related, and makes sure there
2592 # is clear separation between the joins before, during, and
2593 # after the relationship. This information is needed later
2594 # in order to properly resolve prefetch aliases (any alias
2595 # with a relation_chain_depth less than the depth of the
2596 # current prefetch is not considered)
2598 # The increments happen twice per join. An even number means a
2599 # relationship specified via a search_related, whereas an odd
2600 # number indicates a join/prefetch added via attributes
2602 # Also this code will wrap the current resultset (the one we
2603 # chain to) in a subselect IFF it contains limiting attributes
2604 sub _chain_relationship {
2605 my ($self, $rel) = @_;
2606 my $source = $self->result_source;
2607 my $attrs = { %{$self->{attrs}||{}} };
2609 # we need to take the prefetch the attrs into account before we
2610 # ->_resolve_join as otherwise they get lost - captainL
2611 my $join = $self->_merge_attr( $attrs->{join}, $attrs->{prefetch} );
2613 delete @{$attrs}{qw/join prefetch collapse distinct select as columns +select +as +columns/};
2615 my $seen = { %{ (delete $attrs->{seen_join}) || {} } };
2618 my @force_subq_attrs = qw/offset rows group_by having/;
2621 ($attrs->{from} && ref $attrs->{from} ne 'ARRAY')
2623 $self->_has_resolved_attr (@force_subq_attrs)
2625 # Nuke the prefetch (if any) before the new $rs attrs
2626 # are resolved (prefetch is useless - we are wrapping
2627 # a subquery anyway).
2628 my $rs_copy = $self->search;
2629 $rs_copy->{attrs}{join} = $self->_merge_attr (
2630 $rs_copy->{attrs}{join},
2631 delete $rs_copy->{attrs}{prefetch},
2635 -source_handle => $source->handle,
2636 -alias => $attrs->{alias},
2637 $attrs->{alias} => $rs_copy->as_query,
2639 delete @{$attrs}{@force_subq_attrs, 'where'};
2640 $seen->{-relation_chain_depth} = 0;
2642 elsif ($attrs->{from}) { #shallow copy suffices
2643 $from = [ @{$attrs->{from}} ];
2647 -source_handle => $source->handle,
2648 -alias => $attrs->{alias},
2649 $attrs->{alias} => $source->from,
2653 my $jpath = ($seen->{-relation_chain_depth})
2654 ? $from->[-1][0]{-join_path}
2657 my @requested_joins = $source->_resolve_join(
2664 push @$from, @requested_joins;
2666 $seen->{-relation_chain_depth}++;
2668 # if $self already had a join/prefetch specified on it, the requested
2669 # $rel might very well be already included. What we do in this case
2670 # is effectively a no-op (except that we bump up the chain_depth on
2671 # the join in question so we could tell it *is* the search_related)
2674 # we consider the last one thus reverse
2675 for my $j (reverse @requested_joins) {
2676 if ($rel eq $j->[0]{-join_path}[-1]) {
2677 $j->[0]{-relation_chain_depth}++;
2682 # alternative way to scan the entire chain - not backwards compatible
2683 # for my $j (reverse @$from) {
2684 # next unless ref $j eq 'ARRAY';
2685 # if ($j->[0]{-join_path} && $j->[0]{-join_path}[-1] eq $rel) {
2686 # $j->[0]{-relation_chain_depth}++;
2687 # $already_joined++;
2692 unless ($already_joined) {
2693 push @$from, $source->_resolve_join(
2701 $seen->{-relation_chain_depth}++;
2703 return {%$attrs, from => $from, seen_join => $seen};
2706 # too many times we have to do $attrs = { %{$self->_resolved_attrs} }
2707 sub _resolved_attrs_copy {
2709 return { %{$self->_resolved_attrs (@_)} };
2712 sub _resolved_attrs {
2714 return $self->{_attrs} if $self->{_attrs};
2716 my $attrs = { %{ $self->{attrs} || {} } };
2717 my $source = $self->result_source;
2718 my $alias = $attrs->{alias};
2720 $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
2723 # build columns (as long as select isn't set) into a set of as/select hashes
2724 unless ( $attrs->{select} ) {
2726 my @cols = ( ref($attrs->{columns}) eq 'ARRAY' )
2727 ? @{ delete $attrs->{columns}}
2729 ( delete $attrs->{columns} )
2736 ( ref($_) eq 'HASH' )
2740 /^\Q${alias}.\E(.+)$/
2754 # add the additional columns on
2755 foreach ( 'include_columns', '+columns' ) {
2756 push @colbits, map {
2757 ( ref($_) eq 'HASH' )
2759 : { ( split( /\./, $_ ) )[-1] => ( /\./ ? $_ : "${alias}.$_" ) }
2760 } ( ref($attrs->{$_}) eq 'ARRAY' ) ? @{ delete $attrs->{$_} } : delete $attrs->{$_} if ( $attrs->{$_} );
2763 # start with initial select items
2764 if ( $attrs->{select} ) {
2766 ( ref $attrs->{select} eq 'ARRAY' )
2767 ? [ @{ $attrs->{select} } ]
2768 : [ $attrs->{select} ];
2772 ref $attrs->{as} eq 'ARRAY'
2773 ? [ @{ $attrs->{as} } ]
2776 : [ map { m/^\Q${alias}.\E(.+)$/ ? $1 : $_ } @{ $attrs->{select} } ]
2781 # otherwise we intialise select & as to empty
2782 $attrs->{select} = [];
2786 # now add colbits to select/as
2787 push( @{ $attrs->{select} }, map { values( %{$_} ) } @colbits );
2788 push( @{ $attrs->{as} }, map { keys( %{$_} ) } @colbits );
2791 if ( $adds = delete $attrs->{'+select'} ) {
2792 $adds = [$adds] unless ref $adds eq 'ARRAY';
2794 @{ $attrs->{select} },
2795 map { /\./ || ref $_ ? $_ : "${alias}.$_" } @$adds
2798 if ( $adds = delete $attrs->{'+as'} ) {
2799 $adds = [$adds] unless ref $adds eq 'ARRAY';
2800 push( @{ $attrs->{as} }, @$adds );
2803 $attrs->{from} ||= [ {
2804 -source_handle => $source->handle,
2805 -alias => $self->{attrs}{alias},
2806 $self->{attrs}{alias} => $source->from,
2809 if ( $attrs->{join} || $attrs->{prefetch} ) {
2811 $self->throw_exception ('join/prefetch can not be used with a custom {from}')
2812 if ref $attrs->{from} ne 'ARRAY';
2814 my $join = delete $attrs->{join} || {};
2816 if ( defined $attrs->{prefetch} ) {
2817 $join = $self->_merge_attr( $join, $attrs->{prefetch} );
2820 $attrs->{from} = # have to copy here to avoid corrupting the original
2822 @{ $attrs->{from} },
2823 $source->_resolve_join(
2826 { %{ $attrs->{seen_join} || {} } },
2827 ($attrs->{seen_join} && keys %{$attrs->{seen_join}})
2828 ? $attrs->{from}[-1][0]{-join_path}
2835 if ( defined $attrs->{order_by} ) {
2836 $attrs->{order_by} = (
2837 ref( $attrs->{order_by} ) eq 'ARRAY'
2838 ? [ @{ $attrs->{order_by} } ]
2839 : [ $attrs->{order_by} || () ]
2843 if ($attrs->{group_by} and ref $attrs->{group_by} ne 'ARRAY') {
2844 $attrs->{group_by} = [ $attrs->{group_by} ];
2847 # generate the distinct induced group_by early, as prefetch will be carried via a
2848 # subquery (since a group_by is present)
2849 if (delete $attrs->{distinct}) {
2850 if ($attrs->{group_by}) {
2851 carp ("Useless use of distinct on a grouped resultset ('distinct' is ignored when a 'group_by' is present)");
2854 $attrs->{group_by} = [ grep { !ref($_) || (ref($_) ne 'HASH') } @{$attrs->{select}} ];
2856 # add any order_by parts that are not already present in the group_by
2857 # we need to be careful not to add any named functions/aggregates
2858 # i.e. select => [ ... { count => 'foo', -as 'foocount' } ... ]
2859 my %already_grouped = map { $_ => 1 } (@{$attrs->{group_by}});
2861 my $storage = $self->result_source->schema->storage;
2862 my $rs_column_list = $storage->_resolve_column_info ($attrs->{from});
2863 my @chunks = $storage->sql_maker->_order_by_chunks ($attrs->{order_by});
2865 for my $chunk (map { ref $_ ? @$_ : $_ } (@chunks) ) {
2866 $chunk =~ s/\s+ (?: ASC|DESC ) \s* $//ix;
2867 if ($rs_column_list->{$chunk} && not $already_grouped{$chunk}++) {
2868 push @{$attrs->{group_by}}, $chunk;
2874 $attrs->{collapse} ||= {};
2875 if ( my $prefetch = delete $attrs->{prefetch} ) {
2876 $prefetch = $self->_merge_attr( {}, $prefetch );
2878 my $prefetch_ordering = [];
2880 my $join_map = $self->_joinpath_aliases ($attrs->{from}, $attrs->{seen_join});
2883 $source->_resolve_prefetch( $prefetch, $alias, $join_map, $prefetch_ordering, $attrs->{collapse} );
2885 # we need to somehow mark which columns came from prefetch
2886 $attrs->{_prefetch_select} = [ map { $_->[0] } @prefetch ];
2888 push @{ $attrs->{select} }, @{$attrs->{_prefetch_select}};
2889 push @{ $attrs->{as} }, (map { $_->[1] } @prefetch);
2891 push( @{$attrs->{order_by}}, @$prefetch_ordering );
2892 $attrs->{_collapse_order_by} = \@$prefetch_ordering;
2895 # if both page and offset are specified, produce a combined offset
2896 # even though it doesn't make much sense, this is what pre 081xx has
2898 if (my $page = delete $attrs->{page}) {
2900 ($attrs->{rows} * ($page - 1))
2902 ($attrs->{offset} || 0)
2906 return $self->{_attrs} = $attrs;
2909 sub _joinpath_aliases {
2910 my ($self, $fromspec, $seen) = @_;
2913 return $paths unless ref $fromspec eq 'ARRAY';
2915 my $cur_depth = $seen->{-relation_chain_depth} || 0;
2917 if ($cur_depth % 2) {
2918 $self->throw_exception ("-relation_chain_depth is not even, something went horribly wrong ($cur_depth)");
2921 for my $j (@$fromspec) {
2923 next if ref $j ne 'ARRAY';
2924 next if ($j->[0]{-relation_chain_depth} || 0) < $cur_depth;
2926 my $jpath = $j->[0]{-join_path};
2929 $p = $p->{$_} ||= {} for @{$jpath}[ ($cur_depth/2) .. $#$jpath]; #only even depths are actual jpath boundaries
2930 push @{$p->{-join_aliases} }, $j->[0]{-alias};
2937 my ($self, $attr) = @_;
2939 if (ref $attr eq 'HASH') {
2940 return $self->_rollout_hash($attr);
2941 } elsif (ref $attr eq 'ARRAY') {
2942 return $self->_rollout_array($attr);
2948 sub _rollout_array {
2949 my ($self, $attr) = @_;
2952 foreach my $element (@{$attr}) {
2953 if (ref $element eq 'HASH') {
2954 push( @rolled_array, @{ $self->_rollout_hash( $element ) } );
2955 } elsif (ref $element eq 'ARRAY') {
2956 # XXX - should probably recurse here
2957 push( @rolled_array, @{$self->_rollout_array($element)} );
2959 push( @rolled_array, $element );
2962 return \@rolled_array;
2966 my ($self, $attr) = @_;
2969 foreach my $key (keys %{$attr}) {
2970 push( @rolled_array, { $key => $attr->{$key} } );
2972 return \@rolled_array;
2975 sub _calculate_score {
2976 my ($self, $a, $b) = @_;
2978 if (defined $a xor defined $b) {
2981 elsif (not defined $a) {
2985 if (ref $b eq 'HASH') {
2986 my ($b_key) = keys %{$b};
2987 if (ref $a eq 'HASH') {
2988 my ($a_key) = keys %{$a};
2989 if ($a_key eq $b_key) {
2990 return (1 + $self->_calculate_score( $a->{$a_key}, $b->{$b_key} ));
2995 return ($a eq $b_key) ? 1 : 0;
2998 if (ref $a eq 'HASH') {
2999 my ($a_key) = keys %{$a};
3000 return ($b eq $a_key) ? 1 : 0;
3002 return ($b eq $a) ? 1 : 0;
3008 my ($self, $orig, $import) = @_;
3010 return $import unless defined($orig);
3011 return $orig unless defined($import);
3013 $orig = $self->_rollout_attr($orig);
3014 $import = $self->_rollout_attr($import);
3017 foreach my $import_element ( @{$import} ) {
3018 # find best candidate from $orig to merge $b_element into
3019 my $best_candidate = { position => undef, score => 0 }; my $position = 0;
3020 foreach my $orig_element ( @{$orig} ) {
3021 my $score = $self->_calculate_score( $orig_element, $import_element );
3022 if ($score > $best_candidate->{score}) {
3023 $best_candidate->{position} = $position;
3024 $best_candidate->{score} = $score;
3028 my ($import_key) = ( ref $import_element eq 'HASH' ) ? keys %{$import_element} : ($import_element);
3030 if ($best_candidate->{score} == 0 || exists $seen_keys->{$import_key}) {
3031 push( @{$orig}, $import_element );
3033 my $orig_best = $orig->[$best_candidate->{position}];
3034 # merge orig_best and b_element together and replace original with merged
3035 if (ref $orig_best ne 'HASH') {
3036 $orig->[$best_candidate->{position}] = $import_element;
3037 } elsif (ref $import_element eq 'HASH') {
3038 my ($key) = keys %{$orig_best};
3039 $orig->[$best_candidate->{position}] = { $key => $self->_merge_attr($orig_best->{$key}, $import_element->{$key}) };
3042 $seen_keys->{$import_key} = 1; # don't merge the same key twice
3052 $self->_source_handle($_[0]->handle);
3054 $self->_source_handle->resolve;
3058 =head2 throw_exception
3060 See L<DBIx::Class::Schema/throw_exception> for details.
3064 sub throw_exception {
3067 if (ref $self && $self->_source_handle->schema) {
3068 $self->_source_handle->schema->throw_exception(@_)
3071 DBIx::Class::Exception->throw(@_);
3075 # XXX: FIXME: Attributes docs need clearing up
3079 Attributes are used to refine a ResultSet in various ways when
3080 searching for data. They can be passed to any method which takes an
3081 C<\%attrs> argument. See L</search>, L</search_rs>, L</find>,
3084 These are in no particular order:
3090 =item Value: ( $order_by | \@order_by | \%order_by )
3094 Which column(s) to order the results by.
3096 [The full list of suitable values is documented in
3097 L<SQL::Abstract/"ORDER BY CLAUSES">; the following is a summary of
3100 If a single column name, or an arrayref of names is supplied, the
3101 argument is passed through directly to SQL. The hashref syntax allows
3102 for connection-agnostic specification of ordering direction:
3104 For descending order:
3106 order_by => { -desc => [qw/col1 col2 col3/] }
3108 For explicit ascending order:
3110 order_by => { -asc => 'col' }
3112 The old scalarref syntax (i.e. order_by => \'year DESC') is still
3113 supported, although you are strongly encouraged to use the hashref
3114 syntax as outlined above.
3120 =item Value: \@columns
3124 Shortcut to request a particular set of columns to be retrieved. Each
3125 column spec may be a string (a table column name), or a hash (in which
3126 case the key is the C<as> value, and the value is used as the C<select>
3127 expression). Adds C<me.> onto the start of any column without a C<.> in
3128 it and sets C<select> from that, then auto-populates C<as> from
3129 C<select> as normal. (You may also use the C<cols> attribute, as in
3130 earlier versions of DBIC.)
3136 =item Value: \@columns
3140 Indicates additional columns to be selected from storage. Works the same
3141 as L</columns> but adds columns to the selection. (You may also use the
3142 C<include_columns> attribute, as in earlier versions of DBIC). For
3145 $schema->resultset('CD')->search(undef, {
3146 '+columns' => ['artist.name'],
3150 would return all CDs and include a 'name' column to the information
3151 passed to object inflation. Note that the 'artist' is the name of the
3152 column (or relationship) accessor, and 'name' is the name of the column
3153 accessor in the related table.
3155 =head2 include_columns
3159 =item Value: \@columns
3163 Deprecated. Acts as a synonym for L</+columns> for backward compatibility.
3169 =item Value: \@select_columns
3173 Indicates which columns should be selected from the storage. You can use
3174 column names, or in the case of RDBMS back ends, function or stored procedure
3177 $rs = $schema->resultset('Employee')->search(undef, {
3180 { count => 'employeeid' },
3185 When you use function/stored procedure names and do not supply an C<as>
3186 attribute, the column names returned are storage-dependent. E.g. MySQL would
3187 return a column named C<count(employeeid)> in the above example.
3189 B<NOTE:> You will almost always need a corresponding 'as' entry when you use
3196 Indicates additional columns to be selected from storage. Works the same as
3197 L</select> but adds columns to the selection.
3205 Indicates additional column names for those added via L</+select>. See L</as>.
3213 =item Value: \@inflation_names
3217 Indicates column names for object inflation. That is, C<as>
3218 indicates the name that the column can be accessed as via the
3219 C<get_column> method (or via the object accessor, B<if one already
3220 exists>). It has nothing to do with the SQL code C<SELECT foo AS bar>.
3222 The C<as> attribute is used in conjunction with C<select>,
3223 usually when C<select> contains one or more function or stored
3226 $rs = $schema->resultset('Employee')->search(undef, {
3229 { count => 'employeeid' }
3231 as => ['name', 'employee_count'],
3234 my $employee = $rs->first(); # get the first Employee
3236 If the object against which the search is performed already has an accessor
3237 matching a column name specified in C<as>, the value can be retrieved using
3238 the accessor as normal:
3240 my $name = $employee->name();
3242 If on the other hand an accessor does not exist in the object, you need to
3243 use C<get_column> instead:
3245 my $employee_count = $employee->get_column('employee_count');
3247 You can create your own accessors if required - see
3248 L<DBIx::Class::Manual::Cookbook> for details.
3250 Please note: This will NOT insert an C<AS employee_count> into the SQL
3251 statement produced, it is used for internal access only. Thus
3252 attempting to use the accessor in an C<order_by> clause or similar
3253 will fail miserably.
3255 To get around this limitation, you can supply literal SQL to your
3256 C<select> attibute that contains the C<AS alias> text, eg:
3258 select => [\'myfield AS alias']
3264 =item Value: ($rel_name | \@rel_names | \%rel_names)
3268 Contains a list of relationships that should be joined for this query. For
3271 # Get CDs by Nine Inch Nails
3272 my $rs = $schema->resultset('CD')->search(
3273 { 'artist.name' => 'Nine Inch Nails' },
3274 { join => 'artist' }
3277 Can also contain a hash reference to refer to the other relation's relations.
3280 package MyApp::Schema::Track;
3281 use base qw/DBIx::Class/;
3282 __PACKAGE__->table('track');
3283 __PACKAGE__->add_columns(qw/trackid cd position title/);
3284 __PACKAGE__->set_primary_key('trackid');
3285 __PACKAGE__->belongs_to(cd => 'MyApp::Schema::CD');
3288 # In your application
3289 my $rs = $schema->resultset('Artist')->search(
3290 { 'track.title' => 'Teardrop' },
3292 join => { cd => 'track' },
3293 order_by => 'artist.name',
3297 You need to use the relationship (not the table) name in conditions,
3298 because they are aliased as such. The current table is aliased as "me", so
3299 you need to use me.column_name in order to avoid ambiguity. For example:
3301 # Get CDs from 1984 with a 'Foo' track
3302 my $rs = $schema->resultset('CD')->search(
3305 'tracks.name' => 'Foo'
3307 { join => 'tracks' }
3310 If the same join is supplied twice, it will be aliased to <rel>_2 (and
3311 similarly for a third time). For e.g.
3313 my $rs = $schema->resultset('Artist')->search({
3314 'cds.title' => 'Down to Earth',
3315 'cds_2.title' => 'Popular',
3317 join => [ qw/cds cds/ ],
3320 will return a set of all artists that have both a cd with title 'Down
3321 to Earth' and a cd with title 'Popular'.
3323 If you want to fetch related objects from other tables as well, see C<prefetch>
3326 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
3332 =item Value: ($rel_name | \@rel_names | \%rel_names)
3336 Contains one or more relationships that should be fetched along with
3337 the main query (when they are accessed afterwards the data will
3338 already be available, without extra queries to the database). This is
3339 useful for when you know you will need the related objects, because it
3340 saves at least one query:
3342 my $rs = $schema->resultset('Tag')->search(
3351 The initial search results in SQL like the following:
3353 SELECT tag.*, cd.*, artist.* FROM tag
3354 JOIN cd ON tag.cd = cd.cdid
3355 JOIN artist ON cd.artist = artist.artistid
3357 L<DBIx::Class> has no need to go back to the database when we access the
3358 C<cd> or C<artist> relationships, which saves us two SQL statements in this
3361 Simple prefetches will be joined automatically, so there is no need
3362 for a C<join> attribute in the above search.
3364 C<prefetch> can be used with the following relationship types: C<belongs_to>,
3365 C<has_one> (or if you're using C<add_relationship>, any relationship declared
3366 with an accessor type of 'single' or 'filter'). A more complex example that
3367 prefetches an artists cds, the tracks on those cds, and the tags associted
3368 with that artist is given below (assuming many-to-many from artists to tags):
3370 my $rs = $schema->resultset('Artist')->search(
3374 { cds => 'tracks' },
3375 { artist_tags => 'tags' }
3381 B<NOTE:> If you specify a C<prefetch> attribute, the C<join> and C<select>
3382 attributes will be ignored.
3384 B<CAVEATs>: Prefetch does a lot of deep magic. As such, it may not behave
3385 exactly as you might expect.
3391 Prefetch uses the L</cache> to populate the prefetched relationships. This
3392 may or may not be what you want.
3396 If you specify a condition on a prefetched relationship, ONLY those
3397 rows that match the prefetched condition will be fetched into that relationship.
3398 This means that adding prefetch to a search() B<may alter> what is returned by
3399 traversing a relationship. So, if you have C<< Artist->has_many(CDs) >> and you do
3401 my $artist_rs = $schema->resultset('Artist')->search({
3407 my $count = $artist_rs->first->cds->count;
3409 my $artist_rs_prefetch = $artist_rs->search( {}, { prefetch => 'cds' } );
3411 my $prefetch_count = $artist_rs_prefetch->first->cds->count;
3413 cmp_ok( $count, '==', $prefetch_count, "Counts should be the same" );
3415 that cmp_ok() may or may not pass depending on the datasets involved. This
3416 behavior may or may not survive the 0.09 transition.
3428 Makes the resultset paged and specifies the page to retrieve. Effectively
3429 identical to creating a non-pages resultset and then calling ->page($page)
3432 If L<rows> attribute is not specified it defaults to 10 rows per page.
3434 When you have a paged resultset, L</count> will only return the number
3435 of rows in the page. To get the total, use the L</pager> and call
3436 C<total_entries> on it.
3446 Specifes the maximum number of rows for direct retrieval or the number of
3447 rows per page if the page attribute or method is used.
3453 =item Value: $offset
3457 Specifies the (zero-based) row number for the first row to be returned, or the
3458 of the first row of the first page if paging is used.
3464 =item Value: \@columns
3468 A arrayref of columns to group by. Can include columns of joined tables.
3470 group_by => [qw/ column1 column2 ... /]
3476 =item Value: $condition
3480 HAVING is a select statement attribute that is applied between GROUP BY and
3481 ORDER BY. It is applied to the after the grouping calculations have been
3484 having => { 'count(employee)' => { '>=', 100 } }
3490 =item Value: (0 | 1)
3494 Set to 1 to group by all columns. If the resultset already has a group_by
3495 attribute, this setting is ignored and an appropriate warning is issued.
3501 Adds to the WHERE clause.
3503 # only return rows WHERE deleted IS NULL for all searches
3504 __PACKAGE__->resultset_attributes({ where => { deleted => undef } }); )
3506 Can be overridden by passing C<< { where => undef } >> as an attribute
3513 Set to 1 to cache search results. This prevents extra SQL queries if you
3514 revisit rows in your ResultSet:
3516 my $resultset = $schema->resultset('Artist')->search( undef, { cache => 1 } );
3518 while( my $artist = $resultset->next ) {
3522 $rs->first; # without cache, this would issue a query
3524 By default, searches are not cached.
3526 For more examples of using these attributes, see
3527 L<DBIx::Class::Manual::Cookbook>.
3533 =item Value: ( 'update' | 'shared' )
3537 Set to 'update' for a SELECT ... FOR UPDATE or 'shared' for a SELECT