Skip to content

Commit

Permalink
No implicit IN condition operator for array value
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Jun 8, 2024
1 parent 659acbb commit 8a9e01a
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 23 deletions.
7 changes: 4 additions & 3 deletions docs/conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ If you are building multiple conditions against the same field, you can use this
format:

```
$m->addCondition('name', ['John', 'Joe']);
$m->addCondition('name', 'in', ['John', 'Joe']);
```

For all other cases you can implement them with {php:meth}`Model::expr`:
Expand Down Expand Up @@ -381,9 +381,10 @@ Model::addCondition method

Creates condition object based on provided arguments. It acts similar to Model::addCondition

$key can be Model field name, Field object, Expression object, FALSE (interpreted as Expression('false')), TRUE (interpreted as empty condition) or an array in the form of [$key, $operator, $value]
$key can be Model field name, Field object, Expression object, `false` (interpreted as Expression('false')),
`true` (interpreted as empty condition) or an array in the form of [$key, $operator, $value]
$operator can be one of the supported operators >, <, >=, <=, !=, in, not in, like, not like, regexp, not regexp
$value can be Field object, Expression object, array (interpreted as 'any of the values') or other scalar value
$value can be Field object, Expression object or any scalar value

If $value is omitted as argument then $operator is considered as $value and '=' is used as operator

Expand Down
7 changes: 1 addition & 6 deletions src/Model/Scope/Condition.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,7 @@ public function __construct($field, $operator = null, $value = null)
}
}

if (!in_array($this->operator, [
self::OPERATOR_EQUALS,
self::OPERATOR_IN,
self::OPERATOR_DOESNOT_EQUAL,
self::OPERATOR_NOT_IN,
], true)) {
if (!in_array($this->operator, [self::OPERATOR_IN, self::OPERATOR_NOT_IN], true)) {
throw (new Exception('Operator is not supported for array condition value'))
->addMoreInfo('operator', $operator)
->addMoreInfo('value', $value);
Expand Down
2 changes: 1 addition & 1 deletion src/Persistence/Array_/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ protected function evaluateIf($v1, string $operator, $v2): bool

switch (strtoupper($operator)) {
case '=':
$res = is_array($v2) ? $this->evaluateIf($v1, 'IN', $v2) : $v1 === $v2;
$res = $v1 === $v2;

break;
case '>':
Expand Down
4 changes: 1 addition & 3 deletions src/Persistence/Sql/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,7 @@ protected function _subrenderCondition(array $row): string
$value = $value->getDsqlExpression($this);
}

if (is_array($value)) {
$operator = 'in';
} elseif ($value instanceof self && $value->mode === 'select') {
if ($value instanceof self && $value->mode === 'select') {
$operator = 'in';
} else {
$operator = '=';
Expand Down
25 changes: 23 additions & 2 deletions tests/ConditionSqlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ public function testArrayCondition(): void

$m = new Model($this->db, ['table' => 'user']);
$m->addField('name');
$m->addCondition('name', ['John', 'Doe']);
$m->addCondition('name', 'in', ['John', 'Doe']);
self::assertCount(1, $m->export());

$m = new Model($this->db, ['table' => 'user']);
Expand All @@ -373,7 +373,7 @@ public function testArrayCondition(): void

$m = new Model($this->db, ['table' => 'user']);
$m->addField('name');
$m->addCondition('name', []); // this should not fail, should be always false
$m->addCondition('name', 'in', []); // this should not fail, should be always false
self::assertCount(0, $m->export());

$m = new Model($this->db, ['table' => 'user']);
Expand All @@ -382,6 +382,27 @@ public function testArrayCondition(): void
self::assertCount(3, $m->export());
}

public function testConditionEqualWithArrayException(): void
{
$m = new Model($this->db, ['table' => 'user']);
$m->addField('name');

$this->expectException(Exception::class);
$this->expectExceptionMessage('Operator is not supported for array condition value');
$m->addCondition('name', ['John', 'Doe']);
}

public function testConditionInWithNonArrayException(): void
{
$m = new Model($this->db, ['table' => 'user']);
$m->addField('name');
$m->addCondition('name', 'not in', 'John');

$this->expectException(Exception::class);
$this->expectExceptionMessage('Unsupported operator for non-array value');
$m->export();
}

public function testDateCondition(): void
{
$this->setDb([
Expand Down
9 changes: 1 addition & 8 deletions tests/Persistence/ArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ public function testConditionRegexp(): void
], $m->action('select')->getRows());

$m->scope()->clear();
$m->addCondition('code', [11, 12]);
$m->addCondition('code', 'IN', [11, 12]);
self::assertSame([
$dbDataCountries[1],
$dbDataCountries[2],
Expand All @@ -473,13 +473,6 @@ public function testConditionRegexp(): void
$dbDataCountries[8],
$dbDataCountries[9],
], $m->action('select')->getRows());

$m->scope()->clear();
$m->addCondition('code', '!=', [11, 12, 13, 14, 15, 16, 17]);
self::assertSame([
$dbDataCountries[8],
$dbDataCountries[9],
], $m->action('select')->getRows());
}

public function testAggregates(): void
Expand Down
9 changes: 9 additions & 0 deletions tests/Persistence/Sql/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,15 @@ public function testWhereIncompatibleObject3(): void
$this->q('[where]')->where('a', '!=', new \DateTime());
}

public function testWhereNoOperatorWithArrayException(): void
{
$q = $this->q('[where]')->where('a', [1, 2]);

$this->expectException(Exception::class);
$this->expectExceptionMessage('Unsupported operator for array value');
$q->render();
}

/**
* @param mixed $value
*
Expand Down

0 comments on commit 8a9e01a

Please sign in to comment.