SQL CaseWhen/Sum + ContactRequest API fix

This commit is contained in:
2021-04-10 01:33:40 +02:00
parent 7506a81514
commit 896bbe76b4
8 changed files with 121 additions and 38 deletions

View File

@@ -0,0 +1,23 @@
<?php
namespace Driver\SQL\Expression;
use Driver\SQL\Condition\Condition;
class CaseWhen extends Expression {
private Condition $condition;
private $trueCase;
private $falseCase;
public function __construct(Condition $condition, $trueCase, $falseCase) {
$this->condition = $condition;
$this->trueCase = $trueCase;
$this->falseCase = $falseCase;
}
public function getCondition(): Condition { return $this->condition; }
public function getTrueCase() { return $this->trueCase; }
public function getFalseCase() { return $this->falseCase; }
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Driver\SQL\Expression;
use Driver\SQL\Condition\Condition;
class Sum extends Expression {
private $value;
private string $alias;
public function __construct($value, string $alias) {
$this->value = $value;
$this->alias = $alias;
}
public function getValue() { return $this->value; }
public function getAlias(): string { return $this->alias; }
}

View File

@@ -290,7 +290,7 @@ class MySQL extends SQL {
}
}
public function addValue($val, &$params = NULL) {
public function addValue($val, &$params = NULL, bool $unsafe = false) {
if ($val instanceof Keyword) {
return $val->getValue();
} else if ($val instanceof CurrentColumn) {
@@ -300,8 +300,12 @@ class MySQL extends SQL {
} else if ($val instanceof Expression) {
return $this->createExpression($val, $params);
} else {
$params[] = $val;
return "?";
if ($unsafe) {
return $this->getUnsafeValue($val);
} else {
$params[] = $val;
return "?";
}
}
}
@@ -403,7 +407,7 @@ class MySQL extends SQL {
return $query;
}
protected function createExpression(Expression $exp, array &$params) {
protected function createExpression(Expression $exp, array &$params): ?string {
if ($exp instanceof DateAdd || $exp instanceof DateSub) {
$lhs = $this->addValue($exp->getLHS(), $params);
$rhs = $this->addValue($exp->getRHS(), $params);

View File

@@ -276,7 +276,7 @@ class PostgreSQL extends SQL {
}
}
public function addValue($val, &$params = NULL) {
public function addValue($val, &$params = NULL, bool $unsafe = false) {
if ($val instanceof Keyword) {
return $val->getValue();
} else if ($val instanceof CurrentTable) {
@@ -288,8 +288,12 @@ class PostgreSQL extends SQL {
} else if ($val instanceof Expression) {
return $this->createExpression($val, $params);
} else {
$params[] = is_bool($val) ? ($val ? "TRUE" : "FALSE") : $val;
return '$' . count($params);
if ($unsafe) {
return $this->getUnsafeValue($val);
} else {
$params[] = is_bool($val) ? ($val ? "TRUE" : "FALSE") : $val;
return '$' . count($params);
}
}
}
@@ -419,7 +423,7 @@ class PostgreSQL extends SQL {
return $query;
}
protected function createExpression(Expression $exp, array &$params) {
protected function createExpression(Expression $exp, array &$params): ?string {
if ($exp instanceof DateAdd || $exp instanceof DateSub) {
$lhs = $this->addValue($exp->getLHS(), $params);
$rhs = $this->addValue($exp->getRHS(), $params);

View File

@@ -8,7 +8,7 @@ use Driver\SQL\SQL;
class Select extends Query {
private array $columns;
private array $selectValues;
private array $tables;
private array $conditions;
private array $joins;
@@ -18,9 +18,9 @@ class Select extends Query {
private int $limit;
private int $offset;
public function __construct($sql, ...$columns) {
public function __construct($sql, ...$selectValues) {
parent::__construct($sql);
$this->columns = (!empty($columns) && is_array($columns[0])) ? $columns[0] : $columns;
$this->selectValues = (!empty($selectValues) && is_array($selectValues[0])) ? $selectValues[0] : $selectValues;
$this->tables = array();
$this->conditions = array();
$this->joins = array();
@@ -85,7 +85,7 @@ class Select extends Query {
return $this->sql->executeQuery($this, true);
}
public function getColumns(): array { return $this->columns; }
public function getSelectValues(): array { return $this->selectValues; }
public function getTables(): array { return $this->tables; }
public function getConditions(): array { return $this->conditions; }
public function getJoins(): array { return $this->joins; }
@@ -96,11 +96,21 @@ class Select extends Query {
public function getGroupBy(): array { return $this->groupColumns; }
public function build(array &$params): ?string {
$columns = $this->sql->columnName($this->getColumns());
$selectValues = [];
foreach ($this->selectValues as $value) {
if (is_string($value)) {
$selectValues[] = $this->sql->columnName($value);
} else {
$selectValues[] = $this->sql->addValue($value, $params);
}
}
$tables = $this->getTables();
$selectValues = implode(",", $selectValues);
if (!$tables) {
return "SELECT $columns";
return "SELECT $selectValues";
}
$tables = $this->sql->tableName($tables);
@@ -135,6 +145,6 @@ class Select extends Query {
$limit = ($this->getLimit() > 0 ? (" LIMIT " . $this->getLimit()) : "");
$offset = ($this->getOffset() > 0 ? (" OFFSET " . $this->getOffset()) : "");
return "SELECT $columns FROM $tables$joinStr$where$groupBy$orderBy$limit$offset";
return "SELECT $selectValues FROM $tables$joinStr$where$groupBy$orderBy$limit$offset";
}
}

View File

@@ -15,8 +15,10 @@ use Driver\SQL\Constraint\Constraint;
use \Driver\SQL\Constraint\Unique;
use \Driver\SQL\Constraint\PrimaryKey;
use \Driver\SQL\Constraint\ForeignKey;
use Driver\SQL\Expression\CaseWhen;
use Driver\SQL\Expression\CurrentTimeStamp;
use Driver\SQL\Expression\Expression;
use Driver\SQL\Expression\Sum;
use Driver\SQL\Query\AlterTable;
use Driver\SQL\Query\CreateProcedure;
use Driver\SQL\Query\CreateTable;
@@ -187,8 +189,10 @@ abstract class SQL {
}
protected function getUnsafeValue($value): ?string {
if (is_string($value) || is_numeric($value) || is_bool($value)) {
if (is_string($value)) {
return "'" . addslashes("$value") . "'"; // unsafe operation here...
} else if (is_numeric($value) || is_bool($value)) {
return $value;
} else if ($value instanceof Column) {
return $this->columnName($value);
} else if ($value === null) {
@@ -200,7 +204,7 @@ abstract class SQL {
}
protected abstract function getValueDefinition($val);
public abstract function addValue($val, &$params = NULL);
public abstract function addValue($val, &$params = NULL, bool $unsafe = false);
protected abstract function buildUnsafe(Query $statement): string;
public abstract function tableName($table): string;
@@ -222,12 +226,6 @@ abstract class SQL {
}
}
public function sum($col): Keyword {
$sumCol = strtolower(str_replace(".","_", $col)) . "_sum";
$col = $this->columnName($col);
return new Keyword("SUM($col) AS $sumCol");
}
public function distinct($col): Keyword {
$col = $this->columnName($col);
return new Keyword("DISTINCT($col)");
@@ -312,11 +310,23 @@ abstract class SQL {
}
}
protected function createExpression(Expression $exp, array &$params) {
protected function createExpression(Expression $exp, array &$params): ?string {
if ($exp instanceof Column) {
return $this->columnName($exp);
} else if ($exp instanceof Query) {
return "(" . $exp->build($params) . ")";
} else if ($exp instanceof CaseWhen) {
$condition = $this->buildCondition($exp->getCondition(), $params);
// psql requires constant values here
$trueCase = $this->addValue($exp->getTrueCase(), $params, true);
$falseCase = $this->addValue($exp->getFalseCase(), $params, true);
return "CASE WHEN $condition THEN $trueCase ELSE $falseCase END";
} else if ($exp instanceof Sum) {
$value = $this->addValue($exp->getValue(), $params);
$alias = $exp->getAlias();
return "SUM($value) AS $alias";
} else {
$this->lastError = "Unsupported expression type: " . get_class($exp);
return null;