diff --git a/src/Storage/DbalNestedSet.php b/src/Storage/DbalNestedSet.php index 72780766..6ffd5feb 100644 --- a/src/Storage/DbalNestedSet.php +++ b/src/Storage/DbalNestedSet.php @@ -205,11 +205,17 @@ public function findRoot(NodeKey $nodeKey) { * {@inheritdoc} */ public function findParent(NodeKey $nodeKey) { - $ancestors = $this->findAncestors($nodeKey); - if (count($ancestors) > 1) { - // Parent is 2nd-last element. - return $ancestors[count($ancestors) - 2]; + // Only selecting the closest ancestor node in the tree. + $stmt = $this->connection->executeQuery('SELECT parent.id, parent.revision_id, parent.left_pos, parent.right_pos, parent.depth FROM ' . $this->tableName . ' AS child, ' . $this->tableName . ' AS parent WHERE child.left_pos > parent.left_pos AND child.right_pos < parent.right_pos AND child.id = ? AND child.revision_id = ? ORDER BY parent.left_pos DESC LIMIT 1', + [$nodeKey->getId(), $nodeKey->getRevisionId()] + ); + $row = $stmt->fetch(); + + if ($row) { + // There is a parent. + return new Node(new NodeKey($row['id'], $row['revision_id']), $row['left_pos'], $row['right_pos'], $row['depth']); } + // No parent. return NULL; } diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index 6177e32c..e3f5239f 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -209,15 +209,40 @@ public function testFindAncestors() { * Tests finding the parent node. */ public function testFindParent() { + // Node 2 is child of Node 1 (root). + $nodeKey = new NodeKey(2, 1); + $parent = $this->nestedSet->findParent($nodeKey); - $nodeKey = new NodeKey(7, 1); + $this->assertEquals(1, $parent->getId()); + $this->assertEquals(1, $parent->getRevisionId()); + $this->assertEquals(1, $parent->getLeft()); + $this->assertEquals(22, $parent->getRight()); + $this->assertEquals(0, $parent->getDepth()); + // Node 7 is child of Node 3. + $nodeKey = new NodeKey(7, 1); $parent = $this->nestedSet->findParent($nodeKey); $this->assertEquals(3, $parent->getId()); $this->assertEquals(1, $parent->getRevisionId()); $this->assertEquals(10, $parent->getLeft()); $this->assertEquals(21, $parent->getRight()); + $this->assertEquals(1, $parent->getDepth()); + + // Node 6 (leaf) is child of Node 4. + $nodeKey = new NodeKey(6, 1); + $parent = $this->nestedSet->findParent($nodeKey); + + $this->assertEquals(4, $parent->getId()); + $this->assertEquals(1, $parent->getRevisionId()); + $this->assertEquals(3, $parent->getLeft()); + $this->assertEquals(8, $parent->getRight()); + $this->assertEquals(2, $parent->getDepth()); + + // Node 1 (Root) has no parent. + $root = new NodeKey(1, 1); + $rootParent = $this->nestedSet->findParent($root); + $this->assertNull($rootParent); }