Skip to content

Commit 695f6fd

Browse files
committed
Fixed lazychaser#93: works with prefixed tables
1 parent 5524d6c commit 695f6fd

File tree

4 files changed

+62
-32
lines changed

4 files changed

+62
-32
lines changed

phpunit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
include __DIR__.'/vendor/autoload.php';
44

55
$capsule = new \Illuminate\Database\Capsule\Manager;
6-
$capsule->addConnection(array('driver' => 'sqlite', 'database' => ':memory:'));
6+
$capsule->addConnection([ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'prefix' ]);
77
$capsule->setEventDispatcher(new \Illuminate\Events\Dispatcher);
88
$capsule->bootEloquent();
99
$capsule->setAsGlobal();

src/DescendantsRelation.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ public function getRelationQuery(EloquentBuilder $query, EloquentBuilder $parent
5252

5353
$query->from($table.' as '.$hash = $this->getRelationCountHash());
5454

55-
$table = $this->wrap($table);
56-
$hash = $this->wrap($hash);
57-
$lft = $this->wrap($this->parent->getLftName());
58-
$rgt = $this->wrap($this->parent->getRgtName());
55+
$grammar = $query->getQuery()->getGrammar();
56+
57+
$table = $grammar->wrapTable($table);
58+
$hash = $grammar->wrapTable($hash);
59+
$lft = $grammar->wrap($this->parent->getLftName());
60+
$rgt = $grammar->wrap($this->parent->getRgtName());
5961

6062
return $query->whereRaw("{$hash}.{$lft} between {$table}.{$lft} + 1 and {$table}.{$rgt}");
6163
}

src/QueryBuilder.php

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,15 @@ public function withDepth($as = 'depth')
316316

317317
list($lft, $rgt) = $this->wrappedColumns();
318318

319+
$alias = '_d';
320+
$wrappedAlias = $this->query->getGrammar()->wrapTable($alias);
321+
319322
$query = $this->model
320323
->newScopedQuery('_d')
321324
->toBase()
322325
->selectRaw('count(1) - 1')
323-
->from($this->model->getTable().' as _d')
324-
->whereRaw("{$table}.{$lft} between _d.{$lft} and _d.{$rgt}");
326+
->from($this->model->getTable().' as '.$alias)
327+
->whereRaw("{$table}.{$lft} between {$wrappedAlias}.{$lft} and {$wrappedAlias}.{$rgt}");
325328

326329
$this->query->selectSub($query, $as);
327330

@@ -625,21 +628,27 @@ protected function getDuplicatesQuery()
625628
{
626629
$table = $this->wrappedTable();
627630

631+
$firstAlias = 'c1';
632+
$secondAlias = 'c2';
633+
634+
$waFirst = $this->query->getGrammar()->wrapTable($firstAlias);
635+
$waSecond = $this->query->getGrammar()->wrapTable($secondAlias);
636+
628637
$query = $this->model
629-
->newNestedSetQuery('c1')
638+
->newNestedSetQuery($firstAlias)
630639
->toBase()
631-
->from($this->query->raw("{$table} c1, {$table} c2"))
632-
->whereRaw("c1.id < c2.id")
633-
->whereNested(function (BaseQueryBuilder $inner) {
640+
->from($this->query->raw("{$table} as {$waFirst}, {$table} {$waSecond}"))
641+
->whereRaw("{$waFirst}.id < {$waSecond}.id")
642+
->whereNested(function (BaseQueryBuilder $inner) use ($waFirst, $waSecond) {
634643
list($lft, $rgt) = $this->wrappedColumns();
635644

636-
$inner->orWhereRaw("c1.{$lft}=c2.{$lft}")
637-
->orWhereRaw("c1.{$rgt}=c2.{$rgt}")
638-
->orWhereRaw("c1.{$lft}=c2.{$rgt}")
639-
->orWhereRaw("c1.{$rgt}=c2.{$lft}");
645+
$inner->orWhereRaw("{$waFirst}.{$lft}={$waSecond}.{$lft}")
646+
->orWhereRaw("{$waFirst}.{$rgt}={$waSecond}.{$rgt}")
647+
->orWhereRaw("{$waFirst}.{$lft}={$waSecond}.{$rgt}")
648+
->orWhereRaw("{$waFirst}.{$rgt}={$waSecond}.{$lft}");
640649
});
641650

642-
return $this->model->applyNestedSetScope($query, 'c2');
651+
return $this->model->applyNestedSetScope($query, $secondAlias);
643652
}
644653

645654
/**
@@ -649,25 +658,36 @@ protected function getWrongParentQuery()
649658
{
650659
$table = $this->wrappedTable();
651660
$keyName = $this->wrappedKey();
652-
$parentIdName = $this->query->raw($this->model->getParentIdName());
661+
662+
$grammar = $this->query->getGrammar();
663+
664+
$parentIdName = $grammar->wrap($this->model->getParentIdName());
665+
666+
$parentAlias = 'p';
667+
$childAlias = 'c';
668+
$intermAlias = 'i';
669+
670+
$waParent = $grammar->wrapTable($parentAlias);
671+
$waChild = $grammar->wrapTable($childAlias);
672+
$waInterm = $grammar->wrapTable($intermAlias);
653673

654674
$query = $this->model
655675
->newNestedSetQuery('c')
656676
->toBase()
657-
->from($this->query->raw("{$table} c, {$table} p, $table m"))
658-
->whereRaw("c.{$parentIdName}=p.{$keyName}")
659-
->whereRaw("m.{$keyName} <> p.{$keyName}")
660-
->whereRaw("m.{$keyName} <> c.{$keyName}")
661-
->whereNested(function (BaseQueryBuilder $inner) {
677+
->from($this->query->raw("{$table} as {$waChild}, {$table} as {$waParent}, $table as {$waInterm}"))
678+
->whereRaw("{$waChild}.{$parentIdName}={$waParent}.{$keyName}")
679+
->whereRaw("{$waInterm}.{$keyName} <> {$waParent}.{$keyName}")
680+
->whereRaw("{$waInterm}.{$keyName} <> {$waChild}.{$keyName}")
681+
->whereNested(function (BaseQueryBuilder $inner) use ($waInterm, $waChild, $waParent) {
662682
list($lft, $rgt) = $this->wrappedColumns();
663683

664-
$inner->whereRaw("c.{$lft} not between p.{$lft} and p.{$rgt}")
665-
->orWhereRaw("c.{$lft} between m.{$lft} and m.{$rgt}")
666-
->whereRaw("m.{$lft} between p.{$lft} and p.{$rgt}");
684+
$inner->whereRaw("{$waChild}.{$lft} not between {$waParent}.{$lft} and {$waParent}.{$rgt}")
685+
->orWhereRaw("{$waChild}.{$lft} between {$waInterm}.{$lft} and {$waInterm}.{$rgt}")
686+
->whereRaw("{$waInterm}.{$lft} between {$waParent}.{$lft} and {$waParent}.{$rgt}");
667687
});
668688

669-
$this->model->applyNestedSetScope($query, 'p');
670-
$this->model->applyNestedSetScope($query, 'm');
689+
$this->model->applyNestedSetScope($query, $parentAlias);
690+
$this->model->applyNestedSetScope($query, $intermAlias);
671691

672692
return $query;
673693
}
@@ -681,19 +701,23 @@ protected function getMissingParentQuery()
681701
->newNestedSetQuery()
682702
->toBase()
683703
->whereNested(function (BaseQueryBuilder $inner) {
704+
$grammar = $this->query->getGrammar();
705+
684706
$table = $this->wrappedTable();
685707
$keyName = $this->wrappedKey();
686-
$parentIdName = $this->query->raw($this->model->getParentIdName());
708+
$parentIdName = $grammar->wrap($this->model->getParentIdName());
709+
$alias = 'p';
710+
$wrappedAlias = $grammar->wrapTable($alias);
687711

688712
$existsCheck = $this->model
689713
->newNestedSetQuery()
690714
->toBase()
691715
->selectRaw('1')
692-
->from($this->query->raw("{$table} p"))
693-
->whereRaw("{$table}.{$parentIdName} = p.{$keyName}")
716+
->from($this->query->raw("{$table} as {$wrappedAlias}"))
717+
->whereRaw("{$table}.{$parentIdName} = {$wrappedAlias}.{$keyName}")
694718
->limit(1);
695719

696-
$this->model->applyNestedSetScope($existsCheck, 'p');
720+
$this->model->applyNestedSetScope($existsCheck, $alias);
697721

698722
$inner->whereRaw("{$parentIdName} is not null")
699723
->addWhereExistsQuery($existsCheck, 'and', true);

tests/NodeTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public function assertTreeNotBroken($table = 'categories')
4949
{
5050
$checks = array();
5151

52+
$connection = Capsule::connection();
53+
54+
$table = $connection->getQueryGrammar()->wrapTable($table);
55+
5256
// Check if lft and rgt values are ok
5357
$checks[] = "from $table where _lft >= _rgt or (_rgt - _lft) % 2 = 0";
5458

@@ -66,7 +70,7 @@ public function assertTreeNotBroken($table = 'categories')
6670

6771
$sql = 'select max(error) as errors from ('.implode(' union ', $checks).') _';
6872

69-
$actual = Capsule::connection()->selectOne($sql);
73+
$actual = $connection->selectOne($sql);
7074

7175
$this->assertEquals(null, $actual->errors, "The tree structure of $table is broken!");
7276
$actual = (array)Capsule::connection()->selectOne($sql);

0 commit comments

Comments
 (0)