diff --git a/composer.json b/composer.json index aa4ac4a8..5f943d94 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,8 @@ }, "autoload-dev": { "psr-4": { - "JKingWeb\\Arsse\\Test\\": "tests/lib/" + "JKingWeb\\Arsse\\Test\\": "tests/lib/", + "JKingWeb\\Arsse\\TestCase\\": "tests/cases/" } } } diff --git a/tests/cases/Db/BaseDriver.php b/tests/cases/Db/BaseDriver.php new file mode 100644 index 00000000..4b6d68ab --- /dev/null +++ b/tests/cases/Db/BaseDriver.php @@ -0,0 +1,357 @@ + 0.5, + 'dbSQLite3Timeout' => 0, + ]; + + public function setUp() { + $this->setConf($this->conf); + $this->interface = $this->getDbInterface($this->implementation); + if (!$this->interface) { + $this->markTestSkipped("$this->implementation database driver not available"); + } + $this->drv = $this->getDbDriver($this->implementation); + $this->exec("DROP TABLE IF EXISTS arsse_test"); + $this->exec("DROP TABLE IF EXISTS arsse_meta"); + $this->exec("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)"); + $this->exec("INSERT INTO arsse_meta(key,value) values('schema_version','0')"); + } + + public function tearDown() { + unset($this->drv); + try { + $this->exec("ROLLBACK"); + } catch(\Throwable $e) { + } + $this->exec("DROP TABLE IF EXISTS arsse_meta"); + $this->exec("DROP TABLE IF EXISTS arsse_test"); + } + + protected function exec(string $q): bool { + // PDO implementation + $this->interface->exec($q); + return true; + } + + protected function query(string $q) { + // PDO implementation + return $this->interface->query($q)->fetchColumn(); + } + + # TESTS + + public function testFetchDriverName() { + $class = get_class($this->drv); + $this->assertTrue(strlen($class::driverName()) > 0); + } + + public function testCheckCharacterSetAcceptability() { + $this->assertTrue($this->drv->charsetAcceptable()); + } + + public function testExecAValidStatement() { + $this->assertTrue($this->drv->exec($this->create)); + } + + public function testExecAnInvalidStatement() { + $this->assertException("engineErrorGeneral", "Db"); + $this->drv->exec("And the meek shall inherit the earth..."); + } + + public function testExecMultipleStatements() { + $this->assertTrue($this->drv->exec("$this->create; INSERT INTO arsse_test(id) values(2112)")); + $this->assertEquals(2112, $this->query("SELECT id from arsse_test")); + } + + public function testExecTimeout() { + $this->exec($this->create); + $this->exec($this->lock); + $this->assertException("general", "Db", "ExceptionTimeout"); + $this->drv->exec($this->lock); + } + + public function testExecConstraintViolation() { + $this->drv->exec("CREATE TABLE arsse_test(id varchar(255) not null)"); + $this->assertException("constraintViolation", "Db", "ExceptionInput"); + $this->drv->exec("INSERT INTO arsse_test default values"); + } + + public function testExecTypeViolation() { + $this->drv->exec($this->create); + $this->assertException("typeViolation", "Db", "ExceptionInput"); + $this->drv->exec("INSERT INTO arsse_test(id) values('ook')"); + } + + public function testMakeAValidQuery() { + $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1")); + } + + public function testMakeAnInvalidQuery() { + $this->assertException("engineErrorGeneral", "Db"); + $this->drv->query("Apollo was astonished; Dionysus thought me mad"); + } + + public function testQueryTimeout() { + $this->exec($this->create); + $this->exec($this->lock); + $this->assertException("general", "Db", "ExceptionTimeout"); + $this->drv->exec($this->lock); + } + + public function testQueryConstraintViolation() { + $this->drv->exec("CREATE TABLE arsse_test(id integer not null)"); + $this->assertException("constraintViolation", "Db", "ExceptionInput"); + $this->drv->query("INSERT INTO arsse_test default values"); + } + + public function testQueryTypeViolation() { + $this->drv->exec($this->create); + $this->assertException("typeViolation", "Db", "ExceptionInput"); + $this->drv->query("INSERT INTO arsse_test(id) values('ook')"); + } + + public function testPrepareAValidQuery() { + $s = $this->drv->prepare("SELECT ?, ?", "int", "int"); + $this->assertInstanceOf(Statement::class, $s); + } + + public function testPrepareAnInvalidQuery() { + $this->assertException("engineErrorGeneral", "Db"); + $s = $this->drv->prepare("This is an invalid query", "int", "int")->run(); + } + + public function testCreateASavepoint() { + $this->assertEquals(1, $this->drv->savepointCreate()); + $this->assertEquals(2, $this->drv->savepointCreate()); + $this->assertEquals(3, $this->drv->savepointCreate()); + } + + public function testReleaseASavepoint() { + $this->assertEquals(1, $this->drv->savepointCreate()); + $this->assertEquals(true, $this->drv->savepointRelease()); + $this->assertException("savepointInvalid", "Db"); + $this->drv->savepointRelease(); + } + + public function testUndoASavepoint() { + $this->assertEquals(1, $this->drv->savepointCreate()); + $this->assertEquals(true, $this->drv->savepointUndo()); + $this->assertException("savepointInvalid", "Db"); + $this->drv->savepointUndo(); + } + + public function testManipulateSavepoints() { + $this->assertEquals(1, $this->drv->savepointCreate()); + $this->assertEquals(2, $this->drv->savepointCreate()); + $this->assertEquals(3, $this->drv->savepointCreate()); + $this->assertEquals(4, $this->drv->savepointCreate()); + $this->assertEquals(5, $this->drv->savepointCreate()); + $this->assertTrue($this->drv->savepointUndo(3)); + $this->assertFalse($this->drv->savepointRelease(4)); + $this->assertEquals(6, $this->drv->savepointCreate()); + $this->assertFalse($this->drv->savepointRelease(5)); + $this->assertTrue($this->drv->savepointRelease(6)); + $this->assertEquals(3, $this->drv->savepointCreate()); + $this->assertTrue($this->drv->savepointRelease(2)); + $this->assertException("savepointStale", "Db"); + $this->drv->savepointRelease(2); + } + + public function testManipulateSavepointsSomeMore() { + $this->assertEquals(1, $this->drv->savepointCreate()); + $this->assertEquals(2, $this->drv->savepointCreate()); + $this->assertEquals(3, $this->drv->savepointCreate()); + $this->assertEquals(4, $this->drv->savepointCreate()); + $this->assertTrue($this->drv->savepointRelease(2)); + $this->assertFalse($this->drv->savepointUndo(3)); + $this->assertException("savepointStale", "Db"); + $this->drv->savepointUndo(2); + } + + public function testBeginATransaction() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + } + + public function testCommitATransaction() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr->commit(); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(1, $this->query($select)); + } + + public function testRollbackATransaction() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr->rollback(); + $this->assertEquals(0, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + } + + public function testBeginChainedTransactions() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + } + + public function testCommitChainedTransactions() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2->commit(); + $this->assertEquals(0, $this->query($select)); + $tr1->commit(); + $this->assertEquals(2, $this->query($select)); + } + + public function testCommitChainedTransactionsOutOfOrder() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr1->commit(); + $this->assertEquals(2, $this->query($select)); + $tr2->commit(); + } + + public function testRollbackChainedTransactions() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2->rollback(); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr1->rollback(); + $this->assertEquals(0, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + } + + public function testRollbackChainedTransactionsOutOfOrder() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr1->rollback(); + $this->assertEquals(0, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2->rollback(); + $this->assertEquals(0, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + } + + public function testPartiallyRollbackChainedTransactions() { + $select = "SELECT count(*) FROM arsse_test"; + $insert = "INSERT INTO arsse_test default values"; + $this->drv->exec($this->create); + $tr1 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2 = $this->drv->begin(); + $this->drv->query($insert); + $this->assertEquals(2, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr2->rollback(); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(0, $this->query($select)); + $tr1->commit(); + $this->assertEquals(1, $this->drv->query($select)->getValue()); + $this->assertEquals(1, $this->query($select)); + } + + public function testFetchSchemaVersion() { + $this->assertSame(0, $this->drv->schemaVersion()); + $this->drv->exec(str_replace("#", "1", $this->setVersion)); + $this->assertSame(1, $this->drv->schemaVersion()); + $this->drv->exec(str_replace("#", "2", $this->setVersion)); + $this->assertSame(2, $this->drv->schemaVersion()); + } + + public function testLockTheDatabase() { + $this->drv->savepointCreate(true); + $this->assertException(); + $this->exec($this->create); + } + + public function testUnlockTheDatabase() { + $this->drv->savepointCreate(true); + $this->drv->savepointRelease(); + $this->drv->savepointCreate(true); + $this->drv->savepointUndo(); + $this->assertTrue($this->exec($this->create)); + } +} diff --git a/tests/cases/Db/SQLite3/TestDriver.php b/tests/cases/Db/SQLite3/TestDriver.php index 835ad095..3316a01a 100644 --- a/tests/cases/Db/SQLite3/TestDriver.php +++ b/tests/cases/Db/SQLite3/TestDriver.php @@ -6,338 +6,96 @@ declare(strict_types=1); namespace JKingWeb\Arsse\TestCase\Db\SQLite3; -use JKingWeb\Arsse\Arsse; -use JKingWeb\Arsse\Conf; -use JKingWeb\Arsse\Database; -use JKingWeb\Arsse\Db\SQLite3\Driver; -use JKingWeb\Arsse\Db\Result; -use JKingWeb\Arsse\Db\Statement; - /** * @covers \JKingWeb\Arsse\Db\SQLite3\Driver * @covers \JKingWeb\Arsse\Db\SQLite3\ExceptionBuilder */ -class TestDriver extends \JKingWeb\Arsse\Test\AbstractTest { - protected $data; - protected $drv; - protected $ch; +class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver { + protected $implementation = "SQLite 3"; + protected $create = "CREATE TABLE arsse_test(id integer primary key)"; + protected $lock = "BEGIN EXCLUSIVE TRANSACTION"; + protected $setVersion = "PRAGMA user_version=#"; + protected static $file; + public static function setUpBeforeClass() { + self::$file = tempnam(sys_get_temp_dir(), 'ook'); + } + + public static function tearDownAfterClass() { + @unlink(self::$file); + self::$file = null; + } + public function setUp() { - if (!Driver::requirementsMet()) { - $this->markTestSkipped("SQLite extension not loaded"); - } - $this->clearData(); - $this->setConf([ - 'dbDriver' => Driver::class, - 'dbSQLite3Timeout' => 0, - 'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'), - ]); - $this->drv = new Driver(); - $this->ch = new \SQLite3(Arsse::$conf->dbSQLite3File); - $this->ch->enableExceptions(true); + $this->conf['dbSQLite3File'] = self::$file; + parent::setUp(); + $this->exec("PRAGMA user_version=0"); } public function tearDown() { - unset($this->drv); - unset($this->ch); - if (isset(Arsse::$conf)) { - unlink(Arsse::$conf->dbSQLite3File); - } + parent::tearDown(); + $this->exec("PRAGMA user_version=0"); + $this->interface->close(); + unset($this->interface); + } + + protected function exec(string $q): bool { + $this->interface->exec($q); + return true; + } + + protected function query(string $q) { + return $this->interface->querySingle($q); + } + + public function provideDrivers() { $this->clearData(); - } - - public function testFetchDriverName() { - $class = Arsse::$conf->dbDriver; - $this->assertTrue(strlen($class::driverName()) > 0); - } - - public function testCheckCharacterSetAcceptability() { - $this->assertTrue($this->drv->charsetAcceptable()); - } - - public function testExecAValidStatement() { - $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key)")); - } - - public function testExecAnInvalidStatement() { - $this->assertException("engineErrorGeneral", "Db"); - $this->drv->exec("And the meek shall inherit the earth..."); - } - - public function testExecMultipleStatements() { - $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key); INSERT INTO test(id) values(2112)")); - $this->assertEquals(2112, $this->ch->querySingle("SELECT id from test")); - } - - public function testExecTimeout() { - $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION"); - $this->assertException("general", "Db", "ExceptionTimeout"); - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - } - - public function testExecConstraintViolation() { - $this->drv->exec("CREATE TABLE test(id integer not null)"); - $this->assertException("constraintViolation", "Db", "ExceptionInput"); - $this->drv->exec("INSERT INTO test(id) values(null)"); - } - - public function testExecTypeViolation() { - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $this->assertException("typeViolation", "Db", "ExceptionInput"); - $this->drv->exec("INSERT INTO test(id) values('ook')"); - } - - public function testMakeAValidQuery() { - $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1")); - } - - public function testMakeAnInvalidQuery() { - $this->assertException("engineErrorGeneral", "Db"); - $this->drv->query("Apollo was astonished; Dionysus thought me mad"); - } - - public function testQueryTimeout() { - $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION"); - $this->assertException("general", "Db", "ExceptionTimeout"); - $this->drv->query("CREATE TABLE test(id integer primary key)"); - } - - public function testQueryConstraintViolation() { - $this->drv->exec("CREATE TABLE test(id integer not null)"); - $this->assertException("constraintViolation", "Db", "ExceptionInput"); - $this->drv->query("INSERT INTO test(id) values(null)"); - } - - public function testQueryTypeViolation() { - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $this->assertException("typeViolation", "Db", "ExceptionInput"); - $this->drv->query("INSERT INTO test(id) values('ook')"); - } - - public function testPrepareAValidQuery() { - $s = $this->drv->prepare("SELECT ?, ?", "int", "int"); - $this->assertInstanceOf(Statement::class, $s); - } - - public function testPrepareAnInvalidQuery() { - $this->assertException("engineErrorGeneral", "Db"); - $s = $this->drv->prepare("This is an invalid query", "int", "int"); - } - - public function testCreateASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - } - - public function testReleaseASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(true, $this->drv->savepointRelease()); - $this->assertException("savepointInvalid", "Db"); - $this->drv->savepointRelease(); - } - - public function testUndoASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(true, $this->drv->savepointUndo()); - $this->assertException("savepointInvalid", "Db"); - $this->drv->savepointUndo(); - } - - public function testManipulateSavepoints() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertEquals(4, $this->drv->savepointCreate()); - $this->assertEquals(5, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointUndo(3)); - $this->assertFalse($this->drv->savepointRelease(4)); - $this->assertEquals(6, $this->drv->savepointCreate()); - $this->assertFalse($this->drv->savepointRelease(5)); - $this->assertTrue($this->drv->savepointRelease(6)); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointRelease(2)); - $this->assertException("savepointStale", "Db"); - $this->drv->savepointRelease(2); - } - - public function testManipulateSavepointsSomeMore() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertEquals(4, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointRelease(2)); - $this->assertFalse($this->drv->savepointUndo(3)); - $this->assertException("savepointStale", "Db"); - $this->drv->savepointUndo(2); - } - - public function testBeginATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - } - - public function testCommitATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr->commit(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(1, $this->ch->querySingle($select)); - } - - public function testRollbackATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - } - - public function testBeginChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - } - - public function testCommitChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2->commit(); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr1->commit(); - $this->assertEquals(2, $this->ch->querySingle($select)); - } - - public function testCommitChainedTransactionsOutOfOrder() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr1->commit(); - $this->assertEquals(2, $this->ch->querySingle($select)); - $tr2->commit(); - } - - public function testRollbackChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2->rollback(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr1->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - } - - public function testRollbackChainedTransactionsOutOfOrder() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr1->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - } - - public function testPartiallyRollbackChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr2->rollback(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->querySingle($select)); - $tr1->commit(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(1, $this->ch->querySingle($select)); - } - - public function testFetchSchemaVersion() { - $this->assertSame(0, $this->drv->schemaVersion()); - $this->drv->exec("PRAGMA user_version=1"); - $this->assertSame(1, $this->drv->schemaVersion()); - $this->drv->exec("PRAGMA user_version=2"); - $this->assertSame(2, $this->drv->schemaVersion()); - } - - public function testLockTheDatabase() { - $this->drv->savepointCreate(true); - $this->assertException(); - $this->ch->exec("CREATE TABLE test(id integer primary key)"); - } - - public function testUnlockTheDatabase() { - $this->drv->savepointCreate(true); - $this->drv->savepointRelease(); - $this->drv->savepointCreate(true); - $this->drv->savepointUndo(); - $this->assertSame(true, $this->ch->exec("CREATE TABLE test(id integer primary key)")); + $this->setConf([ + 'dbTimeoutExec' => 0.5, + 'dbSQLite3Timeout' => 0, + 'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'), + ]); + $i = $this->provideDbInterfaces(); + $d = $this->provideDbDrivers(); + $pdoExec = function (string $q) { + $this->interface->exec($q); + return true; + }; + $pdoQuery = function (string $q) { + return $this->interface->query($q)->fetchColumn(); + }; + return [ + 'SQLite 3' => [ + $i['SQLite 3']['interface'], + $d['SQLite 3'], + "CREATE TABLE arsse_test(id integer primary key)", + "BEGIN EXCLUSIVE TRANSACTION", + "PRAGMA user_version=#", + function (string $q) { + $this->interface->exec($q); + return true; + }, + function (string $q) { + return $this->interface->querySingle($q); + }, + ], + 'PDO SQLite 3' => [ + $i['PDO SQLite 3']['interface'], + $d['PDO SQLite 3'], + "CREATE TABLE arsse_test(id integer primary key)", + "BEGIN EXCLUSIVE TRANSACTION", + "PRAGMA user_version=#", + $pdoExec, + $pdoQuery, + ], + 'PDO PostgreSQL' => [ + $i['PDO PostgreSQL']['interface'], + $d['PDO PostgreSQL'], + "CREATE TABLE arsse_test(id bigserial primary key)", + "BEGIN; LOCK TABLE arsse_test IN EXCLUSIVE MODE NOWAIT", + "UPDATE arsse_meta set value = '#' where key = 'schema_version'", + $pdoExec, + $pdoQuery, + ], + ]; } } diff --git a/tests/cases/Db/SQLite3PDO/TestDriver.php b/tests/cases/Db/SQLite3PDO/TestDriver.php index 6d58f51b..73ae773e 100644 --- a/tests/cases/Db/SQLite3PDO/TestDriver.php +++ b/tests/cases/Db/SQLite3PDO/TestDriver.php @@ -6,339 +6,35 @@ declare(strict_types=1); namespace JKingWeb\Arsse\TestCase\Db\SQLite3PDO; -use JKingWeb\Arsse\Arsse; -use JKingWeb\Arsse\Conf; -use JKingWeb\Arsse\Database; -use JKingWeb\Arsse\Db\SQLite3\PDODriver; -use JKingWeb\Arsse\Db\Result; -use JKingWeb\Arsse\Db\Statement; - /** * @covers \JKingWeb\Arsse\Db\SQLite3\PDODriver * @covers \JKingWeb\Arsse\Db\PDODriver * @covers \JKingWeb\Arsse\Db\PDOError */ -class TestDriver extends \JKingWeb\Arsse\Test\AbstractTest { - protected $data; - protected $drv; - protected $ch; +class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver { + protected $implementation = "PDO SQLite 3"; + protected $create = "CREATE TABLE arsse_test(id integer primary key)"; + protected $lock = "BEGIN EXCLUSIVE TRANSACTION"; + protected $setVersion = "PRAGMA user_version=#"; + protected static $file; + public static function setUpBeforeClass() { + self::$file = tempnam(sys_get_temp_dir(), 'ook'); + } + + public static function tearDownAfterClass() { + @unlink(self::$file); + self::$file = null; + } + public function setUp() { - if (!PDODriver::requirementsMet()) { - $this->markTestSkipped("PDO-SQLite extension not loaded"); - } - $this->clearData(); - $this->setConf([ - 'dbDriver' => PDODriver::class, - 'dbSQLite3Timeout' => 0, - 'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'), - ]); - $this->drv = new PDODriver(); - $this->ch = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]); + $this->conf['dbSQLite3File'] = self::$file; + parent::setUp(); + $this->exec("PRAGMA user_version=0"); } public function tearDown() { - unset($this->drv); - unset($this->ch); - if (isset(Arsse::$conf)) { - unlink(Arsse::$conf->dbSQLite3File); - } - $this->clearData(); - } - - public function testFetchDriverName() { - $class = Arsse::$conf->dbDriver; - $this->assertTrue(strlen($class::driverName()) > 0); - } - - public function testCheckCharacterSetAcceptability() { - $this->assertTrue($this->drv->charsetAcceptable()); - } - - public function testExecAValidStatement() { - $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key)")); - } - - public function testExecAnInvalidStatement() { - $this->assertException("engineErrorGeneral", "Db"); - $this->drv->exec("And the meek shall inherit the earth..."); - } - - public function testExecMultipleStatements() { - $this->assertTrue($this->drv->exec("CREATE TABLE test(id integer primary key); INSERT INTO test(id) values(2112)")); - $this->assertEquals(2112, $this->ch->query("SELECT id from test")->fetchColumn()); - } - - public function testExecTimeout() { - $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION"); - $this->assertException("general", "Db", "ExceptionTimeout"); - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - } - - public function testExecConstraintViolation() { - $this->drv->exec("CREATE TABLE test(id integer not null)"); - $this->assertException("constraintViolation", "Db", "ExceptionInput"); - $this->drv->exec("INSERT INTO test(id) values(null)"); - } - - public function testExecTypeViolation() { - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $this->assertException("typeViolation", "Db", "ExceptionInput"); - $this->drv->exec("INSERT INTO test(id) values('ook')"); - } - - public function testMakeAValidQuery() { - $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1")); - } - - public function testMakeAnInvalidQuery() { - $this->assertException("engineErrorGeneral", "Db"); - $this->drv->query("Apollo was astonished; Dionysus thought me mad"); - } - - public function testQueryTimeout() { - $this->ch->exec("BEGIN EXCLUSIVE TRANSACTION"); - $this->assertException("general", "Db", "ExceptionTimeout"); - $this->drv->query("CREATE TABLE test(id integer primary key)"); - } - - public function testQueryConstraintViolation() { - $this->drv->exec("CREATE TABLE test(id integer not null)"); - $this->assertException("constraintViolation", "Db", "ExceptionInput"); - $this->drv->query("INSERT INTO test(id) values(null)"); - } - - public function testQueryTypeViolation() { - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $this->assertException("typeViolation", "Db", "ExceptionInput"); - $this->drv->query("INSERT INTO test(id) values('ook')"); - } - - public function testPrepareAValidQuery() { - $s = $this->drv->prepare("SELECT ?, ?", "int", "int"); - $this->assertInstanceOf(Statement::class, $s); - } - - public function testPrepareAnInvalidQuery() { - $this->assertException("engineErrorGeneral", "Db"); - $s = $this->drv->prepare("This is an invalid query", "int", "int"); - } - - public function testCreateASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - } - - public function testReleaseASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(true, $this->drv->savepointRelease()); - $this->assertException("savepointInvalid", "Db"); - $this->drv->savepointRelease(); - } - - public function testUndoASavepoint() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(true, $this->drv->savepointUndo()); - $this->assertException("savepointInvalid", "Db"); - $this->drv->savepointUndo(); - } - - public function testManipulateSavepoints() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertEquals(4, $this->drv->savepointCreate()); - $this->assertEquals(5, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointUndo(3)); - $this->assertFalse($this->drv->savepointRelease(4)); - $this->assertEquals(6, $this->drv->savepointCreate()); - $this->assertFalse($this->drv->savepointRelease(5)); - $this->assertTrue($this->drv->savepointRelease(6)); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointRelease(2)); - $this->assertException("savepointStale", "Db"); - $this->drv->savepointRelease(2); - } - - public function testManipulateSavepointsSomeMore() { - $this->assertEquals(1, $this->drv->savepointCreate()); - $this->assertEquals(2, $this->drv->savepointCreate()); - $this->assertEquals(3, $this->drv->savepointCreate()); - $this->assertEquals(4, $this->drv->savepointCreate()); - $this->assertTrue($this->drv->savepointRelease(2)); - $this->assertFalse($this->drv->savepointUndo(3)); - $this->assertException("savepointStale", "Db"); - $this->drv->savepointUndo(2); - } - - public function testBeginATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - } - - public function testCommitATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr->commit(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(1, $this->ch->query($select)->fetchColumn()); - } - - public function testRollbackATransaction() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - } - - public function testBeginChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - } - - public function testCommitChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2->commit(); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr1->commit(); - $this->assertEquals(2, $this->ch->query($select)->fetchColumn()); - } - - public function testCommitChainedTransactionsOutOfOrder() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr1->commit(); - $this->assertEquals(2, $this->ch->query($select)->fetchColumn()); - $tr2->commit(); - } - - public function testRollbackChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2->rollback(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr1->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - } - - public function testRollbackChainedTransactionsOutOfOrder() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr1->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2->rollback(); - $this->assertEquals(0, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - } - - public function testPartiallyRollbackChainedTransactions() { - $select = "SELECT count(*) FROM test"; - $insert = "INSERT INTO test(id) values(null)"; - $this->drv->exec("CREATE TABLE test(id integer primary key)"); - $tr1 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2 = $this->drv->begin(); - $this->drv->query($insert); - $this->assertEquals(2, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr2->rollback(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(0, $this->ch->query($select)->fetchColumn()); - $tr1->commit(); - $this->assertEquals(1, $this->drv->query($select)->getValue()); - $this->assertEquals(1, $this->ch->query($select)->fetchColumn()); - } - - public function testFetchSchemaVersion() { - $this->assertSame(0, $this->drv->schemaVersion()); - $this->drv->exec("PRAGMA user_version=1"); - $this->assertSame(1, $this->drv->schemaVersion()); - $this->drv->exec("PRAGMA user_version=2"); - $this->assertSame(2, $this->drv->schemaVersion()); - } - - public function testLockTheDatabase() { - $this->drv->savepointCreate(true); - $this->ch->exec("PRAGMA busy_timeout = 0"); - $this->assertException(); - $this->ch->exec("CREATE TABLE test(id integer primary key)"); - } - - public function testUnlockTheDatabase() { - $this->drv->savepointCreate(true); - $this->drv->savepointRelease(); - $this->drv->savepointCreate(true); - $this->drv->savepointUndo(); - $this->assertSame(0, $this->ch->exec("CREATE TABLE test(id integer primary key)")); + parent::tearDown(); + $this->exec("PRAGMA user_version=0"); + unset($this->interface); } } diff --git a/tests/lib/AbstractTest.php b/tests/lib/AbstractTest.php index 750c6b0c..e4930f04 100644 --- a/tests/lib/AbstractTest.php +++ b/tests/lib/AbstractTest.php @@ -43,11 +43,12 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase { public function setConf(array $conf = []) { $defaults = [ 'dbSQLite3File' => ":memory:", + 'dbSQLite3Timeout' => 0, 'dbPostgreSQLUser' => "arsse_test", 'dbPostgreSQLPass' => "arsse_test", 'dbPostgreSQLDb' => "arsse_test", ]; - Arsse::$conf = (new Conf)->import($defaults)->import($conf); + Arsse::$conf = Arsse::$conf ?? (new Conf)->import($defaults)->import($conf); } public function assertException(string $msg = "", string $prefix = "", string $type = "Exception") { @@ -126,6 +127,33 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase { return $value; } + public function provideDbDrivers(array $conf = []): array { + $this->setConf($conf); + return [ + 'SQLite 3' => (function() { + try { + return new \JKingWeb\Arsse\Db\SQLite3\Driver; + } catch (\Exception $e) { + return; + } + })(), + 'PDO SQLite 3' => (function() { + try { + return new \JKingWeb\Arsse\Db\SQLite3\PDODriver; + } catch (\Exception $e) { + return; + } + })(), + 'PDO PostgreSQL' => (function() { + try { + return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver; + } catch (\Exception $e) { + return; + } + })(), + ]; + } + public function provideDbInterfaces(array $conf = []): array { $this->setConf($conf); return [ @@ -180,4 +208,83 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase { ], ]; } + + public function getDbDriver(string $name, array $conf = []) { + $this->setConf($conf); + switch ($name) { + case 'SQLite 3': + return (function() { + try { + return new \JKingWeb\Arsse\Db\SQLite3\Driver; + } catch (\Exception $e) { + return; + } + })(); + case 'PDO SQLite 3': + return (function() { + try { + return new \JKingWeb\Arsse\Db\SQLite3\PDODriver; + } catch (\Exception $e) { + return; + } + })(); + case 'PDO PostgreSQL': + return (function() { + try { + return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver; + } catch (\Exception $e) { + return; + } + })(); + default: + throw new \Exception("Invalid database driver name"); + } + } + + public function getDbInterface(string $name, array $conf = []) { + $this->setConf($conf); + switch ($name) { + case 'SQLite 3': + return (function() { + if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) { + try { + $d = new \SQLite3(Arsse::$conf->dbSQLite3File); + } catch (\Exception $e) { + return; + } + $d->enableExceptions(true); + return $d; + } + })(); + case 'PDO SQLite 3': + return (function() { + if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) { + try { + $d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]); + $d->exec("PRAGMA busy_timeout=0"); + return $d; + } catch (\PDOException $e) { + return; + } + } + })(); + case 'PDO PostgreSQL': + return (function() { + if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) { + $connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, ""); + try { + $c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]); + } catch (\PDOException $e) { + return; + } + foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) { + $c->exec($q); + } + return $c; + } + })(); + default: + throw new \Exception("Invalid database driver name"); + } + } } diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 67914ae7..faf634e7 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -57,6 +57,7 @@ cases/Db/SQLite3PDO/TestUpdate.php cases/Db/PostgreSQL/TestCreation.php + cases/Db/PostgreSQL/TestDriver.php cases/Db/SQLite3/Database/TestMiscellany.php