Skip to content

Commit 80a02f0

Browse files
authored
[#42239] Allow table name to be configured (#6)
* [#42239] Allow table name to be configured * Remove unused fixtures * Ensure first char is a letter
1 parent 311c1bf commit 80a02f0

File tree

5 files changed

+123
-122
lines changed

5 files changed

+123
-122
lines changed

src/Storage/DbalNestedSet.php

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,46 @@
1212
*/
1313
class DbalNestedSet implements NestedSetInterface {
1414

15+
/**
16+
* The regex for validating table names.
17+
*/
18+
const VALID_TABLE_REGEX = '/^[a-zA-Z]\w{1,64}$/';
19+
1520
/**
1621
* The database connection.
1722
*
1823
* @var \Doctrine\DBAL\Connection
1924
*/
2025
protected $connection;
2126

27+
/**
28+
* The table name to use for storing the nested set.
29+
*
30+
* @var string
31+
*/
32+
protected $tableName;
33+
2234
/**
2335
* DbalTree constructor.
2436
*
2537
* @param \Doctrine\DBAL\Connection $connection
2638
* The database connection.
39+
* @param string $tableName
40+
* (optional) The table name to use.
2741
*/
28-
public function __construct(Connection $connection) {
42+
public function __construct(Connection $connection, $tableName = 'tree') {
2943
$this->connection = $connection;
44+
if (!preg_match(self::VALID_TABLE_REGEX, $tableName)) {
45+
throw new \InvalidArgumentException("Table name must match the regex " . self::VALID_TABLE_REGEX);
46+
}
47+
$this->tableName = $tableName;
3048
}
3149

3250
/**
3351
* {@inheritdoc}
3452
*/
3553
public function addRootNode(Node $node) {
36-
$maxRight = $this->connection->fetchColumn('SELECT MAX(nested_right) FROM tree');
54+
$maxRight = $this->connection->fetchColumn('SELECT MAX(right_pos) FROM ' . $this->tableName);
3755
if ($maxRight === FALSE) {
3856
$maxRight = 0;
3957
}
@@ -89,10 +107,10 @@ protected function insertNodeAtPostion($newLeftPosition, $depth, Node $node) {
89107
$this->connection->beginTransaction();
90108

91109
// Make space for inserting node.
92-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right + 2 WHERE nested_right >= ?',
110+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos + 2 WHERE right_pos >= ?',
93111
[$newLeftPosition]
94112
);
95-
$this->connection->executeUpdate('UPDATE tree SET nested_left = nested_left + 2 WHERE nested_left >= ?',
113+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos + 2 WHERE left_pos >= ?',
96114
[$newLeftPosition]
97115
);
98116

@@ -131,11 +149,11 @@ protected function doInsertNode($id, $revisionId, $left, $right, $depth) {
131149
$newNode = new Node($id, $revisionId, $left, $right, $depth);
132150

133151
// Insert the new node.
134-
$this->connection->insert('tree', [
152+
$this->connection->insert($this->tableName, [
135153
'id' => $newNode->getId(),
136154
'revision_id' => $newNode->getRevisionId(),
137-
'nested_left' => $newNode->getLeft(),
138-
'nested_right' => $newNode->getRight(),
155+
'left_pos' => $newNode->getLeft(),
156+
'right_pos' => $newNode->getRight(),
139157
'depth' => $newNode->getDepth(),
140158
]);
141159

@@ -148,11 +166,11 @@ protected function doInsertNode($id, $revisionId, $left, $right, $depth) {
148166
public function findDescendants(Node $node, $depth = 0) {
149167
$descendants = [];
150168
$query = $this->connection->createQueryBuilder();
151-
$query->select('child.id', 'child.revision_id', 'child.nested_left', 'child.nested_right', 'child.depth')
152-
->from('tree', 'child')
153-
->from('tree', 'parent')
154-
->where('child.nested_left > parent.nested_left')
155-
->andWhere('child.nested_right < parent.nested_right')
169+
$query->select('child.id', 'child.revision_id', 'child.left_pos', 'child.right_pos', 'child.depth')
170+
->from($this->tableName, 'child')
171+
->from($this->tableName, 'parent')
172+
->where('child.left_pos > parent.left_pos')
173+
->andWhere('child.right_pos < parent.right_pos')
156174
->andWhere('parent.id = :id')
157175
->andWhere('parent.revision_id = :revision_id')
158176
->setParameter(':id', $node->getId())
@@ -163,7 +181,7 @@ public function findDescendants(Node $node, $depth = 0) {
163181
}
164182
$stmt = $query->execute();
165183
while ($row = $stmt->fetch()) {
166-
$descendants[] = new Node($row['id'], $row['revision_id'], $row['nested_left'], $row['nested_right'], $row['depth']);
184+
$descendants[] = new Node($row['id'], $row['revision_id'], $row['left_pos'], $row['right_pos'], $row['depth']);
167185
}
168186
return $descendants;
169187
}
@@ -180,11 +198,11 @@ public function findChildren(Node $node) {
180198
* {@inheritdoc}
181199
*/
182200
public function getNode($id, $revision_id) {
183-
$result = $this->connection->fetchAssoc("SELECT id, revision_id, nested_left, nested_right, depth FROM tree WHERE id = ? AND revision_id = ?",
201+
$result = $this->connection->fetchAssoc("SELECT id, revision_id, left_pos, right_pos, depth FROM " . $this->tableName . " WHERE id = ? AND revision_id = ?",
184202
[$id, $revision_id]
185203
);
186204
if ($result) {
187-
return new Node($id, $revision_id, $result['nested_left'], $result['nested_right'], $result['depth']);
205+
return new Node($id, $revision_id, $result['left_pos'], $result['right_pos'], $result['depth']);
188206
}
189207
}
190208

@@ -193,11 +211,11 @@ public function getNode($id, $revision_id) {
193211
*/
194212
public function findAncestors(Node $node) {
195213
$ancestors = [];
196-
$stmt = $this->connection->executeQuery('SELECT parent.id, parent.revision_id, parent.nested_left, parent.nested_right, parent.depth FROM tree AS child, tree AS parent WHERE child.nested_left BETWEEN parent.nested_left AND parent.nested_right AND child.id = ? AND child.revision_id = ? ORDER BY parent.nested_left',
214+
$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 BETWEEN parent.left_pos AND parent.right_pos AND child.id = ? AND child.revision_id = ? ORDER BY parent.left_pos',
197215
[$node->getId(), $node->getRevisionId()]
198216
);
199217
while ($row = $stmt->fetch()) {
200-
$ancestors[] = new Node($row['id'], $row['revision_id'], $row['nested_left'], $row['nested_right'], $row['depth']);
218+
$ancestors[] = new Node($row['id'], $row['revision_id'], $row['left_pos'], $row['right_pos'], $row['depth']);
201219
}
202220
return $ancestors;
203221
}
@@ -236,9 +254,9 @@ public function findParent(Node $node) {
236254
*/
237255
public function getTree() {
238256
$tree = [];
239-
$stmt = $this->connection->executeQuery('SELECT id, revision_id, nested_left, nested_right, depth FROM tree ORDER BY nested_left');
257+
$stmt = $this->connection->executeQuery('SELECT id, revision_id, left_pos, right_pos, depth FROM ' . $this->tableName . ' ORDER BY left_pos');
240258
while ($row = $stmt->fetch()) {
241-
$tree[] = new Node($row['id'], $row['revision_id'], $row['nested_left'], $row['nested_right'], $row['depth']);
259+
$tree[] = new Node($row['id'], $row['revision_id'], $row['left_pos'], $row['right_pos'], $row['depth']);
242260
}
243261
return $tree;
244262
}
@@ -256,20 +274,20 @@ public function deleteNode(Node $node) {
256274
$this->connection->beginTransaction();
257275

258276
// Delete the node.
259-
$this->connection->executeUpdate('DELETE FROM tree WHERE nested_left = ?',
277+
$this->connection->executeUpdate('DELETE FROM ' . $this->tableName . ' WHERE left_pos = ?',
260278
[$left]
261279
);
262280

263281
// Move children up a level.
264-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right - 1, nested_left = nested_left - 1, depth = depth -1 WHERE nested_left BETWEEN ? AND ?',
282+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos - 1, left_pos = left_pos - 1, depth = depth -1 WHERE left_pos BETWEEN ? AND ?',
265283
[$left, $right]
266284
);
267285

268286
// Move everything back two places.
269-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right - 2 WHERE nested_right > ?',
287+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos - 2 WHERE right_pos > ?',
270288
[$right]
271289
);
272-
$this->connection->executeUpdate('UPDATE tree SET nested_left = tree.nested_left - 2 WHERE nested_left > ?',
290+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos - 2 WHERE left_pos > ?',
273291
[$right]
274292
);
275293

@@ -298,15 +316,15 @@ public function deleteSubTree(Node $node) {
298316
$this->connection->beginTransaction();
299317

300318
// Delete the node.
301-
$this->connection->executeUpdate('DELETE FROM tree WHERE nested_left BETWEEN ? AND ?',
319+
$this->connection->executeUpdate('DELETE FROM ' . $this->tableName . ' WHERE left_pos BETWEEN ? AND ?',
302320
[$left, $right]
303321
);
304322

305323
// Move everything back two places.
306-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right - ? WHERE nested_right > ?',
324+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos - ? WHERE right_pos > ?',
307325
[$width, $right]
308326
);
309-
$this->connection->executeUpdate('UPDATE tree SET nested_left = nested_left - ? WHERE nested_left > ?',
327+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos - ? WHERE left_pos > ?',
310328
[$width, $right]
311329
);
312330

@@ -374,25 +392,25 @@ protected function moveSubTreeToPosition($newLeftPosition, Node $node) {
374392
}
375393

376394
// Create new space for subtree.
377-
$this->connection->executeUpdate('UPDATE tree SET nested_left = nested_left + ? WHERE nested_left >= ?',
395+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos + ? WHERE left_pos >= ?',
378396
[$width, $newLeftPosition]
379397
);
380398

381-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right + ? WHERE nested_right >= ?',
399+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos + ? WHERE right_pos >= ?',
382400
[$width, $newLeftPosition]
383401
);
384402

385403
// Move subtree into new space.
386-
$this->connection->executeUpdate('UPDATE tree SET nested_left = nested_left + ?, nested_right = nested_right + ?, depth = depth + ? WHERE nested_left >= ? AND nested_right < ?',
404+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos + ?, right_pos = right_pos + ?, depth = depth + ? WHERE left_pos >= ? AND right_pos < ?',
387405
[$distance, $distance, $depthDiff, $tempPos, $tempPos + $width]
388406
);
389407

390408
// Remove old space vacated by subtree.
391-
$this->connection->executeUpdate('UPDATE tree SET nested_left = nested_left - ? WHERE nested_left > ?',
409+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET left_pos = left_pos - ? WHERE left_pos > ?',
392410
[$width, $node->getRight()]
393411
);
394412

395-
$this->connection->executeUpdate('UPDATE tree SET nested_right = nested_right - ? WHERE nested_right > ?',
413+
$this->connection->executeUpdate('UPDATE ' . $this->tableName . ' SET right_pos = right_pos - ? WHERE right_pos > ?',
396414
[$width, $node->getRight()]
397415
);
398416
}
@@ -407,11 +425,11 @@ protected function moveSubTreeToPosition($newLeftPosition, Node $node) {
407425
* {@inheritdoc}
408426
*/
409427
public function getNodeAtPosition($left) {
410-
$result = $this->connection->fetchAssoc("SELECT id, revision_id, nested_left, nested_right, depth FROM tree WHERE nested_left = ?",
428+
$result = $this->connection->fetchAssoc("SELECT id, revision_id, left_pos, right_pos, depth FROM " . $this->tableName . " WHERE left_pos = ?",
411429
[$left]
412430
);
413431
if ($result) {
414-
return new Node($result['id'], $result['revision_id'], $result['nested_left'], $result['nested_right'], $result['depth']);
432+
return new Node($result['id'], $result['revision_id'], $result['left_pos'], $result['right_pos'], $result['depth']);
415433
}
416434
}
417435

tests/Fixtures/schema.php

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/Fixtures/schema.sql

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/Fixtures/test_data.sql

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)