X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=883e190253619dcb1e8fa8902c34b92bf1bdecd0;hb=5233443c7147a7f75ff41560495d8258ae18622c;hp=64bcd4ea53230b3549f94e275605bc097f47cada;hpb=096f421241e5abd4274e4344b873b8570ab17d43;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 64bcd4e..883e190 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -10,10 +10,10 @@ use Carp::Clan qw/^DBIx::Class/; use Data::Page; use Storable; use DBIx::Class::ResultSetColumn; +use DBIx::Class::ResultSourceHandle; use base qw/DBIx::Class/; -__PACKAGE__->load_components(qw/AccessorGroup/); -__PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/); +__PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/); =head1 NAME @@ -85,7 +85,9 @@ sub new { return $class->new_result(@_) if ref $class; my ($source, $attrs) = @_; - #weaken $source; + $source = $source->handle + unless $source->isa('DBIx::Class::ResultSourceHandle'); + $attrs = { %{$attrs||{}} }; if ($attrs->{page}) { $attrs->{rows} ||= 10; @@ -96,8 +98,8 @@ sub new { $attrs->{alias} ||= 'me'; my $self = { - result_source => $source, - result_class => $attrs->{result_class} || $source->result_class, + _source_handle => $source, + result_class => $attrs->{result_class} || $source->resolve->result_class, cond => $attrs->{where}, count => undef, pager => undef, @@ -133,7 +135,10 @@ call it as C. columns => [qw/name artistid/], }); -For a list of attributes that can be passed to C, see L. For more examples of using this function, see L. +For a list of attributes that can be passed to C, see +L. For more examples of using this function, see +L. For a complete +documentation for the first argument, see L. =cut @@ -238,7 +243,7 @@ sub search_rs { : $having); } - my $rs = (ref $self)->new($self->result_source, $new_attrs); + my $rs = (ref $self)->new($self->_source_handle, $new_attrs); if ($rows) { $rs->set_cache($rows); } @@ -408,21 +413,23 @@ sub _unique_queries { ? ($attrs->{key}) : $self->result_source->unique_constraint_names; + my $where = $self->_collapse_cond($self->{attrs}{where} || {}); + my $num_where = scalar keys %$where; + my @unique_queries; foreach my $name (@constraint_names) { my @unique_cols = $self->result_source->unique_constraint_columns($name); my $unique_query = $self->_build_unique_query($query, \@unique_cols); + my $num_cols = scalar @unique_cols; my $num_query = scalar keys %$unique_query; - next unless $num_query; - # XXX: Assuming quite a bit about $self->{attrs}{where} - my $num_cols = scalar @unique_cols; - my $num_where = exists $self->{attrs}{where} - ? scalar keys %{ $self->{attrs}{where} } - : 0; - push @unique_queries, $unique_query - if $num_query + $num_where == $num_cols; + my $total = $num_query + $num_where; + if ($num_query && ($num_query == $num_cols || $total == $num_cols)) { + # The query is either unique on its own or is unique in combination with + # the existing where clause + push @unique_queries, $unique_query; + } } return @unique_queries; @@ -536,7 +543,7 @@ sub single { $attrs->{where}, $attrs ); - return (@data ? $self->_construct_object(@data) : ()); + return (@data ? ($self->_construct_object(@data))[0] : ()); } # _is_unique_query @@ -721,22 +728,29 @@ sub next { $self->{all_cache_position} = 1; return ($self->all)[0]; } + if ($self->{stashed_objects}) { + my $obj = shift(@{$self->{stashed_objects}}); + delete $self->{stashed_objects} unless @{$self->{stashed_objects}}; + return $obj; + } my @row = ( exists $self->{stashed_row} ? @{delete $self->{stashed_row}} : $self->cursor->next ); return unless (@row); - return $self->_construct_object(@row); + my ($row, @more) = $self->_construct_object(@row); + $self->{stashed_objects} = \@more if @more; + return $row; } sub _construct_object { my ($self, @row) = @_; my $info = $self->_collapse_result($self->{_attrs}{as}, \@row); - my $new = $self->result_class->inflate_result($self->result_source, @$info); - $new = $self->{_attrs}{record_filter}->($new) + my @new = $self->result_class->inflate_result($self->_source_handle, @$info); + @new = $self->{_attrs}{record_filter}->(@new) if exists $self->{_attrs}{record_filter}; - return $new; + return @new; } sub _collapse_result { @@ -909,7 +923,7 @@ sub _count { # Separated out so pager can get the full count # offset, order by and page are not needed to count. record_filter is cdbi delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/; - my $tmp_rs = (ref $self)->new($self->result_source, $attrs); + my $tmp_rs = (ref $self)->new($self->_source_handle, $attrs); my ($count) = $tmp_rs->cursor->next; return $count; } @@ -1100,9 +1114,9 @@ sub update { unless ref $values eq 'HASH'; my $cond = $self->_cond_for_update_delete; - + return $self->result_source->storage->update( - $self->result_source->from, $values, $cond + $self->result_source, $values, $cond ); } @@ -1152,7 +1166,7 @@ sub delete { my $cond = $self->_cond_for_update_delete; - $self->result_source->storage->delete($self->result_source->from, $cond); + $self->result_source->storage->delete($self->result_source, $cond); return 1; } @@ -1220,7 +1234,7 @@ attribute set on the resultset (10 by default). sub page { my ($self, $page) = @_; - return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page }); + return (ref $self)->new($self->_source_handle, { %{$self->{attrs}}, page => $page }); } =head2 new_result @@ -1250,11 +1264,10 @@ sub new_result { my %new = ( %{ $self->_remove_alias($values, $alias) }, %{ $self->_remove_alias($collapsed_cond, $alias) }, - -result_source => $self->result_source, + -source_handle => $self->_source_handle ); - my $obj = $self->result_class->new(\%new); - return $obj; + return $self->result_class->new(\%new); } # _collapse_cond @@ -1548,7 +1561,7 @@ sub related_resultset { my $rel_obj = $self->result_source->relationship_info($rel); $self->throw_exception( - "search_related: result source '" . $self->result_source->name . + "search_related: result source '" . $self->_source_handle->source_moniker . "' has no such relationship $rel") unless $rel_obj; @@ -1557,7 +1570,7 @@ sub related_resultset { my $join_count = $seen->{$rel}; my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel); - $self->result_source->schema->resultset($rel_obj->{class})->search_rs( + $self->_source_handle->schema->resultset($rel_obj->{class})->search_rs( undef, { %{$self->{attrs}||{}}, join => undef, @@ -1598,7 +1611,7 @@ sub _resolved_attrs { return $self->{_attrs} if $self->{_attrs}; my $attrs = { %{$self->{attrs}||{}} }; - my $source = $self->{result_source}; + my $source = $self->result_source; my $alias = $attrs->{alias}; $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols}; @@ -1730,6 +1743,16 @@ sub _merge_attr { } } +sub result_source { + my $self = shift; + + if (@_) { + $self->_source_handle($_[0]->handle); + } else { + $self->_source_handle->resolve; + } +} + =head2 throw_exception See L for details. @@ -1738,7 +1761,7 @@ See L for details. sub throw_exception { my $self=shift; - $self->result_source->schema->throw_exception(@_); + $self->_source_handle->schema->throw_exception(@_); } # XXX: FIXME: Attributes docs need clearing up @@ -1760,8 +1783,8 @@ Which column(s) to order the results by. This is currently passed through directly to SQL, so you can give e.g. C for a descending order on the column `year'. -Please note that if you have quoting enabled (see -L) you will need to do C<\'year DESC' > to +Please note that if you have C enabled (see +L) you will need to do C<\'year DESC' > to specify an order. (The scalar ref causes it to be passed as raw sql to the DB, so you will need to manually quote things as appropriate.) @@ -1794,7 +1817,9 @@ Shortcut to include additional columns in the returned results - for example }); would return all CDs and include a 'name' column to the information -passed to object inflation +passed to object inflation. Note that the 'artist' is the name of the +column (or relationship) accessor, and 'name' is the name of the column +accessor in the related table. =head2 select @@ -1845,8 +1870,14 @@ Indicates additional column names for those added via L<+select>. =back -Indicates column names for object inflation. This is used in conjunction with -C contains one or more function or stored +Indicates column names for object inflation. That is, c< as > +indicates the name that the column can be accessed as via the +C method (or via the object accessor, B). It has nothing to do with the SQL code C< SELECT foo AS bar +>. + +The C< as > attribute is used in conjunction with C contains one or more function or stored procedure names: $rs = $schema->resultset('Employee')->search(undef, {