multi-step prefetch along the same rel (e.g. for trees) now works
Matt S Trout [Mon, 6 Feb 2006 01:26:35 +0000 (01:26 +0000)]
Changes
lib/DBIx/Class/ResultSource.pm
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Setup.pm
t/lib/sqlite.sql
t/run/16joins.tl

diff --git a/Changes b/Changes
index 639470e..aaf3405 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,7 @@
 Revision history for DBIx::Class
 
 0.05001
+        - multi-step prefetch along the same rel (e.g. for trees) now works
         - added multi-join (join => [ 'foo', 'foo' ]), aliases second to foo_2
         - hack PK::Auto::Pg for "table" names referencing a schema
         - find() with attributes works
index 8ea0b1f..3db2d76 100644 (file)
@@ -358,9 +358,11 @@ sub resolve_join {
     return map { $self->resolve_join($_, $alias, $seen) } @$join;
   } elsif (ref $join eq 'HASH') {
     return
-      map { $self->resolve_join($_, $alias, $seen),
-            $self->related_source($_)->resolve_join($join->{$_}, $_, $seen) }
-           keys %$join;
+      map {
+        my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
+        ($self->resolve_join($_, $alias, $seen),
+          $self->related_source($_)->resolve_join($join->{$_}, $as, $seen));
+      } keys %$join;
   } elsif (ref $join) {
     $self->throw_exception("No idea how to resolve join reftype ".ref $join);
   } else {
index 6f37ba9..2355aeb 100644 (file)
@@ -25,7 +25,7 @@ __PACKAGE__->load_classes(qw/
     'Producer',
     'CD_to_Producer',
   ),
-  qw/SelfRefAlias/
+  qw/SelfRefAlias TreeLike/
 );
 
 1;
index 6c52140..6b2e3f2 100755 (executable)
@@ -114,4 +114,12 @@ $schema->populate('CD_to_Producer', [
   [ 1, 3 ],
 ]);
 
+$schema->populate('TreeLike', [
+  [ qw/id parent name/ ],
+  [ 1, 0, 'foo'  ],
+  [ 2, 1, 'bar'  ],
+  [ 3, 2, 'baz'  ],
+  [ 4, 3, 'quux' ],
+]);
+
 1;
index 8bc7146..8015b29 100644 (file)
@@ -1,6 +1,6 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Fri Jan 27 01:16:24 2006
+-- Created on Mon Feb  6 01:07:16 2006
 -- 
 BEGIN TRANSACTION;
 
@@ -14,14 +14,6 @@ CREATE TABLE twokeys (
 );
 
 --
--- Table: liner_notes
---
-CREATE TABLE liner_notes (
-  liner_id INTEGER PRIMARY KEY NOT NULL,
-  notes varchar NOT NULL
-);
-
---
 -- Table: cd_to_producer
 --
 CREATE TABLE cd_to_producer (
@@ -31,6 +23,14 @@ CREATE TABLE cd_to_producer (
 );
 
 --
+-- Table: liner_notes
+--
+CREATE TABLE liner_notes (
+  liner_id INTEGER PRIMARY KEY NOT NULL,
+  notes varchar NOT NULL
+);
+
+--
 -- Table: artist
 --
 CREATE TABLE artist (
@@ -43,7 +43,8 @@ CREATE TABLE artist (
 --
 CREATE TABLE self_ref_alias (
   self_ref integer NOT NULL,
-  alias integer NOT NULL
+  alias integer NOT NULL,
+  PRIMARY KEY (self_ref, alias)
 );
 
 --
@@ -77,6 +78,14 @@ CREATE TABLE artist_undirected_map (
 );
 
 --
+-- Table: producer
+--
+CREATE TABLE producer (
+  producerid INTEGER PRIMARY KEY NOT NULL,
+  name varchar NOT NULL
+);
+
+--
 -- Table: onekey
 --
 CREATE TABLE onekey (
@@ -96,18 +105,11 @@ CREATE TABLE track (
 );
 
 --
--- Table: producer
+-- Table: treelike
 --
-CREATE TABLE producer (
-  producerid INTEGER PRIMARY KEY NOT NULL,
-  name varchar NOT NULL
-);
-
---
--- Table: self_ref
---
-CREATE TABLE self_ref (
+CREATE TABLE treelike (
   id INTEGER PRIMARY KEY NOT NULL,
+  parent integer NOT NULL,
   name varchar NOT NULL
 );
 
@@ -121,4 +123,12 @@ CREATE TABLE tags (
   PRIMARY KEY (tagid)
 );
 
+--
+-- Table: self_ref
+--
+CREATE TABLE self_ref (
+  id INTEGER PRIMARY KEY NOT NULL,
+  name varchar NOT NULL
+);
+
 COMMIT;
index 87eaf0a..5307067 100644 (file)
@@ -7,7 +7,7 @@ BEGIN {
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 35 );
+        : ( tests => 40 );
 }
 
 # test the abstract join => SQL generator
@@ -234,6 +234,27 @@ $rs = $schema->resultset("Artist")->search(
 cmp_ok($rs->count, '==', 1, "single artist returned from multi-join");
 is($rs->next->name, 'Caterwauler McCrae', "Correct artist returned");
 
+my $queries;
+$schema->storage->debugcb(sub { $queries++ });
+$schema->storage->debug(1);
+
+my $tree_like =
+     $schema->resultset('TreeLike')->find(4,
+       { join     => { parent => { parent => 'parent' } },
+         prefetch => { parent => { parent => 'parent' } } });
+
+is($tree_like->name, 'quux', 'Bottom of tree ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'baz', 'First level up ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'bar', 'Second level up ok');
+$tree_like = $tree_like->parent;
+is($tree_like->name, 'foo', 'Third level up ok');
+
+$schema->storage->debug(0);
+
+cmp_ok($queries, '==', 1, 'Only one query run');
+
 } # end run_tests
 
 1;