Commit 39dd1e53 authored by Benjamin Morel's avatar Benjamin Morel

Disallow empty CompositeExpression

parent 97e0c2bb
......@@ -5,9 +5,7 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Query\Expression;
use Countable;
use function array_filter;
use function array_merge;
use function array_values;
use function count;
use function implode;
......@@ -38,22 +36,20 @@ class CompositeExpression implements Countable
/**
* Each expression part of the composite expression.
*
* @var self[]|string[]
* @var array<int, self|string>
*/
private $parts = [];
/**
* @internal Use the and() / or() factory methods.
*
* @param string $type Instance type of composite expression.
* @param self[]|string[] $parts Composition of expressions to be joined on composite expression.
* @param self|string $part
* @param self|string ...$parts
*/
public function __construct(string $type, array $parts = [])
public function __construct(string $type, $part, ...$parts)
{
$this->type = $type;
$this->parts = array_values(array_filter($parts, static function ($part) {
return ! ($part instanceof self && count($part) === 0);
}));
$this->parts = array_merge([$part], $parts);
}
/**
......@@ -62,7 +58,7 @@ class CompositeExpression implements Countable
*/
public static function and($part, ...$parts) : self
{
return new self(self::TYPE_AND, array_merge([$part], $parts));
return new self(self::TYPE_AND, $part, ...$parts);
}
/**
......@@ -71,7 +67,7 @@ class CompositeExpression implements Countable
*/
public static function or($part, ...$parts) : self
{
return new self(self::TYPE_OR, array_merge([$part], $parts));
return new self(self::TYPE_OR, $part, ...$parts);
}
/**
......
......@@ -1025,7 +1025,7 @@ class QueryBuilder
return $predicate;
}
return new CompositeExpression(CompositeExpression::TYPE_AND, array_merge([$predicate], $predicates));
return new CompositeExpression(CompositeExpression::TYPE_AND, $predicate, ...$predicates);
}
/**
......@@ -1048,7 +1048,7 @@ class QueryBuilder
return $predicates[0];
}
return new CompositeExpression($type, $predicates);
return new CompositeExpression($type, ...$predicates);
}
/**
......
......@@ -44,14 +44,10 @@ class CompositeExpressionTest extends DbalTestCase
}
/**
* @param string[]|CompositeExpression[] $parts
*
* @dataProvider provideDataForConvertToString
*/
public function testCompositeUsageAndGeneration(string $type, array $parts, string $expects) : void
public function testCompositeUsageAndGeneration(CompositeExpression $expr, string $expects) : void
{
$expr = new CompositeExpression($type, $parts);
self::assertEquals($expects, (string) $expr);
}
......@@ -62,45 +58,39 @@ class CompositeExpressionTest extends DbalTestCase
{
return [
[
CompositeExpression::TYPE_AND,
['u.user = 1'],
CompositeExpression::and('u.user = 1'),
'u.user = 1',
],
[
CompositeExpression::TYPE_AND,
['u.user = 1', 'u.group_id = 1'],
CompositeExpression::and('u.user = 1', 'u.group_id = 1'),
'(u.user = 1) AND (u.group_id = 1)',
],
[
CompositeExpression::TYPE_OR,
['u.user = 1'],
CompositeExpression::or('u.user = 1'),
'u.user = 1',
],
[
CompositeExpression::TYPE_OR,
['u.group_id = 1', 'u.group_id = 2'],
CompositeExpression::or('u.group_id = 1', 'u.group_id = 2'),
'(u.group_id = 1) OR (u.group_id = 2)',
],
[
CompositeExpression::TYPE_AND,
[
CompositeExpression::and(
'u.user = 1',
CompositeExpression::or(
'u.group_id = 1',
'u.group_id = 2'
),
],
)
),
'(u.user = 1) AND ((u.group_id = 1) OR (u.group_id = 2))',
],
[
CompositeExpression::TYPE_OR,
[
CompositeExpression::or(
'u.group_id = 1',
CompositeExpression::and(
'u.user = 1',
'u.group_id = 2'
),
],
)
),
'(u.group_id = 1) OR ((u.user = 1) AND (u.group_id = 2))',
],
];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment