Skip to content

Commit c83f9aa

Browse files
committed
Merging not_in fix into 1.4
2 parents ab36f3f + 22470bb commit c83f9aa

File tree

5 files changed

+81
-50
lines changed

5 files changed

+81
-50
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,10 @@ jobs:
3535
- *composerupdate
3636
script:
3737
- *phpunit
38+
- stage: test
39+
php: 7.3
40+
env: PREFER_LOWEST=""
41+
before_script:
42+
- *composerupdate
43+
script:
44+
- *phpunit
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace SQLParser\Node;
4+
use Doctrine\DBAL\Connection;
5+
use Doctrine\DBAL\Platforms\AbstractPlatform;
6+
use Mouf\Database\MagicQueryException;
7+
8+
/**
9+
* This class represents an In operation in an SQL expression.
10+
*
11+
* @author David Négrier <[email protected]>
12+
*/
13+
abstract class AbstractInListOperator extends AbstractTwoOperandsOperator
14+
{
15+
protected function getSql(array $parameters, AbstractPlatform $platform, $indent = 0, $conditionsMode = self::CONDITION_APPLY, bool $extrapolateParameters = true)
16+
{
17+
$rightOperand = $this->getRightOperand();
18+
19+
$rightOperand = $this->refactorParameterToExpression($rightOperand);
20+
21+
$this->setRightOperand($rightOperand);
22+
23+
$parameterNode = $this->getParameter($rightOperand);
24+
25+
if ($parameterNode !== null) {
26+
if (!isset($parameters[$parameterNode->getName()])) {
27+
throw new MagicQueryException("Missing parameter '" . $parameterNode->getName() . "' for 'IN' operand.");
28+
}
29+
if ($parameters[$parameterNode->getName()] === []) {
30+
return "FALSE";
31+
}
32+
}
33+
34+
return parent::getSql($parameters, $platform, $indent, $conditionsMode, $extrapolateParameters);
35+
}
36+
37+
protected function refactorParameterToExpression(NodeInterface $rightOperand): NodeInterface
38+
{
39+
if ($rightOperand instanceof Parameter) {
40+
$expression = new Expression();
41+
$expression->setSubTree([$rightOperand]);
42+
$expression->setBrackets(true);
43+
return $expression;
44+
}
45+
return $rightOperand;
46+
}
47+
48+
protected function getParameter(NodeInterface $operand): ?Parameter
49+
{
50+
if (!$operand instanceof Expression) {
51+
return null;
52+
}
53+
$subtree = $operand->getSubTree();
54+
if (!isset($subtree[0])) {
55+
return null;
56+
}
57+
if ($subtree[0] instanceof Parameter) {
58+
return $subtree[0];
59+
}
60+
return null;
61+
}
62+
}

src/SQLParser/Node/In.php

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @author David Négrier <[email protected]>
1111
*/
12-
class In extends AbstractTwoOperandsOperator
12+
class In extends AbstractInListOperator
1313
{
1414
/**
1515
* Returns the symbol for this operator.
@@ -20,52 +20,4 @@ protected function getOperatorSymbol()
2020
{
2121
return 'IN';
2222
}
23-
24-
protected function getSql(array $parameters, AbstractPlatform $platform, $indent = 0, $conditionsMode = self::CONDITION_APPLY, bool $extrapolateParameters = true)
25-
{
26-
$rightOperand = $this->getRightOperand();
27-
28-
$rightOperand = $this->refactorParameterToExpression($rightOperand);
29-
30-
$this->setRightOperand($rightOperand);
31-
32-
$parameterNode = $this->getParameter($rightOperand);
33-
34-
if ($parameterNode !== null) {
35-
if (!isset($parameters[$parameterNode->getName()])) {
36-
throw new MagicQueryException("Missing parameter '" . $parameterNode->getName() . "' for 'IN' operand.");
37-
}
38-
if ($parameters[$parameterNode->getName()] === []) {
39-
return "FALSE";
40-
}
41-
}
42-
43-
return parent::getSql($parameters, $platform, $indent, $conditionsMode, $extrapolateParameters);
44-
}
45-
46-
protected function refactorParameterToExpression(NodeInterface $rightOperand): NodeInterface
47-
{
48-
if ($rightOperand instanceof Parameter) {
49-
$expression = new Expression();
50-
$expression->setSubTree([$rightOperand]);
51-
$expression->setBrackets(true);
52-
return $expression;
53-
}
54-
return $rightOperand;
55-
}
56-
57-
protected function getParameter(NodeInterface $operand): ?Parameter
58-
{
59-
if (!$operand instanceof Expression) {
60-
return null;
61-
}
62-
$subtree = $operand->getSubTree();
63-
if (!isset($subtree[0])) {
64-
return null;
65-
}
66-
if ($subtree[0] instanceof Parameter) {
67-
return $subtree[0];
68-
}
69-
return null;
70-
}
7123
}

src/SQLParser/Node/NotIn.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* @author David Négrier <[email protected]>
99
*/
10-
class NotIn extends AbstractTwoOperandsOperator
10+
class NotIn extends AbstractInListOperator
1111
{
1212
/**
1313
* Returns the symbol for this operator.

tests/Mouf/Database/MagicQueryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ public function testStandardSelect()
7979
$sql = 'SELECT * FROM users WHERE status IN :statuses';
8080
$this->assertEquals('SELECT * FROM users WHERE status IN (\'1\',\'2\')', self::simplifySql($magicQuery->build($sql, ['statuses' => [1, 2]])));
8181

82+
$sql = 'SELECT * FROM users WHERE status not in :status';
83+
$this->assertEquals("SELECT * FROM users WHERE status NOT IN ('2','4')", self::simplifySql($magicQuery->build($sql, ['status' => [2, 4]])));
84+
85+
$sql = 'SELECT * FROM users WHERE status not in (:status)';
86+
$this->assertEquals("SELECT * FROM users WHERE status NOT IN ('2','4')", self::simplifySql($magicQuery->build($sql, ['status' => [2, 4]])));
87+
8288
$sql = 'SELECT * FROM myTable where someField BETWEEN :value1 AND :value2';
8389
$this->assertEquals("SELECT * FROM myTable WHERE someField BETWEEN '2' AND '4'", self::simplifySql($magicQuery->build($sql, ['value1' => 2, 'value2' => 4])));
8490
$this->assertEquals("SELECT * FROM myTable WHERE someField >= '2'", self::simplifySql($magicQuery->build($sql, ['value1' => 2])));
@@ -434,6 +440,10 @@ public function testBuildPreparedStatement()
434440
// Let's check that MagicQuery is cleverly adding parenthesis if the user forgot those in the "IN" statement.
435441
$sql = 'SELECT id FROM users WHERE status IN :status';
436442
$this->assertEquals("SELECT id FROM users WHERE status IN (:status)", self::simplifySql($magicQuery->buildPreparedStatement($sql, ['status' => [1,2]])));
443+
444+
// Let's check that MagicQuery is cleverly adding parenthesis if the user forgot those in the "NOT IN" statement.
445+
$sql = 'SELECT id FROM users WHERE status NOT IN :status';
446+
$this->assertEquals("SELECT id FROM users WHERE status NOT IN (:status)", self::simplifySql($magicQuery->buildPreparedStatement($sql, ['status' => [1,2]])));
437447
}
438448

439449
public function testSetOutputDialect()

0 commit comments

Comments
 (0)