diff --git a/CHANGELOG.md b/CHANGELOG.md index ea6fddeaa..2d7250451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,7 @@ - Chg #1001: Remove `ParamInterface` (@vjik) - Chg #1001: Add public properties `$type` and `$value` to `Param` class instead of `getType()` and `getValue()` methods that were removed (@vjik) - Chg #1002: Remove specific condition interfaces (@vjik) +- Chg #1003: Refactor namespace of condition objects and use promoted properties instead of getters (@vjik) ## 1.3.0 March 21, 2024 diff --git a/UPGRADE.md b/UPGRADE.md index 64ec1b85c..54fa1ed4c 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -253,3 +253,5 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace `ConjunctionConditionInterface`, `ExistConditionInterface`, `HashConditionInterface`, `InConditionInterface`, `LikeConditionInterface`, `NotConditionInterface`, `OverlapsConditionInterface`, `SimpleConditionInterface`; - `ConditionInterface` moved to `Yiisoft\Db\QueryBuilder\Condition` namespace; +- Remove `AbstractConjunctionCondition` and `AbstractOverlapsConditionBuilder`; +- Change namespace of condition and condition builder classes; diff --git a/src/QueryBuilder/AbstractDQLQueryBuilder.php b/src/QueryBuilder/AbstractDQLQueryBuilder.php index 7e8f370dc..ab22cf1bc 100644 --- a/src/QueryBuilder/AbstractDQLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDQLQueryBuilder.php @@ -536,10 +536,9 @@ protected function defaultExpressionBuilders(): array Query::class => QueryExpressionBuilder::class, Param::class => ParamBuilder::class, Expression::class => ExpressionBuilder::class, - Condition\AbstractConjunctionCondition::class => Condition\Builder\ConjunctionConditionBuilder::class, Condition\NotCondition::class => Condition\Builder\NotConditionBuilder::class, - Condition\AndCondition::class => Condition\Builder\ConjunctionConditionBuilder::class, - Condition\OrCondition::class => Condition\Builder\ConjunctionConditionBuilder::class, + Condition\AndCondition::class => Condition\Builder\LogicalConditionBuilder::class, + Condition\OrCondition::class => Condition\Builder\LogicalConditionBuilder::class, Condition\BetweenCondition::class => Condition\Builder\BetweenConditionBuilder::class, Condition\InCondition::class => Condition\Builder\InConditionBuilder::class, Condition\LikeCondition::class => Condition\Builder\LikeConditionBuilder::class, diff --git a/src/QueryBuilder/Condition/AbstractConjunctionCondition.php b/src/QueryBuilder/Condition/AbstractConjunctionCondition.php deleted file mode 100644 index 7295b8704..000000000 --- a/src/QueryBuilder/Condition/AbstractConjunctionCondition.php +++ /dev/null @@ -1,35 +0,0 @@ -expressions; - } - - public static function fromArrayDefinition(string $operator, array $operands): self - { - return new static($operands); - } -} diff --git a/src/QueryBuilder/Condition/AbstractOverlapsCondition.php b/src/QueryBuilder/Condition/AbstractOverlapsCondition.php index 7adc5c69f..27810a68c 100644 --- a/src/QueryBuilder/Condition/AbstractOverlapsCondition.php +++ b/src/QueryBuilder/Condition/AbstractOverlapsCondition.php @@ -15,26 +15,14 @@ */ abstract class AbstractOverlapsCondition implements ConditionInterface { - public function __construct( - private string|ExpressionInterface $column, - private iterable|ExpressionInterface $values, - ) { - } - - /** - * @return ExpressionInterface|string The column name or an Expression. - */ - public function getColumn(): string|ExpressionInterface - { - return $this->column; - } - /** - * @return ExpressionInterface|iterable An array of values that {@see columns} value should overlap. + * @param ExpressionInterface|string $column The column name or an expression. + * @param ExpressionInterface|iterable $values An array of values that {@see $columns} value should overlap. */ - public function getValues(): iterable|ExpressionInterface - { - return $this->values; + public function __construct( + public readonly string|ExpressionInterface $column, + public readonly iterable|ExpressionInterface $values, + ) { } /** diff --git a/src/QueryBuilder/Condition/AndCondition.php b/src/QueryBuilder/Condition/AndCondition.php index 464e7286e..4a6ab6c02 100644 --- a/src/QueryBuilder/Condition/AndCondition.php +++ b/src/QueryBuilder/Condition/AndCondition.php @@ -4,16 +4,26 @@ namespace Yiisoft\Db\QueryBuilder\Condition; +use Yiisoft\Db\Expression\ExpressionInterface; + /** * Condition that connects two or more SQL expressions with the `AND` operator. */ -final class AndCondition extends AbstractConjunctionCondition +final class AndCondition implements ConditionInterface { /** - * @return string The operator that's represented by this condition class, such as `AND`, `OR`. + * @param array $expressions The expressions that are connected by this condition. + * + * @psalm-param array $expressions */ - public function getOperator(): string + public function __construct( + public readonly array $expressions, + ) { + } + + public static function fromArrayDefinition(string $operator, array $operands): self { - return 'AND'; + /** @psalm-var array $operands */ + return new self($operands); } } diff --git a/src/QueryBuilder/Condition/BetweenColumnsCondition.php b/src/QueryBuilder/Condition/BetweenColumnsCondition.php index 25cbeded1..df38fff5f 100644 --- a/src/QueryBuilder/Condition/BetweenColumnsCondition.php +++ b/src/QueryBuilder/Condition/BetweenColumnsCondition.php @@ -39,44 +39,18 @@ */ final class BetweenColumnsCondition implements ConditionInterface { - public function __construct( - private array|int|string|Iterator|ExpressionInterface $value, - private string $operator, - private string|ExpressionInterface $intervalStartColumn, - private string|ExpressionInterface $intervalEndColumn - ) { - } - - /** - * @return ExpressionInterface|string The column name or expression that's the end of the interval. - */ - public function getIntervalEndColumn(): string|ExpressionInterface - { - return $this->intervalEndColumn; - } - - /** - * @return ExpressionInterface|string The column name or expression that's the beginning of the interval. - */ - public function getIntervalStartColumn(): string|ExpressionInterface - { - return $this->intervalStartColumn; - } - /** - * @return string The operator to use (for example `BETWEEN` or `NOT BETWEEN`). + * @param array|ExpressionInterface|int|Iterator|string $value The value to compare against. + * @param string $operator The operator to use (for example `BETWEEN` or `NOT BETWEEN`). + * @param ExpressionInterface|string $intervalStartColumn The column name or expression that's the beginning of the interval. + * @param ExpressionInterface|string $intervalEndColumn The column name or expression that's the end of the interval. */ - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return array|ExpressionInterface|int|Iterator|string The value to compare against. - */ - public function getValue(): array|int|string|Iterator|ExpressionInterface - { - return $this->value; + public function __construct( + public readonly array|int|string|Iterator|ExpressionInterface $value, + public readonly string $operator, + public readonly string|ExpressionInterface $intervalStartColumn, + public readonly string|ExpressionInterface $intervalEndColumn, + ) { } /** diff --git a/src/QueryBuilder/Condition/BetweenCondition.php b/src/QueryBuilder/Condition/BetweenCondition.php index d752fd09d..32dafe769 100644 --- a/src/QueryBuilder/Condition/BetweenCondition.php +++ b/src/QueryBuilder/Condition/BetweenCondition.php @@ -12,44 +12,18 @@ */ final class BetweenCondition implements ConditionInterface { - public function __construct( - private string|ExpressionInterface $column, - private string $operator, - private mixed $intervalStart, - private mixed $intervalEnd - ) { - } - - /** - * @return ExpressionInterface|string The column name. - */ - public function getColumn(): string|ExpressionInterface - { - return $this->column; - } - - /** - * @return mixed End of the interval. - */ - public function getIntervalEnd(): mixed - { - return $this->intervalEnd; - } - /** - * @return mixed Beginning of the interval. + * @param ExpressionInterface|string $column The column name. + * @param string $operator The operator to use (for example `BETWEEN` or `NOT BETWEEN`). + * @param mixed $intervalStart Beginning of the interval. + * @param mixed $intervalEnd End of the interval. */ - public function getIntervalStart(): mixed - { - return $this->intervalStart; - } - - /** - * @return string The operator to use (for example `BETWEEN` or `NOT BETWEEN`). - */ - public function getOperator(): string - { - return $this->operator; + public function __construct( + public readonly string|ExpressionInterface $column, + public readonly string $operator, + public readonly mixed $intervalStart, + public readonly mixed $intervalEnd + ) { } /** diff --git a/src/QueryBuilder/Condition/Builder/AbstractOverlapsConditionBuilder.php b/src/QueryBuilder/Condition/Builder/AbstractOverlapsConditionBuilder.php deleted file mode 100644 index 1f420f06b..000000000 --- a/src/QueryBuilder/Condition/Builder/AbstractOverlapsConditionBuilder.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ -abstract class AbstractOverlapsConditionBuilder implements ExpressionBuilderInterface -{ - public function __construct(protected QueryBuilderInterface $queryBuilder) - { - } - - protected function prepareColumn(ExpressionInterface|string $column): string - { - if ($column instanceof ExpressionInterface) { - return $this->queryBuilder->buildExpression($column); - } - - return $this->queryBuilder->getQuoter()->quoteColumnName($column); - } -} diff --git a/src/QueryBuilder/Condition/Builder/BetweenColumnsConditionBuilder.php b/src/QueryBuilder/Condition/Builder/BetweenColumnsConditionBuilder.php index 10f87d61a..7dafffc78 100644 --- a/src/QueryBuilder/Condition/Builder/BetweenColumnsConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/BetweenColumnsConditionBuilder.php @@ -39,10 +39,10 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $operator = $expression->getOperator(); - $startColumn = $this->escapeColumnName($expression->getIntervalStartColumn(), $params); - $endColumn = $this->escapeColumnName($expression->getIntervalEndColumn(), $params); - $value = $this->createPlaceholder($expression->getValue(), $params); + $operator = $expression->operator; + $startColumn = $this->escapeColumnName($expression->intervalStartColumn, $params); + $endColumn = $this->escapeColumnName($expression->intervalEndColumn, $params); + $value = $this->createPlaceholder($expression->value, $params); return "$value $operator $startColumn AND $endColumn"; } diff --git a/src/QueryBuilder/Condition/Builder/BetweenConditionBuilder.php b/src/QueryBuilder/Condition/Builder/BetweenConditionBuilder.php index 0815e3883..255cf412a 100644 --- a/src/QueryBuilder/Condition/Builder/BetweenConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/BetweenConditionBuilder.php @@ -38,16 +38,18 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $operator = $expression->getOperator(); - $column = $expression->getColumn(); - $column = $column instanceof ExpressionInterface ? $this->queryBuilder->buildExpression($column) : $column; + $operator = $expression->operator; + $column = $expression->column; + $column = $column instanceof ExpressionInterface + ? $this->queryBuilder->buildExpression($column) + : $column; if (!str_contains($column, '(')) { $column = $this->queryBuilder->getQuoter()->quoteColumnName($column); } - $phName1 = $this->createPlaceholder($expression->getIntervalStart(), $params); - $phName2 = $this->createPlaceholder($expression->getIntervalEnd(), $params); + $phName1 = $this->createPlaceholder($expression->intervalStart, $params); + $phName2 = $this->createPlaceholder($expression->intervalEnd, $params); return "$column $operator $phName1 AND $phName2"; } diff --git a/src/QueryBuilder/Condition/Builder/ExistsConditionBuilder.php b/src/QueryBuilder/Condition/Builder/ExistsConditionBuilder.php index ca1a55da5..1f52433ce 100644 --- a/src/QueryBuilder/Condition/Builder/ExistsConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/ExistsConditionBuilder.php @@ -36,9 +36,8 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $operator = $expression->getOperator(); - $query = $expression->getQuery(); - $sql = $this->queryBuilder->buildExpression($query, $params); - return "$operator $sql"; + return $expression->operator + . ' ' + . $this->queryBuilder->buildExpression($expression->query, $params); } } diff --git a/src/QueryBuilder/Condition/Builder/HashConditionBuilder.php b/src/QueryBuilder/Condition/Builder/HashConditionBuilder.php index 871edcff2..090e5723b 100644 --- a/src/QueryBuilder/Condition/Builder/HashConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/HashConditionBuilder.php @@ -42,7 +42,7 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $hash = $expression->getHash() ?? []; + $hash = $expression->hash; $parts = []; /** diff --git a/src/QueryBuilder/Condition/Builder/InConditionBuilder.php b/src/QueryBuilder/Condition/Builder/InConditionBuilder.php index ac73d45c9..37917cf26 100644 --- a/src/QueryBuilder/Condition/Builder/InConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/InConditionBuilder.php @@ -53,9 +53,9 @@ public function __construct(protected QueryBuilderInterface $queryBuilder) */ public function build(ExpressionInterface $expression, array &$params = []): string { - $column = $expression->getColumn(); - $operator = strtoupper($expression->getOperator()); - $values = $expression->getValues(); + $column = $expression->column; + $operator = strtoupper($expression->operator); + $values = $expression->values; if ($column === []) { /** no columns to test against */ @@ -146,7 +146,7 @@ public function build(ExpressionInterface $expression, array &$params = []): str protected function buildValues(InCondition $condition, iterable $values, array &$params = []): array { $sqlValues = []; - $column = $condition->getColumn(); + $column = $condition->column; if (is_array($column)) { /** @psalm-var mixed $column */ diff --git a/src/QueryBuilder/Condition/Builder/LikeConditionBuilder.php b/src/QueryBuilder/Condition/Builder/LikeConditionBuilder.php index 5d4d1efcd..ecf83f98f 100644 --- a/src/QueryBuilder/Condition/Builder/LikeConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/LikeConditionBuilder.php @@ -57,7 +57,7 @@ public function __construct( */ public function build(ExpressionInterface $expression, array &$params = []): string { - $values = $expression->getValue(); + $values = $expression->value; $escape = $expression->getEscapingReplacements(); if ($escape === []) { @@ -97,7 +97,7 @@ public function build(ExpressionInterface $expression, array &$params = []): str */ protected function prepareColumn(LikeCondition $expression, array &$params): string { - $column = $expression->getColumn(); + $column = $expression->column; if ($column instanceof ExpressionInterface) { return $this->queryBuilder->buildExpression($column, $params); @@ -143,7 +143,7 @@ protected function preparePlaceholderName( */ protected function parseOperator(LikeCondition $expression): array { - $operator = strtoupper($expression->getOperator()); + $operator = strtoupper($expression->operator); if (!preg_match('/^(AND |OR |)((NOT |)I?LIKE)/', $operator, $matches)) { throw new InvalidArgumentException("Invalid operator in like condition: \"$operator\""); } diff --git a/src/QueryBuilder/Condition/Builder/ConjunctionConditionBuilder.php b/src/QueryBuilder/Condition/Builder/LogicalConditionBuilder.php similarity index 60% rename from src/QueryBuilder/Condition/Builder/ConjunctionConditionBuilder.php rename to src/QueryBuilder/Condition/Builder/LogicalConditionBuilder.php index 2ef073a52..98dfd52c2 100644 --- a/src/QueryBuilder/Condition/Builder/ConjunctionConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/LogicalConditionBuilder.php @@ -10,7 +10,8 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\ExpressionBuilderInterface; use Yiisoft\Db\Expression\ExpressionInterface; -use Yiisoft\Db\QueryBuilder\Condition\AbstractConjunctionCondition; +use Yiisoft\Db\QueryBuilder\Condition\AndCondition; +use Yiisoft\Db\QueryBuilder\Condition\OrCondition; use Yiisoft\Db\QueryBuilder\QueryBuilderInterface; use function count; @@ -19,20 +20,21 @@ use function reset; /** - * Build an object of {@see AbstractConjunctionCondition} into SQL expressions. + * Build an object of {@see AndCondition} or {@see OrCondition} into SQL expressions. * - * @implements ExpressionBuilderInterface + * @implements ExpressionBuilderInterface */ -class ConjunctionConditionBuilder implements ExpressionBuilderInterface +final class LogicalConditionBuilder implements ExpressionBuilderInterface { - public function __construct(private readonly QueryBuilderInterface $queryBuilder) - { + public function __construct( + private readonly QueryBuilderInterface $queryBuilder + ) { } /** - * Build SQL for {@see AbstractConjunctionCondition}. + * Build SQL for {@see AndCondition} or {@see OrCondition}. * - * @param AbstractConjunctionCondition $expression + * @param AndCondition|OrCondition $expression * * @throws Exception * @throws InvalidArgumentException @@ -41,35 +43,37 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - /** @psalm-var string[] $parts */ - $parts = $this->buildExpressionsFrom($expression, $params); + $parts = $this->buildExpressions($expression->expressions, $params); if (empty($parts)) { return ''; } if (count($parts) === 1) { - return reset($parts); + return (string) reset($parts); } - return '(' . implode(") {$expression->getOperator()} (", $parts) . ')'; + $operator = match ($expression::class) { + AndCondition::class => 'AND', + OrCondition::class => 'OR', + }; + + return '(' . implode(") $operator (", $parts) . ')'; } /** - * Builds expressions, that are stored in `$condition`. - * * @throws Exception * @throws InvalidArgumentException * @throws InvalidConfigException * @throws NotSupportedException + * + * @psalm-param array $expressions + * @psalm-return list */ - private function buildExpressionsFrom(AbstractConjunctionCondition $condition, array &$params = []): array + private function buildExpressions(array $expressions, array &$params = []): array { $parts = []; - /** @psalm-var array $expressions */ - $expressions = $condition->getExpressions(); - foreach ($expressions as $conditionValue) { if (is_array($conditionValue)) { $conditionValue = $this->queryBuilder->buildCondition($conditionValue, $params); diff --git a/src/QueryBuilder/Condition/Builder/NotConditionBuilder.php b/src/QueryBuilder/Condition/Builder/NotConditionBuilder.php index 882f254eb..3922fdac4 100644 --- a/src/QueryBuilder/Condition/Builder/NotConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/NotConditionBuilder.php @@ -36,7 +36,7 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $operand = $expression->getCondition(); + $operand = $expression->condition; if ($operand === '') { return ''; diff --git a/src/QueryBuilder/Condition/Builder/SimpleConditionBuilder.php b/src/QueryBuilder/Condition/Builder/SimpleConditionBuilder.php index 343a82363..5ba3ab0e5 100644 --- a/src/QueryBuilder/Condition/Builder/SimpleConditionBuilder.php +++ b/src/QueryBuilder/Condition/Builder/SimpleConditionBuilder.php @@ -38,10 +38,9 @@ public function __construct(private readonly QueryBuilderInterface $queryBuilder */ public function build(ExpressionInterface $expression, array &$params = []): string { - $operator = $expression->getOperator(); - $column = $expression->getColumn(); - /** @psalm-var mixed $value */ - $value = $expression->getValue(); + $operator = $expression->operator; + $column = $expression->column; + $value = $expression->value; if ($column instanceof ExpressionInterface) { $column = $this->queryBuilder->buildExpression($column, $params); diff --git a/src/QueryBuilder/Condition/ExistsCondition.php b/src/QueryBuilder/Condition/ExistsCondition.php index 3554d34fc..e415f3c73 100644 --- a/src/QueryBuilder/Condition/ExistsCondition.php +++ b/src/QueryBuilder/Condition/ExistsCondition.php @@ -12,24 +12,14 @@ */ final class ExistsCondition implements ConditionInterface { - public function __construct(private string $operator, private QueryInterface $query) - { - } - /** - * @return string The operator to use (for example, `EXISTS` or `NOT EXISTS`). + * @param string $operator The operator to use (for example, `EXISTS` or `NOT EXISTS`). + * @param QueryInterface $query The {@see QueryInterfacee} implementation representing the sub-query. */ - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return QueryInterface The {@see Query} object representing the sub-query. - */ - public function getQuery(): QueryInterface - { - return $this->query; + public function __construct( + public readonly string $operator, + public readonly QueryInterface $query, + ) { } /** diff --git a/src/QueryBuilder/Condition/HashCondition.php b/src/QueryBuilder/Condition/HashCondition.php index a6c56999f..a7cad2251 100644 --- a/src/QueryBuilder/Condition/HashCondition.php +++ b/src/QueryBuilder/Condition/HashCondition.php @@ -9,16 +9,12 @@ */ final class HashCondition implements ConditionInterface { - public function __construct(private array|null $hash = []) - { - } - /** - * @return array|null The condition specification. + * @param array $hash The condition specification. */ - public function getHash(): array|null - { - return $this->hash; + public function __construct( + public readonly array $hash = [], + ) { } /** diff --git a/src/QueryBuilder/Condition/InCondition.php b/src/QueryBuilder/Condition/InCondition.php index cc50f9759..561d4df87 100644 --- a/src/QueryBuilder/Condition/InCondition.php +++ b/src/QueryBuilder/Condition/InCondition.php @@ -14,39 +14,19 @@ */ final class InCondition implements ConditionInterface { - public function __construct( - private array|string|Iterator|ExpressionInterface $column, - private string $operator, - private int|iterable|Iterator|QueryInterface $values - ) { - } - /** - * @return array|ExpressionInterface|Iterator|string The column name. If it's an array, a composite `IN` condition + * @param array|ExpressionInterface|Iterator|string $column The column name. If it's an array, a composite `IN` condition * will be generated. - */ - public function getColumn(): array|string|ExpressionInterface|Iterator - { - return $this->column; - } - - /** - * @return string The operator to use (for example, `IN` or `NOT IN`). - */ - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return int|iterable|Iterator|QueryInterface An array of values that {@see columns} value should be among. - * - * If it's an empty array, the generated expression will be a `false` value if {@see operator} is `IN` and empty if + * @param string $operator The operator to use (for example, `IN` or `NOT IN`). + * @param int|iterable|Iterator|QueryInterface $values An array of values that {@see $columns} value should be among. + * If it's an empty array, the generated expression will be a `false` value if {@see $operator} is `IN` and empty if * operator is `NOT IN`. */ - public function getValues(): int|iterable|Iterator|QueryInterface - { - return $this->values; + public function __construct( + public readonly array|string|Iterator|ExpressionInterface $column, + public readonly string $operator, + public readonly int|iterable|Iterator|QueryInterface $values + ) { } /** diff --git a/src/QueryBuilder/Condition/LikeCondition.php b/src/QueryBuilder/Condition/LikeCondition.php index e9c5ea393..298a5d467 100644 --- a/src/QueryBuilder/Condition/LikeCondition.php +++ b/src/QueryBuilder/Condition/LikeCondition.php @@ -20,20 +20,19 @@ final class LikeCondition implements ConditionInterface { protected array|null $escapingReplacements = []; - public function __construct( - private readonly string|ExpressionInterface $column, - private readonly string $operator, - private readonly array|int|string|Iterator|ExpressionInterface|null $value, - private readonly ?bool $caseSensitive = null, - ) { - } - /** - * @return ExpressionInterface|string The column name. + * @param ExpressionInterface|string $column The column name. + * @param string $operator The operator to use such as `>` or `<=`. + * @param array|ExpressionInterface|int|Iterator|string|null $value The value to the right of {@see operator}. + * @param bool|null $caseSensitive Whether the comparison is case-sensitive. `null` means using the default + * behavior. */ - public function getColumn(): string|ExpressionInterface - { - return $this->column; + public function __construct( + public readonly string|ExpressionInterface $column, + public readonly string $operator, + public readonly array|int|string|Iterator|ExpressionInterface|null $value, + public readonly ?bool $caseSensitive = null, + ) { } /** @@ -44,30 +43,6 @@ public function getEscapingReplacements(): ?array return $this->escapingReplacements; } - /** - * @return string The operator to use such as `>` or `<=`. - */ - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return array|ExpressionInterface|int|Iterator|string|null The value to the right of {@see operator}. - */ - public function getValue(): array|int|string|Iterator|ExpressionInterface|null - { - return $this->value; - } - - /** - * @return bool|null Whether the comparison is case-sensitive. `null` means using the default behavior. - */ - public function getCaseSensitive(): ?bool - { - return $this->caseSensitive; - } - /** * This method allows specifying how to escape special characters in the value(s). * diff --git a/src/QueryBuilder/Condition/NotCondition.php b/src/QueryBuilder/Condition/NotCondition.php index e8114d48d..f96ba198f 100644 --- a/src/QueryBuilder/Condition/NotCondition.php +++ b/src/QueryBuilder/Condition/NotCondition.php @@ -17,16 +17,12 @@ */ final class NotCondition implements ConditionInterface { - public function __construct(private ExpressionInterface|array|null|string $condition) - { - } - /** - * @return array|ExpressionInterface|string|null the condition to negate. + * @param array|ExpressionInterface|string|null $condition The condition to negate. */ - public function getCondition(): ExpressionInterface|array|null|string - { - return $this->condition; + public function __construct( + public readonly ExpressionInterface|array|null|string $condition, + ) { } /** diff --git a/src/QueryBuilder/Condition/OrCondition.php b/src/QueryBuilder/Condition/OrCondition.php index 6cb829f57..0bf8bb606 100644 --- a/src/QueryBuilder/Condition/OrCondition.php +++ b/src/QueryBuilder/Condition/OrCondition.php @@ -4,16 +4,26 @@ namespace Yiisoft\Db\QueryBuilder\Condition; +use Yiisoft\Db\Expression\ExpressionInterface; + /** * Condition that connects two or more SQL expressions with the `AND` operator. */ -final class OrCondition extends AbstractConjunctionCondition +final class OrCondition implements ConditionInterface { /** - * @return string The operator that's represented by this condition class, such as `AND`, `OR`. + * @param array $expressions The expressions that are connected by this condition. + * + * @psalm-param array $expressions */ - public function getOperator(): string + public function __construct( + public readonly array $expressions, + ) { + } + + public static function fromArrayDefinition(string $operator, array $operands): self { - return 'OR'; + /** @psalm-var array $operands */ + return new self($operands); } } diff --git a/src/QueryBuilder/Condition/SimpleCondition.php b/src/QueryBuilder/Condition/SimpleCondition.php index 04a5cb1d6..4c54d0cc1 100644 --- a/src/QueryBuilder/Condition/SimpleCondition.php +++ b/src/QueryBuilder/Condition/SimpleCondition.php @@ -14,35 +14,16 @@ */ final class SimpleCondition implements ConditionInterface { - public function __construct( - private string|ExpressionInterface $column, - private string $operator, - private mixed $value - ) { - } - - /** - * @return ExpressionInterface|string The column name or an Expression. - */ - public function getColumn(): string|ExpressionInterface - { - return $this->column; - } - /** - * @return string The operator to use such as `>` or `<=`. + * @param ExpressionInterface|string $column The column name or an expression. + * @param string $operator The operator to use such as `>` or `<=`. + * @param mixed $value The value to the right of {@see $operator}. */ - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return mixed The value to the right of {@see operator}. - */ - public function getValue(): mixed - { - return $this->value; + public function __construct( + public readonly string|ExpressionInterface $column, + public readonly string $operator, + public readonly mixed $value + ) { } /** diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index bf0904e66..101b93551 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -22,8 +22,10 @@ use Yiisoft\Db\Expression\ExpressionInterface; use Yiisoft\Db\Query\Query; use Yiisoft\Db\Query\QueryInterface; +use Yiisoft\Db\QueryBuilder\Condition\AndCondition; use Yiisoft\Db\QueryBuilder\Condition\ArrayOverlapsCondition; use Yiisoft\Db\QueryBuilder\Condition\JsonOverlapsCondition; +use Yiisoft\Db\QueryBuilder\Condition\OrCondition; use Yiisoft\Db\QueryBuilder\Condition\SimpleCondition; use Yiisoft\Db\Schema\Column\ColumnInterface; use Yiisoft\Db\Schema\QuoterInterface; @@ -1566,52 +1568,41 @@ public function testBuildWithWhereExistsWithParameters(): void $this->assertSame([':some_value' => 'asd', ':merchant_id' => 6], $params); } - /** - * @throws InvalidArgumentException - */ public function testsCreateConditionFromArray(): void { - $db = $this->getConnection(); - - $qb = $db->getQueryBuilder(); + $qb = $this->getConnection()->getQueryBuilder(); $condition = $qb->createConditionFromArray(['and', 'a = 1', 'b = 2']); - - $this->assertSame('AND', $condition->getOperator()); - $this->assertSame(['a = 1', 'b = 2'], $condition->getExpressions()); + $this->assertInstanceOf(AndCondition::class, $condition); + $this->assertSame(['a = 1', 'b = 2'], $condition->expressions); $condition = $qb->createConditionFromArray(['or', 'a = 1', 'b = 2']); - - $this->assertSame('OR', $condition->getOperator()); - $this->assertSame(['a = 1', 'b = 2'], $condition->getExpressions()); + $this->assertInstanceOf(OrCondition::class, $condition); + $this->assertSame(['a = 1', 'b = 2'], $condition->expressions); $condition = $qb->createConditionFromArray(['and', 'a = 1', ['or', 'b = 2', 'c = 3']]); - - $this->assertSame('AND', $condition->getOperator()); - $this->assertSame(['a = 1', ['or', 'b = 2', 'c = 3']], $condition->getExpressions()); + $this->assertInstanceOf(AndCondition::class, $condition); + $this->assertSame(['a = 1', ['or', 'b = 2', 'c = 3']], $condition->expressions); $condition = $qb->createConditionFromArray(['or', 'a = 1', ['and', 'b = 2', 'c = 3']]); - - $this->assertSame('OR', $condition->getOperator()); - $this->assertSame(['a = 1', ['and', 'b = 2', 'c = 3']], $condition->getExpressions()); + $this->assertInstanceOf(OrCondition::class, $condition); + $this->assertSame(['a = 1', ['and', 'b = 2', 'c = 3']], $condition->expressions); $condition = $qb->createConditionFromArray(['and', 'a = 1', ['or', 'b = 2', ['and', 'c = 3', 'd = 4']]]); - - $this->assertSame('AND', $condition->getOperator()); - $this->assertSame(['a = 1', ['or', 'b = 2', ['and', 'c = 3', 'd = 4']]], $condition->getExpressions()); + $this->assertInstanceOf(AndCondition::class, $condition); + $this->assertSame(['a = 1', ['or', 'b = 2', ['and', 'c = 3', 'd = 4']]], $condition->expressions); $condition = $qb->createConditionFromArray(['or', 'a = 1', ['and', 'b = 2', ['or', 'c = 3', 'd = 4']]]); - - $this->assertSame('OR', $condition->getOperator()); - $this->assertSame(['a = 1', ['and', 'b = 2', ['or', 'c = 3', 'd = 4']]], $condition->getExpressions()); + $this->assertInstanceOf(OrCondition::class, $condition); + $this->assertSame(['a = 1', ['and', 'b = 2', ['or', 'c = 3', 'd = 4']]], $condition->expressions); $condition = $qb->createConditionFromArray( ['and', 'a = 1', ['or', 'b = 2', ['and', 'c = 3', ['or', 'd = 4', 'e = 5']]]] ); - $this->assertSame('AND', $condition->getOperator()); + $this->assertInstanceOf(AndCondition::class, $condition); $this->assertSame( ['a = 1', ['or', 'b = 2', ['and', 'c = 3', ['or', 'd = 4', 'e = 5']]]], - $condition->getExpressions(), + $condition->expressions, ); } @@ -1623,14 +1614,14 @@ public function testCreateOverlapsConditionFromArray(): void $condition = $qb->createConditionFromArray(['array overlaps', 'column', [1, 2, 3]]); $this->assertInstanceOf(ArrayOverlapsCondition::class, $condition); - $this->assertSame('column', $condition->getColumn()); - $this->assertSame([1, 2, 3], $condition->getValues()); + $this->assertSame('column', $condition->column); + $this->assertSame([1, 2, 3], $condition->values); $condition = $qb->createConditionFromArray(['json overlaps', 'column', [1, 2, 3]]); $this->assertInstanceOf(JsonOverlapsCondition::class, $condition); - $this->assertSame('column', $condition->getColumn()); - $this->assertSame([1, 2, 3], $condition->getValues()); + $this->assertSame('column', $condition->column); + $this->assertSame([1, 2, 3], $condition->values); } public function testCreateOverlapsConditionFromArrayWithInvalidOperandsCount(): void diff --git a/tests/Db/QueryBuilder/Condition/AndConditionTest.php b/tests/Db/QueryBuilder/Condition/AndConditionTest.php index 19b22d6bd..b4f825264 100644 --- a/tests/Db/QueryBuilder/Condition/AndConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/AndConditionTest.php @@ -18,13 +18,6 @@ public function testConstructor(): void { $andCondition = new AndCondition(['a' => 1, 'b' => 2]); - $this->assertSame(['a' => 1, 'b' => 2], $andCondition->getExpressions()); - } - - public function testGetOperator(): void - { - $andCondition = new AndCondition(['a' => 1, 'b' => 2]); - - $this->assertSame('AND', $andCondition->getOperator()); + $this->assertSame(['a' => 1, 'b' => 2], $andCondition->expressions); } } diff --git a/tests/Db/QueryBuilder/Condition/BetweenColumnsConditionTest.php b/tests/Db/QueryBuilder/Condition/BetweenColumnsConditionTest.php index f55734d61..51972321b 100644 --- a/tests/Db/QueryBuilder/Condition/BetweenColumnsConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/BetweenColumnsConditionTest.php @@ -19,10 +19,10 @@ public function testConstructor(): void { $betweenColumnsCondition = new BetweenColumnsCondition(42, 'BETWEEN', 'min_value', 'max_value'); - $this->assertSame(42, $betweenColumnsCondition->getValue()); - $this->assertSame('BETWEEN', $betweenColumnsCondition->getOperator()); - $this->assertSame('min_value', $betweenColumnsCondition->getIntervalStartColumn()); - $this->assertSame('max_value', $betweenColumnsCondition->getIntervalEndColumn()); + $this->assertSame(42, $betweenColumnsCondition->value); + $this->assertSame('BETWEEN', $betweenColumnsCondition->operator); + $this->assertSame('min_value', $betweenColumnsCondition->intervalStartColumn); + $this->assertSame('max_value', $betweenColumnsCondition->intervalEndColumn); } public function testFromArrayDefinition(): void @@ -32,10 +32,10 @@ public function testFromArrayDefinition(): void [42, 'min_value', 'max_value'] ); - $this->assertSame(42, $betweenColumnsCondition->getValue()); - $this->assertSame('BETWEEN', $betweenColumnsCondition->getOperator()); - $this->assertSame('min_value', $betweenColumnsCondition->getIntervalStartColumn()); - $this->assertSame('max_value', $betweenColumnsCondition->getIntervalEndColumn()); + $this->assertSame(42, $betweenColumnsCondition->value); + $this->assertSame('BETWEEN', $betweenColumnsCondition->operator); + $this->assertSame('min_value', $betweenColumnsCondition->intervalStartColumn); + $this->assertSame('max_value', $betweenColumnsCondition->intervalEndColumn); } public function testFromArrayDefinitionExceptionWithoutOperands(): void diff --git a/tests/Db/QueryBuilder/Condition/BetweenConditionTest.php b/tests/Db/QueryBuilder/Condition/BetweenConditionTest.php index 65b011590..8e62c01c7 100644 --- a/tests/Db/QueryBuilder/Condition/BetweenConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/BetweenConditionTest.php @@ -19,20 +19,20 @@ public function testConstructor(): void { $betweenCondition = new BetweenCondition('date', 'BETWEEN', 1, 2); - $this->assertSame('date', $betweenCondition->getColumn()); - $this->assertSame('BETWEEN', $betweenCondition->getOperator()); - $this->assertSame(1, $betweenCondition->getIntervalStart()); - $this->assertSame(2, $betweenCondition->getIntervalEnd()); + $this->assertSame('date', $betweenCondition->column); + $this->assertSame('BETWEEN', $betweenCondition->operator); + $this->assertSame(1, $betweenCondition->intervalStart); + $this->assertSame(2, $betweenCondition->intervalEnd); } public function testFromArrayDefinition(): void { $betweenCondition = BetweenCondition::fromArrayDefinition('BETWEEN', ['date', 1, 2]); - $this->assertSame('date', $betweenCondition->getColumn()); - $this->assertSame('BETWEEN', $betweenCondition->getOperator()); - $this->assertSame(1, $betweenCondition->getIntervalStart()); - $this->assertSame(2, $betweenCondition->getIntervalEnd()); + $this->assertSame('date', $betweenCondition->column); + $this->assertSame('BETWEEN', $betweenCondition->operator); + $this->assertSame(1, $betweenCondition->intervalStart); + $this->assertSame(2, $betweenCondition->intervalEnd); } public function testFromArrayDefinitionExceptionWithoutOperands(): void diff --git a/tests/Db/QueryBuilder/Condition/ExistsConditionTest.php b/tests/Db/QueryBuilder/Condition/ExistsConditionTest.php index cafc3f91b..6087c0c92 100644 --- a/tests/Db/QueryBuilder/Condition/ExistsConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/ExistsConditionTest.php @@ -25,8 +25,8 @@ public function testConstructor(): void ->where(['active' => 1]); $existCondition = new ExistsCondition('EXISTS', $query); - $this->assertSame('EXISTS', $existCondition->getOperator()); - $this->assertSame($query, $existCondition->getQuery()); + $this->assertSame('EXISTS', $existCondition->operator); + $this->assertSame($query, $existCondition->query); } public function testFromArrayDefinition(): void @@ -37,8 +37,8 @@ public function testFromArrayDefinition(): void ->where(['active' => 1]); $existCondition = ExistsCondition::fromArrayDefinition('EXISTS', [$query]); - $this->assertSame('EXISTS', $existCondition->getOperator()); - $this->assertSame($query, $existCondition->getQuery()); + $this->assertSame('EXISTS', $existCondition->operator); + $this->assertSame($query, $existCondition->query); } public function testFromArrayDefinitionExceptionQuery(): void diff --git a/tests/Db/QueryBuilder/Condition/HashConditionTest.php b/tests/Db/QueryBuilder/Condition/HashConditionTest.php index 5a8936f66..0c2a6447a 100644 --- a/tests/Db/QueryBuilder/Condition/HashConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/HashConditionTest.php @@ -18,13 +18,13 @@ public function testConstructor(): void { $hashCondition = new HashCondition(['expired' => false, 'active' => true]); - $this->assertSame(['expired' => false, 'active' => true], $hashCondition->getHash()); + $this->assertSame(['expired' => false, 'active' => true], $hashCondition->hash); } public function testFromArrayDefinition(): void { $hashCondition = HashCondition::fromArrayDefinition('AND', ['expired' => false, 'active' => true]); - $this->assertSame(['expired' => false, 'active' => true], $hashCondition->getHash()); + $this->assertSame(['expired' => false, 'active' => true], $hashCondition->hash); } } diff --git a/tests/Db/QueryBuilder/Condition/InConditionTest.php b/tests/Db/QueryBuilder/Condition/InConditionTest.php index 9f6dcb423..8e2c9541a 100644 --- a/tests/Db/QueryBuilder/Condition/InConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/InConditionTest.php @@ -19,18 +19,18 @@ public function testConstructor(): void { $inCondition = new InCondition('id', 'IN', [1, 2, 3]); - $this->assertSame('id', $inCondition->getColumn()); - $this->assertSame('IN', $inCondition->getOperator()); - $this->assertSame([1, 2, 3], $inCondition->getValues()); + $this->assertSame('id', $inCondition->column); + $this->assertSame('IN', $inCondition->operator); + $this->assertSame([1, 2, 3], $inCondition->values); } public function testFromArrayDefinition(): void { $inCondition = InCondition::fromArrayDefinition('IN', ['id', [1, 2, 3]]); - $this->assertSame('id', $inCondition->getColumn()); - $this->assertSame('IN', $inCondition->getOperator()); - $this->assertSame([1, 2, 3], $inCondition->getValues()); + $this->assertSame('id', $inCondition->column); + $this->assertSame('IN', $inCondition->operator); + $this->assertSame([1, 2, 3], $inCondition->values); } public function testFromArrayDefinitionException(): void diff --git a/tests/Db/QueryBuilder/Condition/LikeConditionTest.php b/tests/Db/QueryBuilder/Condition/LikeConditionTest.php index 484bbf028..f3fc63974 100644 --- a/tests/Db/QueryBuilder/Condition/LikeConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/LikeConditionTest.php @@ -18,19 +18,20 @@ public function testConstructor(): void { $likeCondition = new LikeCondition('id', 'LIKE', 'test'); - $this->assertSame('id', $likeCondition->getColumn()); - $this->assertSame('LIKE', $likeCondition->getOperator()); - $this->assertSame('test', $likeCondition->getValue()); - $this->assertNull($likeCondition->getCaseSensitive()); + $this->assertSame('id', $likeCondition->column); + $this->assertSame('LIKE', $likeCondition->operator); + $this->assertSame('test', $likeCondition->value); + $this->assertNull($likeCondition->caseSensitive); } public function testFromArrayDefinition(): void { $likeCondition = LikeCondition::fromArrayDefinition('LIKE', ['id', 'test']); - $this->assertSame('id', $likeCondition->getColumn()); - $this->assertSame('LIKE', $likeCondition->getOperator()); - $this->assertSame('test', $likeCondition->getValue()); + $this->assertSame('id', $likeCondition->column); + $this->assertSame('LIKE', $likeCondition->operator); + $this->assertSame('test', $likeCondition->value); + $this->assertNull($likeCondition->caseSensitive); } public function testFromArrayDefinitionException(): void @@ -63,9 +64,9 @@ public function testFromArrayDefinitionSetEscapingReplacements(): void { $likeCondition = LikeCondition::fromArrayDefinition('LIKE', ['id', 'test', ['%' => '\%', '_' => '\_']]); - $this->assertSame('id', $likeCondition->getColumn()); - $this->assertSame('LIKE', $likeCondition->getOperator()); - $this->assertSame('test', $likeCondition->getValue()); + $this->assertSame('id', $likeCondition->column); + $this->assertSame('LIKE', $likeCondition->operator); + $this->assertSame('test', $likeCondition->value); $this->assertSame(['%' => '\%', '_' => '\_'], $likeCondition->getEscapingReplacements()); } @@ -84,9 +85,9 @@ public function testFromArrayDefinitionCaseSensitive(?bool $caseSensitive): void { $likeCondition = LikeCondition::fromArrayDefinition('LIKE', ['id', 'test', 'caseSensitive' => $caseSensitive]); - $this->assertSame('id', $likeCondition->getColumn()); - $this->assertSame('LIKE', $likeCondition->getOperator()); - $this->assertSame('test', $likeCondition->getValue()); - $this->assertSame($caseSensitive, $likeCondition->getCaseSensitive()); + $this->assertSame('id', $likeCondition->column); + $this->assertSame('LIKE', $likeCondition->operator); + $this->assertSame('test', $likeCondition->value); + $this->assertSame($caseSensitive, $likeCondition->caseSensitive); } } diff --git a/tests/Db/QueryBuilder/Condition/NotConditionTest.php b/tests/Db/QueryBuilder/Condition/NotConditionTest.php index d2fcaf267..40da90175 100644 --- a/tests/Db/QueryBuilder/Condition/NotConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/NotConditionTest.php @@ -19,14 +19,14 @@ public function testConstructor(): void { $notCondition = new NotCondition('id = 1'); - $this->assertSame('id = 1', $notCondition->getCondition()); + $this->assertSame('id = 1', $notCondition->condition); } public function testFromArrayDefinition(): void { $notCondition = NotCondition::fromArrayDefinition('NOT', ['id = 1']); - $this->assertSame('id = 1', $notCondition->getCondition()); + $this->assertSame('id = 1', $notCondition->condition); } public function testFromArrayDefinitionException(): void diff --git a/tests/Db/QueryBuilder/Condition/SimpleConditionTest.php b/tests/Db/QueryBuilder/Condition/SimpleConditionTest.php index 581c80632..fa5e5990e 100644 --- a/tests/Db/QueryBuilder/Condition/SimpleConditionTest.php +++ b/tests/Db/QueryBuilder/Condition/SimpleConditionTest.php @@ -19,18 +19,18 @@ public function testConstructor(): void { $simpleCondition = new SimpleCondition('id', '=', 1); - $this->assertSame('id', $simpleCondition->getColumn()); - $this->assertSame('=', $simpleCondition->getOperator()); - $this->assertSame(1, $simpleCondition->getValue()); + $this->assertSame('id', $simpleCondition->column); + $this->assertSame('=', $simpleCondition->operator); + $this->assertSame(1, $simpleCondition->value); } public function testFromArrayDefinition(): void { $simpleCondition = SimpleCondition::fromArrayDefinition('=', ['id', 1]); - $this->assertSame('id', $simpleCondition->getColumn()); - $this->assertSame('=', $simpleCondition->getOperator()); - $this->assertSame(1, $simpleCondition->getValue()); + $this->assertSame('id', $simpleCondition->column); + $this->assertSame('=', $simpleCondition->operator); + $this->assertSame(1, $simpleCondition->value); } public function testFromArrayDefinitionColumnException(): void @@ -63,11 +63,11 @@ public function testNullSecondOperand(): void { $condition = SimpleCondition::fromArrayDefinition('=', ['id', null]); - $this->assertNull($condition->getValue()); + $this->assertNull($condition->value); $condition2 = new SimpleCondition('name', 'IS NOT', null); - $this->assertSame('IS NOT', $condition2->getOperator()); - $this->assertNull($condition2->getValue()); + $this->assertSame('IS NOT', $condition2->operator); + $this->assertNull($condition2->value); } }