3 namespace Friendica\Test\Util\Database;
9 * This class extends native PDO one but allow nested transactions
10 * by using the SQL statements `SAVEPOINT', 'RELEASE SAVEPOINT' AND 'ROLLBACK SAVEPOINT'
12 class ExtendedPDO extends PDO
15 * @var array Database drivers that support SAVEPOINT * statements.
17 protected static $_supportedDrivers = array("pgsql", "mysql");
20 * @var int the current transaction depth
22 protected $_transactionDepth = 0;
27 public function getTransactionDepth()
29 return $this->_transactionDepth;
33 * Test if database driver support savepoints
37 protected function hasSavepoint()
39 return in_array($this->getAttribute(PDO::ATTR_DRIVER_NAME),
40 self::$_supportedDrivers);
49 public function beginTransaction()
51 if($this->_transactionDepth == 0 || !$this->hasSavepoint()) {
52 parent::beginTransaction();
54 $this->exec("SAVEPOINT LEVEL{$this->_transactionDepth}");
57 $this->_transactionDepth++;
61 * Commit current transaction
65 public function commit()
67 $this->_transactionDepth--;
69 if($this->_transactionDepth == 0 || !$this->hasSavepoint()) {
72 $this->exec("RELEASE SAVEPOINT LEVEL{$this->_transactionDepth}");
77 * Rollback current transaction,
79 * @throws PDOException if there is no transaction started
82 public function rollBack()
85 if ($this->_transactionDepth == 0) {
86 throw new PDOException('Rollback error : There is no transaction started');
89 $this->_transactionDepth--;
91 if($this->_transactionDepth == 0 || !$this->hasSavepoint()) {
94 $this->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->_transactionDepth}");