Allow config save to create new entries

This commit is contained in:
Bartek Fabiszewski 2020-06-05 11:41:41 +02:00
parent bb5c142390
commit e24075d055
3 changed files with 69 additions and 31 deletions

View File

@ -129,12 +129,14 @@ class ConfigTest extends UloggerDatabaseTestCase {
"stroke_opacity" => $this->config->strokeOpacity "stroke_opacity" => $this->config->strokeOpacity
]; ];
$cnt = count($expected); $cnt = count($expected);
$this->assertEquals($cnt, $this->getConnection()->getRowCount('config'), "Wrong row count"); $this->assertGreaterThanOrEqual($cnt, $this->getConnection()->getRowCount('config'), "Wrong row count");
$actual = $this->getConnection()->createQueryTable("config", "SELECT * FROM config"); $actual = $this->getConnection()->createQueryTable("config", "SELECT * FROM config");
for ($i = 0; $i < $cnt; $i++) { for ($i = 0; $i < $cnt; $i++) {
$row = $actual->getRow($i); $row = $actual->getRow($i);
$actualValue = $row['value']; $actualValue = $row['value'];
$this->assertEquals(serialize($expected[$row['name']]), is_resource($actualValue) ? stream_get_contents($actualValue) : $actualValue); if (isset($expected[$row['name']])) {
$this->assertEquals(serialize($expected[$row['name']]), is_resource($actualValue) ? stream_get_contents($actualValue) : $actualValue);
}
} }
$this->assertEquals(1, $this->getConnection()->getRowCount('ol_layers'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('ol_layers'), "Wrong row count");
$expected = [ $expected = [

View File

@ -182,10 +182,10 @@ class uConfig {
*/ */
public function setFromDatabase() { public function setFromDatabase() {
try { try {
$query = "SELECT name, value FROM " . self::db()->table('config'); $query = "SELECT name, value FROM " . self::db()->table("config");
$result = self::db()->query($query); $result = self::db()->query($query);
$arr = $result->fetchAll(PDO::FETCH_KEY_PAIR); $arr = $result->fetchAll(PDO::FETCH_KEY_PAIR);
$this->setFromArray(array_map([ $this, 'unserialize' ], $arr)); $this->setFromArray(array_map([ $this, "unserialize" ], $arr));
$this->setLayersFromDatabase(); $this->setLayersFromDatabase();
if (!$this->requireAuthentication) { if (!$this->requireAuthentication) {
// tracks must be public if we don't require authentication // tracks must be public if we don't require authentication
@ -218,29 +218,29 @@ class uConfig {
try { try {
// PDO::PARAM_LOB doesn't work here with pgsql, why? // PDO::PARAM_LOB doesn't work here with pgsql, why?
$placeholder = self::db()->lobPlaceholder(); $placeholder = self::db()->lobPlaceholder();
$query = "UPDATE " . self::db()->table('config') . " $values = [
SET value = CASE name ["'color_extra'", $placeholder],
WHEN 'color_extra' THEN $placeholder ["'color_hilite'", $placeholder],
WHEN 'color_hilite' THEN $placeholder ["'color_normal'", $placeholder],
WHEN 'color_normal' THEN $placeholder ["'color_start'", $placeholder],
WHEN 'color_start' THEN $placeholder ["'color_stop'", $placeholder],
WHEN 'color_stop' THEN $placeholder ["'google_key'", $placeholder],
WHEN 'google_key' THEN $placeholder ["'latitude'", $placeholder],
WHEN 'latitude' THEN $placeholder ["'longitude'", $placeholder],
WHEN 'longitude' THEN $placeholder ["'interval_seconds'", $placeholder],
WHEN 'interval_seconds' THEN $placeholder ["'lang'", $placeholder],
WHEN 'lang' THEN $placeholder ["'map_api'", $placeholder],
WHEN 'map_api' THEN $placeholder ["'pass_lenmin'", $placeholder],
WHEN 'pass_lenmin' THEN $placeholder ["'pass_strength'", $placeholder],
WHEN 'pass_strength' THEN $placeholder ["'public_tracks'", $placeholder],
WHEN 'public_tracks' THEN $placeholder ["'require_auth'", $placeholder],
WHEN 'require_auth' THEN $placeholder ["'stroke_color'", $placeholder],
WHEN 'stroke_color' THEN $placeholder ["'stroke_opacity'", $placeholder],
WHEN 'stroke_opacity' THEN $placeholder ["'stroke_weight'", $placeholder],
WHEN 'stroke_weight' THEN $placeholder ["'units'", $placeholder],
WHEN 'units' THEN $placeholder ["'upload_maxsize'", $placeholder]
WHEN 'upload_maxsize' THEN $placeholder ];
END"; $query = self::db()->insertOrReplace("config", [ "name", "value" ], $values, "name", "value");
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$params = [ $params = [
$this->colorExtra, $this->colorExtra,
@ -265,7 +265,7 @@ class uConfig {
$this->uploadMaxSize $this->uploadMaxSize
]; ];
$stmt->execute(array_map('serialize', $params)); $stmt->execute(array_map("serialize", $params));
$this->saveLayers(); $this->saveLayers();
$ret = true; $ret = true;
} catch (PDOException $e) { } catch (PDOException $e) {
@ -280,7 +280,7 @@ class uConfig {
* @throws PDOException * @throws PDOException
*/ */
private function deleteLayers() { private function deleteLayers() {
$query = "DELETE FROM " . self::db()->table('ol_layers'); $query = "DELETE FROM " . self::db()->table("ol_layers");
self::db()->exec($query); self::db()->exec($query);
} }
@ -291,7 +291,7 @@ class uConfig {
private function saveLayers() { private function saveLayers() {
$this->deleteLayers(); $this->deleteLayers();
if (!empty($this->olLayers)) { if (!empty($this->olLayers)) {
$query = "INSERT INTO " . self::db()->table('ol_layers') . " (id, name, url, priority) VALUES (?, ?, ?, ?)"; $query = "INSERT INTO " . self::db()->table("ol_layers") . " (id, name, url, priority) VALUES (?, ?, ?, ?)";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
foreach ($this->olLayers as $layer) { foreach ($this->olLayers as $layer) {
$stmt->execute([ $layer->id, $layer->name, $layer->url, $layer->priority]); $stmt->execute([ $layer->id, $layer->name, $layer->url, $layer->priority]);
@ -308,7 +308,7 @@ class uConfig {
$query = "SELECT id, name, url, priority FROM " . self::db()->table('ol_layers'); $query = "SELECT id, name, url, priority FROM " . self::db()->table('ol_layers');
$result = self::db()->query($query); $result = self::db()->query($query);
while ($row = $result->fetch()) { while ($row = $result->fetch()) {
$this->olLayers[] = new uLayer($row['id'], $row['name'], $row['url'], $row['priority']); $this->olLayers[] = new uLayer($row["id"], $row["name"], $row["url"], $row["priority"]);
} }
} }

View File

@ -222,6 +222,42 @@ require_once(ROOT_DIR . "/helpers/utils.php");
} }
} }
/**
* Replace into
* Note: requires PostgreSQL >= 9.5
* @param string $table Table name (without prefix)
* @param string[] $columns Column names
* @param string[][] $values Values [ [ value1, value2 ], ... ]
* @param string $key Unique column
* @param string $update Updated column
* @return string
*/
public function insertOrReplace($table, $columns, $values, $key, $update) {
$cols = implode(", ", $columns);
$rows = [];
foreach ($values as $row) {
$rows[] = "(" . implode(", ", $row) . ")";
}
$vals = implode(", ", $rows);
switch (self::$driver) {
default:
case "mysql":
return "INSERT INTO {$this->table($table)} ($cols)
VALUES $vals
ON DUPLICATE KEY UPDATE $update = VALUES($update)";
break;
case "pgsql":
return "INSERT INTO {$this->table($table)} ($cols)
VALUES $vals
ON CONFLICT ($key) DO UPDATE SET $update = EXCLUDED.$update";
break;
case "sqlite":
return "REPLACE INTO {$this->table($table)} ($cols)
VALUES $vals";
break;
}
}
/** /**
* Set character set * Set character set
* @param string $charset * @param string $charset