Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
- New #984: Add `createQuery()` and `select()` methods to `ConnectionInterface` (@Tigrov)
- Chg #985: Rename `insertWithReturningPks()` to `insertReturningPks()` in `CommandInterface` and `DMLQueryBuilderInterface` (@Tigrov)
- Enh #992: Add optional type casting to `DataReaderInterface` using columns (@Tigrov)
- New #988: Add `CaseExpression` and `CaseExpressionBuilder` to build `CASE-WHEN-THEN-ELSE` SQL expressions (@Tigrov)
- New #988, #1053: Add `CaseExpression` and `CaseExpressionBuilder` to build `CASE-WHEN-THEN-ELSE` SQL expressions (@Tigrov)
- Enh #991: Improve types in `ConnectionInterface::transaction()` (@kikara)
- Chg #998: Add `yiisoft/db-implementation` virtual package as dependency (@vjik)
- Chg #999: Remove `requireTransaction()` method and `$isolationLevel` property from `AbstractCommand` (@vjik)
Expand Down
1 change: 1 addition & 0 deletions docs/guide/en/expressions/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ of the `Yiisoft\Db\Query\QueryInterface` and the `insert()`, `update()`, `upsert
## Available expressions
- [Expression](expression.md) that does not require escaping or quoting of its content;
- [Function expressions](functions.md) `ArrayMerge`, `Greatest`, `Least`, `Length`, `Longest`, `Shortest`;
- [Statement expressions](statements.md) `CaseX`;
4 changes: 2 additions & 2 deletions docs/guide/en/expressions/functions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Function expressions
# Function Expressions

The library provides several classes to represent SQL functions as expressions.

> [!WARNING]
> The functions do not quote string values or column names, use [Value](../../../../src/Expression/Value/Value.php)
> expression for string values and [ColumnName](../../../../src/Expression/Value/ColumnName.php) expression for column names
> object for string values and [ColumnName](../../../../src/Expression/Value/ColumnName.php) object for column names
> or quote the values directly.
>
> For example, `new Longest(new Value('short'), new ColumnName('column'), "'longest'")`
Expand Down
25 changes: 25 additions & 0 deletions docs/guide/en/expressions/statements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Statement Expressions

The library provides classes to represent SQL statements as expressions.

> [!WARNING]
> The statements do not quote string values or column names, use [Value](../../../../src/Expression/Value/Value.php)
> object for string values and [ColumnName](../../../../src/Expression/Value/ColumnName.php) object for column names
> or quote the values directly.

The following expression classes are available:

- [CaseX](#casex)

## CaseX

The [CaseX](../../../../src/Expression/Statement/CaseX.php) expression allows you to create SQL `CASE` statements.

```php
$case = new CaseX(
new Column('status'),
when1: new Wnen(new Value('active'), new Value('Active User')),
when2: new Wnen("'inactive'", "'Inactive User'"),
else: new Value('Unknown Status'),
);
```
6 changes: 3 additions & 3 deletions docs/guide/en/query/where.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ Operand 1 should be the column name, and operand 2 and 3 should be the starting

For example, `['between', 'id', 1,10]` will generate `id BETWEEN 1 AND 10`.

You can also use `Yiisoft\Db\Expression\ColumnName` and `Yiisoft\Db\Expression\Value` expressions:
You can also use `Yiisoft\Db\Expression\Value\ColumnName` and `Yiisoft\Db\Expression\Value\Value` expressions:

```php
use Yiisoft\Db\Expression\ColumnName;
use Yiisoft\Db\Expression\Value;
use Yiisoft\Db\Expression\Value\ColumnName;
use Yiisoft\Db\Expression\Value\Value;

['between', new Value('2025-08-11'), new ColumnName('start_date'), new ColumnName('end_date')]
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,49 @@

namespace Yiisoft\Db\Expression\Statement\Builder;

use InvalidArgumentException;
use Yiisoft\Db\Constant\GettypeResult;
use Yiisoft\Db\Expression\ExpressionBuilderInterface;
use Yiisoft\Db\Expression\Statement\CaseExpression;
use Yiisoft\Db\Expression\Statement\CaseX;
use Yiisoft\Db\Expression\ExpressionInterface;
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;

use function gettype;
use function is_string;

/**
* Builds expressions for {@see CaseExpression}.
* Builds expressions for {@see CaseX}.
*
* @implements ExpressionBuilderInterface<CaseExpression>
* @implements ExpressionBuilderInterface<CaseX>
*/
class CaseExpressionBuilder implements ExpressionBuilderInterface
class CaseXBuilder implements ExpressionBuilderInterface
{
public function __construct(protected readonly QueryBuilderInterface $queryBuilder)
{
}

/**
* Builds an SQL CASE expression from the given {@see CaseExpression} object.
* Builds an SQL `CASE` expression from the given {@see CaseX} object.
*
* @param CaseExpression $expression The CASE expression to build.
* @param CaseX $expression The `CASE` expression to build.
* @param array $params The parameters to be bound to the query.
*
* @return string SQL CASE expression.
* @return string SQL `CASE` expression.
*/
public function build(ExpressionInterface $expression, array &$params = []): string
{
$whenClauses = $expression->getWhen();

if (empty($whenClauses)) {
throw new InvalidArgumentException('The CASE expression must have at least one WHEN clause.');
}

$sql = 'CASE';

$case = $expression->getCase();

if ($case !== null) {
$sql .= ' ' . $this->buildCondition($case, $params);
if ($expression->value !== null) {
$sql .= ' ' . $this->buildCondition($expression->value, $params);
}

foreach ($whenClauses as $when) {
foreach ($expression->when as $when) {
$sql .= ' WHEN ' . $this->buildCondition($when->condition, $params);
$sql .= ' THEN ' . $this->buildResult($when->result, $params);
}

if ($expression->hasElse()) {
$sql .= ' ELSE ' . $this->buildResult($expression->getElse(), $params);
$sql .= ' ELSE ' . $this->buildResult($expression->else, $params);
}

return $sql . ' END';
Expand All @@ -80,7 +71,7 @@ protected function buildCondition(mixed $condition, array &$params): string
}

/**
* Builds the result part of the CASE expression based on its type.
* Builds the result part of the `CASE` expression based on its type.
*
* @return string The SQL result string.
*/
Expand Down
208 changes: 0 additions & 208 deletions src/Expression/Statement/CaseExpression.php

This file was deleted.

Loading