switch complex expr

This commit is contained in:
Yuri Kuznetsov
2023-03-07 18:52:49 +02:00
parent 2d62c902cb
commit 369f3ba9a5
4 changed files with 66 additions and 0 deletions
@@ -186,6 +186,21 @@ class Expression implements WhereItem
return self::composeFunction('IF', $condition, $then, $else);
}
/**
* 'CASE' expression. Even arguments define 'WHEN' conditions, following odd arguments
* define 'THEN' values. The last unmatched argument defines 'ELSE'.
*
* @param Expression|scalar|null ...$arguments Arguments.
*/
public static function switch(Expression|string|int|float|bool|null ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments.");
}
return self::composeFunction('SWITCH', ...$arguments);
}
/**
* 'IFNULL' function. If the first argument is not NULL, returns it,
* otherwise returns the second argument.
@@ -950,6 +950,28 @@ abstract class BaseQueryComposer implements QueryComposer
}
switch ($function) {
case 'SWITCH':
if (count($argumentPartList) < 2) {
throw new RuntimeException("Not enough arguments for SWITCH function.");
}
$part = "CASE";
for ($i = 0; $i < floor(count($argumentPartList) / 2); $i++) {
$whenPart = $argumentPartList[$i * 2];
$thenPart = $argumentPartList[$i * 2 + 1];
$part .= " WHEN {$whenPart} THEN {$thenPart}";
}
if (count($argumentPartList) % 2) {
$part .= " ELSE " . end($argumentPartList);
}
$part .= " END";
return $part;
case 'MONTH':
return "DATE_FORMAT({$part}, '%Y-%m')";
@@ -122,6 +122,7 @@ class Functions
'NOT_IN',
'IFNULL',
'NULLIF',
'SWITCH',
'BINARY',
'MD5',
'UNIX_TIMESTAMP',
@@ -2888,4 +2888,32 @@ class MysqlQueryComposerTest extends \PHPUnit\Framework\TestCase
$this->query->composeSelect($query)
);
}
public function testSwitch1(): void
{
$sql = "SELECT CASE WHEN 1 THEN '1' WHEN 0 THEN '0' ELSE NULL END AS `value`";
$query = SelectBuilder::create()
->select('SWITCH:(1, "1", 0, "0", null)', 'value')
->build();
$this->assertEquals(
$sql,
$this->query->composeSelect($query)
);
}
public function testSwitch2(): void
{
$sql = "SELECT CASE WHEN 1 THEN '1' WHEN 0 THEN '0' END AS `value`";
$query = SelectBuilder::create()
->select('SWITCH:(1, "1", 0, "0")', 'value')
->build();
$this->assertEquals(
$sql,
$this->query->composeSelect($query)
);
}
}