Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Or Operand detection in MagicJoin #25

Merged
merged 2 commits into from Jun 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/SQLParser/Node/Expression.php
Expand Up @@ -208,12 +208,21 @@ public function walk(VisitorInterface $visitor)
$node = $result;
}
if ($result !== NodeTraverser::DONT_TRAVERSE_CHILDREN) {
foreach ($this->subTree as $key => $operand) {
$result2 = $operand->walk($visitor);
if (is_array($this->subTree)) {
foreach ($this->subTree as $key => $operand) {
$result2 = $operand->walk($visitor);
if ($result2 === NodeTraverser::REMOVE_NODE) {
unset($this->subTree[$key]);
} elseif ($result2 instanceof NodeInterface) {
$this->subTree[$key] = $result2;
}
}
} else {
$result2 = $this->subTree->walk($visitor);
if ($result2 === NodeTraverser::REMOVE_NODE) {
unset($this->subTree[$key]);
$this->subTree = [];
} elseif ($result2 instanceof NodeInterface) {
$this->subTree[$key] = $result2;
$this->subTree = $result2;
}
}
}
Expand Down
17 changes: 9 additions & 8 deletions src/SQLParser/Node/NodeFactory.php
Expand Up @@ -33,6 +33,7 @@
namespace SQLParser\Node;

use Mouf\Database\MagicQueryException;
use Mouf\Database\MagicQueryParserException;
use SQLParser\SqlRenderInterface;
use Doctrine\DBAL\Connection;
use Mouf\MoufManager;
Expand Down Expand Up @@ -620,16 +621,16 @@ public static function simplify($nodes)
*/

if (isset(self::$OPERATOR_TO_CLASS[$operation]) && is_subclass_of(self::$OPERATOR_TO_CLASS[$operation], 'SQLParser\Node\AbstractTwoOperandsOperator')) {
$leftOperand = array_shift($operands);
while (!empty($operands)) {
$rightOperand = array_shift($operands);

$instance = new self::$OPERATOR_TO_CLASS[$operation]();
$instance->setLeftOperand($leftOperand);
$instance->setRightOperand($rightOperand);
$leftOperand = $instance;
if (count($operands) !== 2) {
throw new MagicQueryParserException("Expected exactly 2 operands on ".self::$OPERATOR_TO_CLASS[$operation].". Found ".count($operands));
}

$leftOperand = array_shift($operands);
$rightOperand = array_shift($operands);
$instance = new self::$OPERATOR_TO_CLASS[$operation]();
$instance->setLeftOperand($leftOperand);
$instance->setRightOperand($rightOperand);

return $instance;
} elseif (isset(self::$OPERATOR_TO_CLASS[$operation]) && is_subclass_of(self::$OPERATOR_TO_CLASS[$operation], 'SQLParser\Node\AbstractManyInstancesOperator')) {
$instance = new self::$OPERATOR_TO_CLASS[$operation]();
Expand Down
33 changes: 31 additions & 2 deletions tests/Mouf/Database/MagicQueryTest.php
Expand Up @@ -116,6 +116,16 @@ public function testInNullException() {
$magicQuery->build($sql, ['statuses' => NULL]);
}

/**
* @expectedException \Mouf\Database\MagicQueryException
*/
public function testInvalidSql() {
$magicQuery = new MagicQuery();

$sql = 'SELECT * FROM users WHERE date_end => :startDate';
$this->assertEquals('SELECT * FROM users WHERE date_end => \'2014-06-06\'', self::simplifySql($magicQuery->build($sql, ['startDate' => '2014-06-06'])));
}

public function testWithCache()
{
global $db_url;
Expand Down Expand Up @@ -148,7 +158,7 @@ public function testParseError()
$magicQuery->build($sql);
}

public function testMagicJoin()
private function getSchema()
{
$schema = new Schema();
$role = $schema->createTable('role');
Expand All @@ -165,6 +175,12 @@ public function testMagicJoin()
$role_right->addForeignKeyConstraint($schema->getTable('role'), array('role_id'), array('id'), array('onUpdate' => 'CASCADE'));
$role_right->addForeignKeyConstraint($schema->getTable('right'), array('right_id'), array('id'), array('onUpdate' => 'CASCADE'));
$role_right->setPrimaryKey(['role_id', 'right_id']);
return $schema;
}

public function testMagicJoin()
{
$schema = $this->getSchema();

$schemaAnalyzer = new SchemaAnalyzer(new StubSchemaManager($schema));

Expand All @@ -175,6 +191,19 @@ public function testMagicJoin()
$this->assertEquals($expectedSql, self::simplifySql($magicQuery->build($sql)));
}

public function testMagicJoinNodeWalker()
{
$schema = $this->getSchema();

$schemaAnalyzer = new SchemaAnalyzer(new StubSchemaManager($schema));

$magicQuery = new MagicQuery(null, null, $schemaAnalyzer);

$sql = "SELECT role.* FROM magicjoin(role) WHERE role.label = 'my_role' AND (right.label LIKE '%test%' OR right.label LIKE '%testBis%')";
$expectedSql = "SELECT role.* FROM role LEFT JOIN role_right ON (role_right.role_id = role.id) LEFT JOIN right ON (role_right.right_id = right.id) WHERE (role.label = 'my_role') AND (((right.label LIKE '%test%') OR (right.label LIKE '%testBis%')))";
$this->assertEquals($expectedSql, self::simplifySql($magicQuery->build($sql)));
}

public function testMagicJoin2()
{
$schema = new Schema();
Expand Down Expand Up @@ -290,4 +319,4 @@ private static function simplifySql($sql)

return $sql;
}
}
}