diff --git a/core/Logic/CaseWhenExpression.class.php b/core/Logic/CaseWhenExpression.class.php new file mode 100644 index 0000000000..f6594c63da --- /dev/null +++ b/core/Logic/CaseWhenExpression.class.php @@ -0,0 +1,87 @@ +addCase($expression, $result); + } + if ($else !== null) { + $this->addElse($else); + } + } + + /** + * @param $expression + * @param $result + * @return CaseWhenExpression + */ + public function addCase($expression, $result) + { + $this->cases[] = array($expression, $result); + return $this; + } + + /** + * @param $result + * @return CaseWhenExpression + */ + public function addElse($result) + { + $this->else = $result; + return $this; + } + + /** + * @param ProtoDAO $dao + * @param JoinCapableQuery $query + * @return MappableObject + */ + public function toMapped(ProtoDAO $dao, JoinCapableQuery $query) + { + $expr = new CaseWhenExpression(); + foreach ($this->cases as $case) { + $expr->addCase( + $dao->guessAtom($case[0], $query), + $dao->guessAtom($case[1], $query) + ); + } + if ($this->else) { + $expr->addElse($dao->guessAtom($this->else, $query)); + } + + return $expr; + } + + public function toDialectString(Dialect $dialect) + { + $sqlCases = array(); + foreach ($this->cases as $case) { + $sqlCases[] = 'WHEN '.$dialect->toFieldString($case[0]) + .' THEN '.$dialect->toValueString($case[1]); + } + if ($this->else) { + $sqlCases[] = 'ELSE '.$dialect->toValueString($this->else); + } + + return 'CASE '.implode(' ', $sqlCases).' END'; + } + } \ No newline at end of file diff --git a/core/Logic/PrefixUnaryExpression.class.php b/core/Logic/PrefixUnaryExpression.class.php index 73445296d3..9c17877b58 100644 --- a/core/Logic/PrefixUnaryExpression.class.php +++ b/core/Logic/PrefixUnaryExpression.class.php @@ -26,7 +26,7 @@ final class PrefixUnaryExpression implements LogicalObject, MappableObject */ public static function create($subject, $logic) { - return new self($subject, $logic); + return new self($logic, $subject); } public function __construct($logic, $subject) diff --git a/test/db/CaseWhenExpressionDBTest.class.php b/test/db/CaseWhenExpressionDBTest.class.php new file mode 100644 index 0000000000..e7e5f7b310 --- /dev/null +++ b/test/db/CaseWhenExpressionDBTest.class.php @@ -0,0 +1,42 @@ +getDbByType('PgSQL')->getDialect(); + + $beautifulNameExpr = CaseWhenExpression::create( + Expression::isTrue('capital'), + SQLFunction::create('upper', 'name'), + SQLFunction::create('lower', 'name') + ) + ->addCase(Expression::eq('name', 'St. Peterburg'), 'ST. PETERBURG'); + + $orderExpr = CaseWhenExpression::create() + ->addCase(Expression::isTrue('capital'), SQLFunction::create('upper', 'name')) + ->addCase(Expression::eq('name', 'St. Peterburg'), 'ST. PETERBURG') + ->addElse('name'); + + $criteria = Criteria::create(TestCity::dao()) + ->addProjection(Projection::property($beautifulNameExpr, 'beautifulName')) + ->addOrder($orderExpr); + + $expectation = 'SELECT CASE ' + .'WHEN ("custom_table"."capital" IS TRUE) THEN upper("custom_table"."name") ' + .'WHEN ("custom_table"."name" = \'St. Peterburg\') THEN \'ST. PETERBURG\' ' + .'ELSE lower("custom_table"."name") ' + .'END AS "beautifulName" ' + .'FROM "custom_table" ' + .'ORDER BY CASE ' + .'WHEN ("custom_table"."capital" IS TRUE) THEN upper("custom_table"."name") ' + .'WHEN ("custom_table"."name" = \'St. Peterburg\') THEN \'ST. PETERBURG\' ' + .'ELSE "custom_table"."name" ' + .'END'; + + $this->assertEquals($expectation, $criteria->toDialectString($dialect)); + } + } +?> \ No newline at end of file