mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2025-01-03 14:32:40 +00:00
SQLite driver tweaks
This commit is contained in:
parent
7ca0f4e877
commit
ef75b5e9ab
6 changed files with 35 additions and 23 deletions
|
@ -13,6 +13,8 @@ abstract class AbstractDriver implements Driver {
|
||||||
protected $transDepth = 0;
|
protected $transDepth = 0;
|
||||||
protected $transStatus = [];
|
protected $transStatus = [];
|
||||||
|
|
||||||
|
protected abstract function getError(): string;
|
||||||
|
|
||||||
/** @codeCoverageIgnore */
|
/** @codeCoverageIgnore */
|
||||||
public function schemaVersion(): int {
|
public function schemaVersion(): int {
|
||||||
// FIXME: generic schemaVersion() will need to be covered for database engines other than SQLite
|
// FIXME: generic schemaVersion() will need to be covered for database engines other than SQLite
|
||||||
|
@ -46,6 +48,8 @@ abstract class AbstractDriver implements Driver {
|
||||||
$sql = @file_get_contents($file);
|
$sql = @file_get_contents($file);
|
||||||
if ($sql===false) {
|
if ($sql===false) {
|
||||||
throw new Exception("updateFileUnusable", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a]); // @codeCoverageIgnore
|
throw new Exception("updateFileUnusable", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a]); // @codeCoverageIgnore
|
||||||
|
} elseif ($sql==="") {
|
||||||
|
throw new Exception("updateFileIncomplete", ['file' => $file, 'driver_name' => $this->driverName(), 'current' => $a]);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->exec($sql);
|
$this->exec($sql);
|
||||||
|
|
|
@ -27,10 +27,9 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||||
}
|
}
|
||||||
// if no database file is specified in the configuration, use a suitable default
|
// if no database file is specified in the configuration, use a suitable default
|
||||||
$dbFile = $dbFile ?? Arsse::$conf->dbSQLite3File ?? \JKingWeb\Arsse\BASE."arsse.db";
|
$dbFile = $dbFile ?? Arsse::$conf->dbSQLite3File ?? \JKingWeb\Arsse\BASE."arsse.db";
|
||||||
$mode = \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE;
|
|
||||||
$timeout = Arsse::$conf->dbSQLite3Timeout * 1000;
|
$timeout = Arsse::$conf->dbSQLite3Timeout * 1000;
|
||||||
try {
|
try {
|
||||||
$this->makeConnection($dbFile, $mode, Arsse::$conf->dbSQLite3Key);
|
$this->makeConnection($dbFile, Arsse::$conf->dbSQLite3Key);
|
||||||
// set the timeout; parameters are not allowed for pragmas, but this usage should be safe
|
// set the timeout; parameters are not allowed for pragmas, but this usage should be safe
|
||||||
$this->exec("PRAGMA busy_timeout = $timeout");
|
$this->exec("PRAGMA busy_timeout = $timeout");
|
||||||
// set other initial options
|
// set other initial options
|
||||||
|
@ -62,8 +61,8 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||||
return class_exists("SQLite3");
|
return class_exists("SQLite3");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function makeConnection(string $file, int $opts, string $key) {
|
protected function makeConnection(string $file, string $key) {
|
||||||
$this->db = new \SQLite3($file, $opts, $key);
|
$this->db = new \SQLite3($file, \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE, $key);
|
||||||
// enable exceptions
|
// enable exceptions
|
||||||
$this->db->enableExceptions(true);
|
$this->db->enableExceptions(true);
|
||||||
}
|
}
|
||||||
|
@ -76,6 +75,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||||
unset($this->db);
|
unset($this->db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @codeCoverageIgnore */
|
||||||
public static function create(): \JKingWeb\Arsse\Db\Driver {
|
public static function create(): \JKingWeb\Arsse\Db\Driver {
|
||||||
if (self::requirementsMet()) {
|
if (self::requirementsMet()) {
|
||||||
return new self;
|
return new self;
|
||||||
|
@ -96,7 +96,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaVersion(): int {
|
public function schemaVersion(): int {
|
||||||
return $this->query("PRAGMA user_version")->getValue();
|
return (int) $this->query("PRAGMA user_version")->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaUpdate(int $to, string $basePath = null): bool {
|
public function schemaUpdate(int $to, string $basePath = null): bool {
|
||||||
|
|
|
@ -7,6 +7,7 @@ declare(strict_types=1);
|
||||||
namespace JKingWeb\Arsse;
|
namespace JKingWeb\Arsse;
|
||||||
|
|
||||||
use JKingWeb\Arsse\Arsse;
|
use JKingWeb\Arsse\Arsse;
|
||||||
|
use JKingWeb\Arsse\Db\SQLite3\Driver;
|
||||||
use org\bovigo\vfs\vfsStream;
|
use org\bovigo\vfs\vfsStream;
|
||||||
use Phake;
|
use Phake;
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ class TestDbDriverCreationSQLite3 extends Test\AbstractTest {
|
||||||
protected $ch;
|
protected $ch;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
if (!extension_loaded("sqlite3")) {
|
if (!Driver::requirementsMet()) {
|
||||||
$this->markTestSkipped("SQLite extension not loaded");
|
$this->markTestSkipped("SQLite extension not loaded");
|
||||||
}
|
}
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
|
@ -107,7 +108,6 @@ class TestDbDriverCreationSQLite3 extends Test\AbstractTest {
|
||||||
// set up configuration
|
// set up configuration
|
||||||
Arsse::$conf = new Conf();
|
Arsse::$conf = new Conf();
|
||||||
Arsse::$conf->dbSQLite3File = ":memory:";
|
Arsse::$conf->dbSQLite3File = ":memory:";
|
||||||
// set up database shim
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown() {
|
||||||
|
@ -117,78 +117,78 @@ class TestDbDriverCreationSQLite3 extends Test\AbstractTest {
|
||||||
public function testFailToCreateDatabase() {
|
public function testFailToCreateDatabase() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
||||||
$this->assertException("fileUncreatable", "Db");
|
$this->assertException("fileUncreatable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToCreateJournal() {
|
public function testFailToCreateJournal() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
|
||||||
$this->assertException("fileUncreatable", "Db");
|
$this->assertException("fileUncreatable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToCreateSharedMmeory() {
|
public function testFailToCreateSharedMmeory() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
|
||||||
$this->assertException("fileUncreatable", "Db");
|
$this->assertException("fileUncreatable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToReadDatabase() {
|
public function testFailToReadDatabase() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
|
||||||
$this->assertException("fileUnreadable", "Db");
|
$this->assertException("fileUnreadable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToReadJournal() {
|
public function testFailToReadJournal() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
|
||||||
$this->assertException("fileUnreadable", "Db");
|
$this->assertException("fileUnreadable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToReadSharedMmeory() {
|
public function testFailToReadSharedMmeory() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
|
||||||
$this->assertException("fileUnreadable", "Db");
|
$this->assertException("fileUnreadable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToWriteToDatabase() {
|
public function testFailToWriteToDatabase() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
|
||||||
$this->assertException("fileUnwritable", "Db");
|
$this->assertException("fileUnwritable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToWriteToJournal() {
|
public function testFailToWriteToJournal() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
|
||||||
$this->assertException("fileUnwritable", "Db");
|
$this->assertException("fileUnwritable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToWriteToSharedMmeory() {
|
public function testFailToWriteToSharedMmeory() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
|
||||||
$this->assertException("fileUnwritable", "Db");
|
$this->assertException("fileUnwritable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToAccessDatabase() {
|
public function testFailToAccessDatabase() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
|
||||||
$this->assertException("fileUnusable", "Db");
|
$this->assertException("fileUnusable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToAccessJournal() {
|
public function testFailToAccessJournal() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
|
||||||
$this->assertException("fileUnusable", "Db");
|
$this->assertException("fileUnusable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFailToAccessSharedMmeory() {
|
public function testFailToAccessSharedMmeory() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
|
||||||
$this->assertException("fileUnusable", "Db");
|
$this->assertException("fileUnusable", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAssumeDatabaseCorruption() {
|
public function testAssumeDatabaseCorruption() {
|
||||||
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
|
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
|
||||||
$this->assertException("fileCorrupt", "Db");
|
$this->assertException("fileCorrupt", "Db");
|
||||||
new Db\SQLite3\Driver;
|
new Driver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class TestDbDriverSQLite3 extends Test\AbstractTest {
|
||||||
protected $ch;
|
protected $ch;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
if (!extension_loaded("sqlite3")) {
|
if (!Db\SQLite3\Driver::requirementsMet()) {
|
||||||
$this->markTestSkipped("SQLite extension not loaded");
|
$this->markTestSkipped("SQLite extension not loaded");
|
||||||
}
|
}
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
|
|
|
@ -11,7 +11,8 @@ class TestDbResultSQLite3 extends Test\AbstractTest {
|
||||||
protected $c;
|
protected $c;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
if (!extension_loaded("sqlite3")) {
|
$this->clearData();
|
||||||
|
if (!Db\SQLite3\Driver::requirementsMet()) {
|
||||||
$this->markTestSkipped("SQLite extension not loaded");
|
$this->markTestSkipped("SQLite extension not loaded");
|
||||||
}
|
}
|
||||||
$c = new \SQLite3(":memory:");
|
$c = new \SQLite3(":memory:");
|
||||||
|
@ -22,6 +23,7 @@ class TestDbResultSQLite3 extends Test\AbstractTest {
|
||||||
public function tearDown() {
|
public function tearDown() {
|
||||||
$this->c->close();
|
$this->c->close();
|
||||||
unset($this->c);
|
unset($this->c);
|
||||||
|
$this->clearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructResult() {
|
public function testConstructResult() {
|
||||||
|
|
|
@ -68,6 +68,12 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
|
||||||
$this->drv->schemaUpdate(1, $this->base);
|
$this->drv->schemaUpdate(1, $this->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLoadEmptyFile() {
|
||||||
|
file_put_contents($this->path."0.sql", "");
|
||||||
|
$this->assertException("updateFileIncomplete", "Db");
|
||||||
|
$this->drv->schemaUpdate(1, $this->base);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadCorrectFile() {
|
public function testLoadCorrectFile() {
|
||||||
file_put_contents($this->path."0.sql", self::MINIMAL1);
|
file_put_contents($this->path."0.sql", self::MINIMAL1);
|
||||||
$this->drv->schemaUpdate(1, $this->base);
|
$this->drv->schemaUpdate(1, $this->base);
|
||||||
|
@ -76,7 +82,7 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
|
||||||
|
|
||||||
public function testPerformPartialUpdate() {
|
public function testPerformPartialUpdate() {
|
||||||
file_put_contents($this->path."0.sql", self::MINIMAL1);
|
file_put_contents($this->path."0.sql", self::MINIMAL1);
|
||||||
file_put_contents($this->path."1.sql", "");
|
file_put_contents($this->path."1.sql", " ");
|
||||||
$this->assertException("updateFileIncomplete", "Db");
|
$this->assertException("updateFileIncomplete", "Db");
|
||||||
try {
|
try {
|
||||||
$this->drv->schemaUpdate(2, $this->base);
|
$this->drv->schemaUpdate(2, $this->base);
|
||||||
|
|
Loading…
Reference in a new issue