Skip to content

Commit

Permalink
Avoiding SQL errors by prefixing columns with the Table alias
Browse files Browse the repository at this point in the history
fixes #4508
  • Loading branch information
lorenzo committed Sep 6, 2014
1 parent 4d183f8 commit 06048e1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
42 changes: 31 additions & 11 deletions src/Model/Behavior/TreeBehavior.php
Expand Up @@ -189,7 +189,7 @@ protected function _setParent($entity, $parent) {
$max = $left - 1;

if ($left < $targetLeft) {
//Moving to the right
// Moving to the right
$targetLeft = $parentRight - $diff;
$targetRight = $parentRight - 1;
$min = $right + 1;
Expand All @@ -198,7 +198,7 @@ protected function _setParent($entity, $parent) {
}

if ($right - $left > 1) {
//Correcting internal subtree
// Correcting internal subtree
$internalLeft = $left + 1;
$internalRight = $right - 1;
$this->_sync($targetLeft - $left, '+', "BETWEEN {$internalLeft} AND {$internalRight}", true);
Expand All @@ -210,7 +210,7 @@ protected function _setParent($entity, $parent) {
$this->_unmarkInternalTree();
}

//Allocating new position
// Allocating new position
$entity->set($config['left'], $targetLeft);
$entity->set($config['right'], $targetRight);
}
Expand Down Expand Up @@ -280,13 +280,20 @@ public function findPath(Query $query, array $options) {
}

$config = $this->config();
list($left, $right) = [$config['left'], $config['right']];
$alias = $this->_table->alias();
list($left, $right) = array_map(
function($field) use ($alias) {
return "$alias.$field";
},
[$config['left'], $config['right']]
);

$node = $this->_table->get($options['for'], ['fields' => [$left, $right]]);

return $this->_scope($query)
->where([
"$left <=" => $node->get($left),
"$right >=" => $node->get($right)
"$left <=" => $node->get($config['left']),
"$right >=" => $node->get($config['right'])
]);
}

Expand All @@ -300,7 +307,13 @@ public function findPath(Query $query, array $options) {
*/
public function childCount(Entity $node, $direct = false) {
$config = $this->config();
list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']];
$alias = $this->_table->alias();
list($parent, $left, $right) = array_map(
function($field) use ($alias) {
return "$alias.$field";
},
[$config['parent'], $config['left'], $config['right']]
);

if ($direct) {
return $this->_scope($this->_table->find())
Expand All @@ -309,7 +322,7 @@ public function childCount(Entity $node, $direct = false) {
}

$this->_ensureFields($node);
return ($node->{$right} - $node->{$left} - 1) / 2;
return ($node->get($config['right']) - $node->get($config['left']) - 1) / 2;
}

/**
Expand All @@ -330,8 +343,15 @@ public function childCount(Entity $node, $direct = false) {
*/
public function findChildren(Query $query, array $options) {
$config = $this->config();
$alias = $this->_table->alias();
$options += ['for' => null, 'direct' => false];
list($parent, $left, $right) = [$config['parent'], $config['left'], $config['right']];
list($parent, $left, $right) = array_map(
function($field) use ($alias) {
return "$alias.$field";
},
[$config['parent'], $config['left'], $config['right']]
);

list($for, $direct) = [$options['for'], $options['direct']];

if (empty($for)) {
Expand All @@ -349,8 +369,8 @@ public function findChildren(Query $query, array $options) {
$node = $this->_getNode($for);
return $this->_scope($query)
->where([
"{$right} <" => $node->{$right},
"{$left} >" => $node->{$left}
"{$right} <" => $node->get($config['right']),
"{$left} >" => $node->get($config['left'])
]);
}

Expand Down
21 changes: 21 additions & 0 deletions tests/TestCase/Model/Behavior/TreeBehaviorTest.php
Expand Up @@ -755,6 +755,27 @@ public function testRemoveRootFromTree() {
$this->assertTreeNumbers($expected, $table);
}

/**
* Tests that using associations having tree fields in the schema
* does not generate SQL errors
*
* @return void
*/
public function testFindPathWithAssociation() {
$table = $this->table;
$other = TableRegistry::get('FriendlyTrees', [
'table' => $table->table()
]);
$table->hasOne('FriendlyTrees', [
'foreignKey' => 'id'
]);
$result = $table
->find('children', ['for' => 1])
->contain('FriendlyTrees')
->toArray();
$this->assertCount(9, $result);
}

/**
* Custom assertion use to verify tha a tree is returned in the expected order
* and that it is still valid
Expand Down

0 comments on commit 06048e1

Please sign in to comment.