diff --git a/src/Partial/CaseStatement.php b/src/Partial/CaseStatement.php new file mode 100644 index 0000000..499f5a7 --- /dev/null +++ b/src/Partial/CaseStatement.php @@ -0,0 +1,59 @@ +expression = new Expression('CASE'); + + if ($expression) { + $this->expression = $this->expression->append('%s', $expression); + } + } + + public function when(StatementInterface $when, StatementInterface $then): self + { + $this->expression = $this->expression->append('WHEN %s THEN %s', $when, $then); + + return $this; + } + + public function else(StatementInterface $else): self + { + $this->else = new Expression('ELSE %s', $else); + + return $this; + } + + public function sql(EngineInterface $engine): string + { + return $this->buildCaseStatement()->append('END')->sql($engine); + } + + public function params(EngineInterface $engine): array + { + return $this->buildCaseStatement()->params($engine); + } + + private function buildCaseStatement(): ExpressionInterface + { + $expression = $this->expression; + + if ($this->else) { + $expression = $expression->append('%s', $this->else); + } + + return $expression; + } +} diff --git a/src/functions.php b/src/functions.php index a6c5c3c..c710a96 100644 --- a/src/functions.php +++ b/src/functions.php @@ -4,6 +4,8 @@ namespace Latitude\QueryBuilder; +use Latitude\QueryBuilder\Partial\CaseStatement; +use Latitude\QueryBuilder\Partial\Criteria; use Latitude\QueryBuilder\Partial\Parameter; use function array_map; @@ -56,7 +58,7 @@ function on(string $left, string $right): CriteriaInterface */ function order($column, ?string $direction = null): StatementInterface { - if (! $direction) { + if (!$direction) { return identify($column); } @@ -152,3 +154,8 @@ function listing(array $values, string $separator = ', '): Partial\Listing { return new Partial\Listing($separator, ...paramAll($values)); } + +function caseStatement(?StatementInterface $expression = null): CaseStatement +{ + return new Partial\CaseStatement($expression); +} diff --git a/tests/Partial/CaseStatementTest.php b/tests/Partial/CaseStatementTest.php new file mode 100644 index 0000000..e062ed4 --- /dev/null +++ b/tests/Partial/CaseStatementTest.php @@ -0,0 +1,60 @@ +when( + $field->eq('admin'), + literal(1), + ) + ->when( + $field->eq('editor'), + literal(2), + ) + ->when( + $field->eq('user'), + param(3), + ) + ->else(param(4)); + + $this->assertSql('CASE WHEN role = ? THEN 1 WHEN role = ? THEN 2 WHEN role = ? THEN ? ELSE ? END', $expr); + $this->assertParams(['admin', 'editor', 'user', 3, 4], $expr); + } + + public function testAsSwitch(): void + { + $expr = caseStatement(identify('role')) + ->when( + param('admin'), + literal(1), + ) + ->when( + param('editor'), + literal(2), + ) + ->when( + param('user'), + param(3), + ) + ->else(param(4)); + + $this->assertSql('CASE role WHEN ? THEN 1 WHEN ? THEN 2 WHEN ? THEN ? ELSE ? END', $expr); + $this->assertParams(['admin', 'editor', 'user', 3, 4], $expr); + } +}