From 689c1c77d0d9ca830345f73c598fe512669f22e2 Mon Sep 17 00:00:00 2001 From: "J. King" Date: Thu, 9 Mar 2017 17:14:26 -0500 Subject: [PATCH] Test for advisory locking --- lib/Database.php | 12 ++++++------ lib/Db/AbstractDriver.php | 18 +++++++++++------- tests/Db/SQLite3/TestDbDriverSQLite3.php | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/Database.php b/lib/Database.php index fb3356d..268614d 100644 --- a/lib/Database.php +++ b/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 { diff --git a/lib/Db/AbstractDriver.php b/lib/Db/AbstractDriver.php index 3d46199..c78adea 100644 --- a/lib/Db/AbstractDriver.php +++ b/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 { diff --git a/tests/Db/SQLite3/TestDbDriverSQLite3.php b/tests/Db/SQLite3/TestDbDriverSQLite3.php index 2cbbe11..b463b1f 100644 --- a/tests/Db/SQLite3/TestDbDriverSQLite3.php +++ b/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()); + } } \ No newline at end of file