ON Conflict for postgres

This commit is contained in:
Roman Hergenreder 2020-06-18 15:08:09 +02:00
parent 94eb70c24e
commit 63fcba9dd9
4 changed files with 46 additions and 15 deletions

@ -4,6 +4,7 @@ namespace Driver\SQL;
use \Api\Parameter\Parameter;
use Driver\SQL\Column\Column;
use \Driver\SQL\Column\IntColumn;
use \Driver\SQL\Column\SerialColumn;
use \Driver\SQL\Column\StringColumn;
@ -12,7 +13,9 @@ use \Driver\SQL\Column\DateTimeColumn;
use Driver\SQL\Column\BoolColumn;
use Driver\SQL\Column\JsonColumn;
use Driver\SQL\Expression\Add;
use Driver\SQL\Strategy\Strategy;
use Driver\SQL\Strategy\UpdateStrategy;
class PostgreSQL extends SQL {
@ -129,24 +132,31 @@ class PostgreSQL extends SQL {
protected function getOnDuplicateStrategy(?Strategy $strategy, &$params) {
if (!is_null($strategy)) {
/*if ($onDuplicateKey instanceof UpdateStrategy) {
if ($strategy instanceof UpdateStrategy) {
$updateValues = array();
foreach($onDuplicateKey->getValues() as $key => $value) {
foreach($strategy->getValues() as $key => $value) {
$leftColumn = $this->columnName($key);
if ($value instanceof Column) {
$columnName = $value->getName();
$updateValues[] = "\"$key\"=\"$columnName\"";
$columnName = $this->columnName($value->getName());
$updateValues[] = "$leftColumn=$columnName";
} else if ($value instanceof Add) {
$columnName = $this->columnName($value->getColumn());
$operator = $value->getOperator();
$value = $value->getValue();
$updateValues[] = "$leftColumn=$columnName$operator" . $this->addValue($value, $params);
} else {
$updateValues[] = "\"$key\"=" . $this->addValue($value, $parameters);
$updateValues[] = "$leftColumn=" . $this->addValue($value, $parameters);
}
}
$onDuplicateKey = " ON CONFLICT DO UPDATE SET " . implode(",", $updateValues);
} else*/ {
$strategyClass = get_class($strategy);
$this->lastError = "ON DUPLICATE Strategy $strategyClass is not supported yet.";
return false;
}
$conflictingColumns = $this->columnName($strategy->getConflictingColumns());
$updateValues = implode(",", $updateValues);
return " ON CONFLICT ($conflictingColumns) DO UPDATE SET $updateValues";
} else {
$strategyClass = get_class($strategy);
$this->lastError = "ON DUPLICATE Strategy $strategyClass is not supported yet.";
return false;
}
} else {
return "";
}

@ -143,7 +143,7 @@ abstract class SQL {
$returningCol = $insert->getReturning();
$returning = $this->getReturning($returningCol);
$query = "INSERT INTO $tableName$columnStr VALUES$values$onDuplicateKey$returning";
$query = "INSERT INTO $tableName$columnStr VALUES $values$onDuplicateKey$returning";
if($insert->dump) { var_dump($query); var_dump($parameters); }
$res = $this->execute($query, $parameters, !empty($returning));
$success = ($res !== FALSE);

@ -5,10 +5,16 @@ namespace Driver\SQL\Strategy;
class UpdateStrategy extends Strategy {
private array $values;
private array $conflictingColumns;
public function __construct($values) {
public function __construct($conflictingColumns, $values) {
$this->conflictingColumns = $conflictingColumns;
$this->values = $values;
}
public function getConflictingColumns() {
return $this->conflictingColumns;
}
public function getValues() { return $this->values; }
}

@ -239,13 +239,28 @@ class User extends ApiObject {
public function processVisit() {
if ($this->sql && isset($_COOKIE["PHPSESSID"]) && !empty($_COOKIE["PHPSESSID"])) {
if ($this->isBot()) {
return;
}
$cookie = $_COOKIE["PHPSESSID"];
$month = (new DateTime())->format("Ym");
$this->sql->insert("Visitor", array("cookie", "month"))
->addRow($cookie, $month)
->onDuplicateKeyStrategy(new UpdateStrategy(array("count" => new Add("count", 1))))
->onDuplicateKeyStrategy(new UpdateStrategy(
array("month", "cookie"),
array("count" => new Add("Visitor.count", 1))))
->execute();
}
}
private function isBot() {
if (!isset($_SERVER["HTTP_USER_AGENT"]) || empty($_SERVER["HTTP_USER_AGENT"])) {
return false;
}
return preg_match('/robot|spider|crawler|curl|^$/i', $_SERVER['HTTP_USER_AGENT']) === 1;
}
}