Browse Source

Test for advisory locking

microsub
J. King 7 years ago
parent
commit
689c1c77d0
  1. 12
      lib/Database.php
  2. 18
      lib/Db/AbstractDriver.php
  3. 18
      tests/Db/SQLite3/TestDbDriverSQLite3.php

12
lib/Database.php

@ -94,26 +94,26 @@ class Database {
case "integer":
$type = "int";
case "int":
$value =& $in;
$value = $in;
break;
case "float":
case "double":
case "real":
$type = "numeric";
case "numeric":
$value =& $in;
$value = $in;
break;
case "str":
case "string":
$type = "text";
case "text":
$value =& $in;
$value = $in;
break;
case "json":
if(is_array($in) || is_object($in)) {
$value = json_encode($in);
} else {
$value =& $in;
$value = $in;
}
break;
case "datetime":
@ -156,10 +156,10 @@ class Database {
break;
default:
$type = "text";
$value =& $in;
$value = $in;
break;
}
$this->db->prepare("REPLACE INTO newssync_settings(key,value,type) values(?,?,?)", "str", "str", "str")->run($key, $value, $type);
return (bool) $this->db->prepare("REPLACE INTO newssync_settings(key,value,type) values(?,?,?)", "str", "str", "str")->run($key, $value, $type)->changes();
}
public function settingRemove(string $key): bool {

18
lib/Db/AbstractDriver.php

@ -8,8 +8,8 @@ abstract class AbstractDriver implements Driver {
public function schemaVersion(): int {
try {
return $this->data->db->settingGet("schema_version");
} catch(\Throwable $e) {
return (int) $this->query("SELECT value from newssync_settings where key is schema_version")->getValue();
} catch(Exception $e) {
return 0;
}
}
@ -47,19 +47,23 @@ abstract class AbstractDriver implements Driver {
if($this->schemaVersion() < 1) return true;
if($this->isLocked()) return false;
$uuid = UUID::mintStr();
if(!$this->data->db->settingSet("lock", $uuid)) return false;
try {
$this->prepare("INSERT INTO newssync_settings(key,value) values(?,?)", "str", "str")->run("lock", $uuid);
} catch(ExceptionInput $e) {
return false;
}
sleep(1);
if($this->data->db->settingGet("lock") != $uuid) return false;
return true;
return ($this->query("SELECT value from newssync_settings where key is 'lock'")->getValue() == $uuid);
}
public function unlock(): bool {
return $this->data->db->settingRemove("lock");
$this->exec("DELETE from newssync_settings where key is 'lock'");
return true;
}
public function isLocked(): bool {
if($this->schemaVersion() < 1) return false;
return ($this->query("SELECT count(*) from newssync_settings where key = 'lock'")->getSingle() > 0);
return ($this->query("SELECT count(*) from newssync_settings where key is 'lock'")->getValue() > 0);
}
public function prepare(string $query, string ...$paramType): Statement {

18
tests/Db/SQLite3/TestDbDriverSQLite3.php

@ -246,4 +246,22 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase {
$this->assertEquals(2, $this->drv->query($select)->getValue());
$this->assertEquals(2, $ch->querySingle($select));
}
function testManipulateAdvisoryLock() {
$this->assertFalse($this->drv->isLocked());
$this->assertTrue($this->drv->lock());
$this->assertFalse($this->drv->isLocked());
$this->drv->exec("CREATE TABLE newssync_settings(key primary key, value, type) without rowid; PRAGMA user_version=1");
$this->assertTrue($this->drv->lock());
$this->assertTrue($this->drv->isLocked());
$this->assertFalse($this->drv->lock());
$this->drv->exec("PRAGMA user_version=0");
$this->assertFalse($this->drv->isLocked());
$this->assertTrue($this->drv->lock());
$this->assertFalse($this->drv->isLocked());
$this->drv->exec("PRAGMA user_version=1");
$this->assertTrue($this->drv->isLocked());
$this->assertTrue($this->drv->unlock());
$this->assertFalse($this->drv->isLocked());
}
}
Loading…
Cancel
Save