From ea4b066df37ef4aa7cf068b2e74b11439026fae3 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 24 May 2021 20:30:56 +0200 Subject: [PATCH] Fix DBA::lock() testability because of "autocommits" --- tests/DatabaseTestTrait.php | 2 ++ tests/Util/Database/ExtendedPDO.php | 28 +++++++++--------- tests/Util/Database/StaticDatabase.php | 40 ++++++++++++++++++-------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/tests/DatabaseTestTrait.php b/tests/DatabaseTestTrait.php index 7d255c693..eae5ce2ac 100644 --- a/tests/DatabaseTestTrait.php +++ b/tests/DatabaseTestTrait.php @@ -34,6 +34,8 @@ trait DatabaseTestTrait StaticDatabase::statConnect($_SERVER); // Rollbacks every DB usage (in case the test couldn't call tearDown) StaticDatabase::statRollback(); + // Rollback the first, outer transaction just 2 be sure + StaticDatabase::getGlobConnection()->rollBack(); // Start the first, outer transaction StaticDatabase::getGlobConnection()->beginTransaction(); } diff --git a/tests/Util/Database/ExtendedPDO.php b/tests/Util/Database/ExtendedPDO.php index 6a59d2aee..c9ce42b3e 100644 --- a/tests/Util/Database/ExtendedPDO.php +++ b/tests/Util/Database/ExtendedPDO.php @@ -69,7 +69,7 @@ class ExtendedPDO extends PDO { if($this->_transactionDepth <= 0 || !$this->hasSavepoint()) { parent::beginTransaction(); - $this->_transactionDepth = $this->_transactionDepth < 0 ? 0 : $this->_transactionDepth; + $this->_transactionDepth = 0; } else { $this->exec("SAVEPOINT LEVEL{$this->_transactionDepth}"); } @@ -84,14 +84,15 @@ class ExtendedPDO extends PDO */ public function commit() { + // We don't want to "really" commit something, so skip the most outer hierarchy + if ($this->_transactionDepth <= 1 && $this->hasSavepoint()) { + $this->_transactionDepth = $this->_transactionDepth <= 0 ? 0 : 1; + return true; + } + $this->_transactionDepth--; - if($this->_transactionDepth <= 0 || !$this->hasSavepoint()) { - parent::commit(); - $this->_transactionDepth = $this->_transactionDepth < 0 ? 0 : $this->_transactionDepth; - } else { - $this->exec("RELEASE SAVEPOINT LEVEL{$this->_transactionDepth}"); - } + $this->exec("RELEASE SAVEPOINT LEVEL{$this->_transactionDepth}"); } /** @@ -102,14 +103,15 @@ class ExtendedPDO extends PDO */ public function rollBack() { - if ($this->_transactionDepth <= 0) { - throw new PDOException('Rollback error : There is no transaction started'); - } - $this->_transactionDepth--; - if($this->_transactionDepth == 0 || !$this->hasSavepoint()) { - parent::rollBack(); + if($this->_transactionDepth <= 0 || !$this->hasSavepoint()) { + $this->_transactionDepth = 0; + try { + parent::rollBack(); + } catch (PDOException $e) { + // this shouldn't happen, but it does ... + } } else { $this->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->_transactionDepth}"); } diff --git a/tests/Util/Database/StaticDatabase.php b/tests/Util/Database/StaticDatabase.php index 48b392978..3bf6396a9 100644 --- a/tests/Util/Database/StaticDatabase.php +++ b/tests/Util/Database/StaticDatabase.php @@ -39,6 +39,9 @@ class StaticDatabase extends Database */ private static $staticConnection; + /** @var bool */ + private $_locked = false; + /** * Override the behaviour of connect, due there is just one, static connection at all * @@ -77,6 +80,31 @@ class StaticDatabase extends Database return true; } + /** Mock for locking tables */ + public function lock($table) + { + if ($this->_locked) { + return false; + } + + $this->in_transaction = true; + $this->_locked = true; + + return true; + } + + /** Mock for unlocking tables */ + public function unlock() + { + // See here: https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html + $this->performCommit(); + + $this->in_transaction = false; + $this->_locked = false; + + return true; + } + /** * Does a commit * @@ -163,18 +191,6 @@ class StaticDatabase extends Database return self::$staticConnection; } - /** - * Perform a global commit for every nested transaction of the static connection - */ - public static function statCommit() - { - if (isset(self::$staticConnection)) { - while (self::$staticConnection->getTransactionDepth() > 0) { - self::$staticConnection->commit(); - } - } - } - /** * Perform a global rollback for every nested transaction of the static connection */