2016-10-06 02:08:43 +00:00
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
2017-03-28 04:12:12 +00:00
|
|
|
namespace JKingWeb\Arsse\Db;
|
2016-10-17 20:49:39 +00:00
|
|
|
use JKingWeb\DrUUID\UUID as UUID;
|
2016-10-06 02:08:43 +00:00
|
|
|
|
2017-03-03 01:47:00 +00:00
|
|
|
abstract class AbstractDriver implements Driver {
|
2017-02-16 20:29:42 +00:00
|
|
|
protected $transDepth = 0;
|
2017-02-19 22:02:03 +00:00
|
|
|
|
2017-02-16 20:29:42 +00:00
|
|
|
public function schemaVersion(): int {
|
|
|
|
try {
|
2017-03-28 04:12:12 +00:00
|
|
|
return (int) $this->query("SELECT value from arsse_settings where key is schema_version")->getValue();
|
2017-03-09 22:14:26 +00:00
|
|
|
} catch(Exception $e) {
|
2017-02-16 20:29:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2017-02-19 22:02:03 +00:00
|
|
|
|
2017-05-06 16:02:27 +00:00
|
|
|
public function begin(): Transaction {
|
|
|
|
return new Transaction($this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function savepointCreate(): bool {
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->exec("SAVEPOINT arsse_".(++$this->transDepth));
|
2017-02-16 20:29:42 +00:00
|
|
|
return true;
|
|
|
|
}
|
2016-10-06 02:08:43 +00:00
|
|
|
|
2017-05-06 16:02:27 +00:00
|
|
|
public function savepointRelease(bool $all = false): bool {
|
2017-02-16 20:29:42 +00:00
|
|
|
if($this->transDepth==0) return false;
|
|
|
|
if(!$all) {
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->exec("RELEASE SAVEPOINT arsse_".($this->transDepth--));
|
2017-02-16 20:29:42 +00:00
|
|
|
} else {
|
|
|
|
$this->exec("COMMIT TRANSACTION");
|
2017-02-19 22:02:03 +00:00
|
|
|
$this->transDepth = 0;
|
2017-02-16 20:29:42 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2016-10-06 02:08:43 +00:00
|
|
|
|
2017-05-06 16:02:27 +00:00
|
|
|
public function savepointUndo(bool $all = false): bool {
|
2017-02-16 20:29:42 +00:00
|
|
|
if($this->transDepth==0) return false;
|
|
|
|
if(!$all) {
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->exec("ROLLBACK TRANSACTION TO SAVEPOINT arsse_".($this->transDepth));
|
2017-02-16 20:29:42 +00:00
|
|
|
// rollback to savepoint does not collpase the savepoint
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->exec("RELEASE SAVEPOINT arsse_".($this->transDepth--));
|
2017-02-16 20:29:42 +00:00
|
|
|
} else {
|
|
|
|
$this->exec("ROLLBACK TRANSACTION");
|
|
|
|
$this->transDepth = 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2016-10-06 02:08:43 +00:00
|
|
|
|
2017-02-16 20:29:42 +00:00
|
|
|
public function lock(): bool {
|
|
|
|
if($this->schemaVersion() < 1) return true;
|
|
|
|
if($this->isLocked()) return false;
|
|
|
|
$uuid = UUID::mintStr();
|
2017-03-09 22:14:26 +00:00
|
|
|
try {
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->prepare("INSERT INTO arsse_settings(key,value) values(?,?)", "str", "str")->run("lock", $uuid);
|
2017-03-09 22:14:26 +00:00
|
|
|
} catch(ExceptionInput $e) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-02-16 20:29:42 +00:00
|
|
|
sleep(1);
|
2017-03-28 04:12:12 +00:00
|
|
|
return ($this->query("SELECT value from arsse_settings where key is 'lock'")->getValue() == $uuid);
|
2017-02-16 20:29:42 +00:00
|
|
|
}
|
2016-10-17 20:49:39 +00:00
|
|
|
|
2017-02-16 20:29:42 +00:00
|
|
|
public function unlock(): bool {
|
2017-03-10 02:39:42 +00:00
|
|
|
if($this->schemaVersion() < 1) return true;
|
2017-03-28 04:12:12 +00:00
|
|
|
$this->exec("DELETE from arsse_settings where key is 'lock'");
|
2017-03-09 22:14:26 +00:00
|
|
|
return true;
|
2017-02-16 20:29:42 +00:00
|
|
|
}
|
2016-10-17 20:49:39 +00:00
|
|
|
|
2017-02-16 20:29:42 +00:00
|
|
|
public function isLocked(): bool {
|
|
|
|
if($this->schemaVersion() < 1) return false;
|
2017-03-28 04:12:12 +00:00
|
|
|
return ($this->query("SELECT count(*) from arsse_settings where key is 'lock'")->getValue() > 0);
|
2017-02-16 20:29:42 +00:00
|
|
|
}
|
2016-10-17 20:49:39 +00:00
|
|
|
|
2017-04-06 15:02:47 +00:00
|
|
|
public function prepare(string $query, ...$paramType): Statement {
|
2017-02-16 20:29:42 +00:00
|
|
|
return $this->prepareArray($query, $paramType);
|
|
|
|
}
|
2016-10-06 02:08:43 +00:00
|
|
|
}
|