Make sure we always work with resolved rs attributes while counting (and test)
Peter Rabbitson [Wed, 20 May 2009 13:32:27 +0000 (13:32 +0000)]
lib/DBIx/Class/ResultSet.pm
t/count/prefetch.t [new file with mode: 0644]

index a87a3cd..13e1174 100644 (file)
@@ -1156,9 +1156,10 @@ sub count {
   return scalar @{ $self->get_cache } if $self->get_cache;
 
   my @subq_attrs = qw/prefetch collapse distinct group_by having having_bind/;
+  my $attrs = $self->_resolved_attrs;
 
   # if we are not paged - we are simply asking for a limit
-  if (not $self->{attrs}{page} and not $self->{attrs}{software_limit}) {
+  if (not $attrs->{page} and not $attrs->{software_limit}) {
     push @subq_attrs, qw/rows offset/;
   }
 
@@ -1209,7 +1210,7 @@ sub _count_simple {
 sub __count {
   my ($self, $attrs) = @_;
 
-  $attrs ||= { %{$self->{attrs}} };
+  $attrs ||= { %{$self->_resolved_attrs} };
 
   # take off any column specs, any pagers, record_filter is cdbi, and no point of ordering a count
   delete $attrs->{$_} for (qw/columns +columns select +select as +as rows offset page pager order_by record_filter/); 
diff --git a/t/count/prefetch.t b/t/count/prefetch.t
new file mode 100644 (file)
index 0000000..bd0426b
--- /dev/null
@@ -0,0 +1,63 @@
+use strict;
+use warnings;
+
+use lib qw(t/lib);
+
+use Test::More;
+use DBICTest;
+use DBIC::SqlMakerTest;
+use DBIC::DebugObj;
+
+plan tests => 6;
+
+my $schema = DBICTest->init_schema();
+
+# collapsing prefetch
+{
+  my $rs = $schema->resultset("Artist")
+            ->search_related('cds',
+                { 'tracks.position' => [1,2] },
+                { prefetch => [qw/tracks artist/] },
+            );
+  is ($rs->all, 5, 'Correct number of objects');
+
+
+  my ($sql, @bind);
+  $schema->storage->debugobj(DBIC::DebugObj->new(\$sql, \@bind));
+  $schema->storage->debug(1);
+
+
+  is ($rs->count, 5, 'Correct count');
+
+  is_same_sql_bind (
+    $sql,
+    \@bind,
+    'SELECT COUNT( * ) FROM (SELECT cds.cdid FROM artist me LEFT JOIN cd cds ON cds.artist = me.artistid LEFT JOIN track tracks ON tracks.cd = cds.cdid JOIN artist artist ON artist.artistid = cds.artist WHERE tracks.position = ? OR tracks.position = ? GROUP BY cds.cdid ORDER BY tracks.cd) count_subq',
+    [ qw/'1' '2'/ ], # wtf? we quote bind vals?
+  );
+}
+
+# non-collapsing prefetch (no multi prefetches)
+{
+  my $rs = $schema->resultset("CD")
+            ->search_related('tracks',
+                { position => [1,2] },
+                { prefetch => [qw/disc lyrics/] },
+            );
+  is ($rs->all, 10, 'Correct number of objects');
+
+
+  my ($sql, @bind);
+  $schema->storage->debugobj(DBIC::DebugObj->new(\$sql, \@bind));
+  $schema->storage->debug(1);
+
+
+  is ($rs->count, 10, 'Correct count');
+
+  is_same_sql_bind (
+    $sql,
+    \@bind,
+    'SELECT COUNT( * ) FROM cd me LEFT JOIN track tracks ON tracks.cd = me.cdid JOIN cd disc ON disc.cdid = tracks.cd LEFT JOIN lyrics lyrics ON lyrics.track_id = tracks.trackid WHERE ( ( position = ? OR position = ? ) )',
+    [ qw/'1' '2'/ ], # wtf? we quote bind vals?
+  );
+}