mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-23 06:44:57 +00:00
Add tests for transactions and savepoints
Existing code had subtle bugs; using increment and decrement operators actually makes things easier to understand (for once)
This commit is contained in:
parent
485400df2b
commit
f0663e99c3
2 changed files with 158 additions and 8 deletions
|
@ -15,16 +15,14 @@ abstract class AbstractDriver implements Driver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function begin(): bool {
|
public function begin(): bool {
|
||||||
$this->exec("SAVEPOINT newssync_".($this->transDepth));
|
$this->exec("SAVEPOINT newssync_".(++$this->transDepth));
|
||||||
$this->transDepth += 1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function commit(bool $all = false): bool {
|
public function commit(bool $all = false): bool {
|
||||||
if($this->transDepth==0) return false;
|
if($this->transDepth==0) return false;
|
||||||
if(!$all) {
|
if(!$all) {
|
||||||
$this->exec("RELEASE SAVEPOINT newssync_".($this->transDepth - 1));
|
$this->exec("RELEASE SAVEPOINT newssync_".($this->transDepth--));
|
||||||
$this->transDepth -= 1;
|
|
||||||
} else {
|
} else {
|
||||||
$this->exec("COMMIT TRANSACTION");
|
$this->exec("COMMIT TRANSACTION");
|
||||||
$this->transDepth = 0;
|
$this->transDepth = 0;
|
||||||
|
@ -35,11 +33,9 @@ abstract class AbstractDriver implements Driver {
|
||||||
public function rollback(bool $all = false): bool {
|
public function rollback(bool $all = false): bool {
|
||||||
if($this->transDepth==0) return false;
|
if($this->transDepth==0) return false;
|
||||||
if(!$all) {
|
if(!$all) {
|
||||||
$this->exec("ROLLBACK TRANSACTION TO SAVEPOINT newssync_".($this->transDepth - 1));
|
$this->exec("ROLLBACK TRANSACTION TO SAVEPOINT newssync_".($this->transDepth));
|
||||||
// rollback to savepoint does not collpase the savepoint
|
// rollback to savepoint does not collpase the savepoint
|
||||||
$this->commit();
|
$this->exec("RELEASE SAVEPOINT newssync_".($this->transDepth--));
|
||||||
$this->transDepth -= 1;
|
|
||||||
if($this->transDepth==0) $this->exec("ROLLBACK TRANSACTION");
|
|
||||||
} else {
|
} else {
|
||||||
$this->exec("ROLLBACK TRANSACTION");
|
$this->exec("ROLLBACK TRANSACTION");
|
||||||
$this->transDepth = 0;
|
$this->transDepth = 0;
|
||||||
|
|
|
@ -92,4 +92,158 @@ class TestDbDriverSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
$this->assertException("engineErrorGeneral", "Db");
|
$this->assertException("engineErrorGeneral", "Db");
|
||||||
$s = $this->drv->prepare("This is an invalid query", "int", "int");
|
$s = $this->drv->prepare("This is an invalid query", "int", "int");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testBeginTransaction() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCommitTransaction() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->commit();
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(1, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRollbackTransaction() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->rollback();
|
||||||
|
$this->assertEquals(0, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBeginChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCommitChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->commit();
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->commit();
|
||||||
|
$this->assertEquals(2, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRollbackChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->rollback();
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->rollback();
|
||||||
|
$this->assertEquals(0, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPartiallyRollbackChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->rollback();
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->commit();
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(1, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFullyRollbackChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->rollback(true);
|
||||||
|
$this->assertEquals(0, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFullyCommitChainedTransactions() {
|
||||||
|
$select = "SELECT count(*) FROM test";
|
||||||
|
$insert = "INSERT INTO test(id) values(null)";
|
||||||
|
$ch = new \SQLite3($this->data->conf->dbSQLite3File);
|
||||||
|
$this->drv->exec("CREATE TABLE test(id integer primary key)");
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(1, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->begin();
|
||||||
|
$this->drv->query($insert);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(0, $ch->querySingle($select));
|
||||||
|
$this->drv->commit(true);
|
||||||
|
$this->assertEquals(2, $this->drv->query($select)->getValue());
|
||||||
|
$this->assertEquals(2, $ch->querySingle($select));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue