From: Peter Rabbitson Date: Fri, 19 Jun 2009 13:39:43 +0000 (+0000) Subject: single() throws with has_many prefetch X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=61fd5dfcb33d602247d07297a24810635482263d;p=dbsrgits%2FDBIx-Class-Historic.git single() throws with has_many prefetch --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 2160cf0..6faf118 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -698,10 +698,14 @@ a warning: Query returned more than one row -In this case, you should be using L or L instead, or if you really +In this case, you should be using L or L instead, or if you really know what you are doing, use the L attribute to explicitly limit the size of the resultset. +This method will also throw an exception if it is called on a resultset prefetching +has_many, as such a prefetch implies fetching multiple rows from the database in +order to assemble the resulting object. + =back =cut @@ -714,6 +718,12 @@ sub single { my $attrs = $self->_resolved_attrs_copy; + if (keys %{$attrs->{collapse}}) { + $self->throw_exception( + 'single() can not be used on resultsets prefetching has_many. Use find( \%cond ) or next() instead' + ); + } + if ($where) { if (defined $attrs->{where}) { $attrs->{where} = { diff --git a/t/prefetch/rows_bug.t b/t/prefetch/rows_bug.t index be3fff1..6e849f2 100644 --- a/t/prefetch/rows_bug.t +++ b/t/prefetch/rows_bug.t @@ -4,10 +4,11 @@ use strict; use warnings; use Test::More; +use Test::Exception; use lib qw(t/lib); use DBICTest; -plan tests => 4; +plan tests => 7; my $schema = DBICTest->init_schema(); @@ -49,24 +50,36 @@ $no_prefetch = $schema->resultset('Artist')->search( { rows => 1 } ); -$use_prefetch = $schema->resultset('Artist')->search( - { artistid => $artist_many_cds->id }, - { - prefetch => 'cds', - rows => 1 - } -); +$use_prefetch = $no_prefetch->search ({}, { prefetch => 'cds' }); -my $prefetch_artist = $use_prefetch->first; -my $normal_artist = $no_prefetch->first; +my $normal_artist = $no_prefetch->single; +my $prefetch_artist = $use_prefetch->find({ name => $artist_many_cds->name }); +my $prefetch2_artist = $use_prefetch->first; is( $prefetch_artist->cds->count, $normal_artist->cds->count, - "Count of child rel with prefetch + rows => 1 is right" + "Count of child rel with prefetch + rows => 1 is right (find)" +); +is( + $prefetch2_artist->cds->count, + $normal_artist->cds->count, + "Count of child rel with prefetch + rows => 1 is right (first)" ); + is ( scalar ($prefetch_artist->cds->all), scalar ($normal_artist->cds->all), - "Amount of child rel rows with prefetch + rows => 1 is right" + "Amount of child rel rows with prefetch + rows => 1 is right (find)" +); +is ( + scalar ($prefetch2_artist->cds->all), + scalar ($normal_artist->cds->all), + "Amount of child rel rows with prefetch + rows => 1 is right (first)" +); + +throws_ok ( + sub { $use_prefetch->single }, + qr/resultsets prefetching has_many/, + 'single() with multiprefetch is illegal', );