mirror of
https://github.com/silverstripe/silverstripe-sqlite3
synced 2024-10-22 17:05:37 +02:00
FIX correct nesting level mismatches causing errors
Transactions that used more than one level would cause errors if there were consecutive calls to start a transaction - because each query executed would clear the flag indicating that a transaction was already in progress. The comment for the logic to reset the nesting level on a query was indicating that DDL (data definition language) would not work within a transaction. This is untrue, and the module itself uses a transaction to alter table or field names. So this function has been converted to a no-op, deprecated to be removed in version 3 of this module. It is also no longer called upon each query. There have been some maintenance tidyups around this area also by abstracting the nested transaction flag manipulations into protected functions.
This commit is contained in:
parent
0efd40e5c2
commit
62ef14f711
@ -470,12 +470,12 @@ class SQLite3Database extends Database
|
|||||||
|
|
||||||
public function transactionStart($transaction_mode = false, $session_characteristics = false)
|
public function transactionStart($transaction_mode = false, $session_characteristics = false)
|
||||||
{
|
{
|
||||||
if ($this->transactionNesting > 0) {
|
if ($this->transactionDepth()) {
|
||||||
$this->transactionSavepoint('NESTEDTRANSACTION' . $this->transactionNesting);
|
$this->transactionSavepoint($this->getTransactionSavepointName());
|
||||||
} else {
|
} else {
|
||||||
$this->query('BEGIN');
|
$this->query('BEGIN');
|
||||||
}
|
}
|
||||||
++$this->transactionNesting;
|
$this->transactionDepthIncrease();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transactionSavepoint($savepoint)
|
public function transactionSavepoint($savepoint)
|
||||||
@ -483,6 +483,18 @@ class SQLite3Database extends Database
|
|||||||
$this->query("SAVEPOINT \"$savepoint\"");
|
$this->query("SAVEPOINT \"$savepoint\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the name of the current savepoint
|
||||||
|
* {@see transactionDepth} should be greater than zero
|
||||||
|
* or the name will be invalid (because there are none).
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getTransactionSavepointName()
|
||||||
|
{
|
||||||
|
return 'NESTEDTRANSACTION' . $this->transactionDepth();
|
||||||
|
}
|
||||||
|
|
||||||
public function transactionRollback($savepoint = false)
|
public function transactionRollback($savepoint = false)
|
||||||
{
|
{
|
||||||
// Named transaction
|
// Named transaction
|
||||||
@ -492,13 +504,13 @@ class SQLite3Database extends Database
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fail if transaction isn't available
|
// Fail if transaction isn't available
|
||||||
if (!$this->transactionNesting) {
|
if (!$this->transactionDepth()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
--$this->transactionNesting;
|
$this->transactionDepthDecrease();
|
||||||
if ($this->transactionNesting > 0) {
|
if ($this->transactionDepth()) {
|
||||||
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
|
$this->transactionRollback($this->getTransactionSavepointName());
|
||||||
} else {
|
} else {
|
||||||
$this->query('ROLLBACK;');
|
$this->query('ROLLBACK;');
|
||||||
}
|
}
|
||||||
@ -513,17 +525,30 @@ class SQLite3Database extends Database
|
|||||||
public function transactionEnd($chain = false)
|
public function transactionEnd($chain = false)
|
||||||
{
|
{
|
||||||
// Fail if transaction isn't available
|
// Fail if transaction isn't available
|
||||||
if (!$this->transactionNesting) {
|
if (!$this->transactionDepth()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
--$this->transactionNesting;
|
$this->query('COMMIT;');
|
||||||
if ($this->transactionNesting <= 0) {
|
$this->transactionDepthDecrease();
|
||||||
$this->transactionNesting = 0;
|
|
||||||
$this->query('COMMIT;');
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the nested transaction level by one
|
||||||
|
*/
|
||||||
|
protected function transactionDepthIncrease()
|
||||||
|
{
|
||||||
|
++$this->transactionNesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease the nested transaction level by one
|
||||||
|
*/
|
||||||
|
protected function transactionDepthDecrease()
|
||||||
|
{
|
||||||
|
--$this->transactionNesting;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In error condition, set transactionNesting to zero
|
* In error condition, set transactionNesting to zero
|
||||||
*/
|
*/
|
||||||
@ -534,28 +559,22 @@ class SQLite3Database extends Database
|
|||||||
|
|
||||||
public function query($sql, $errorLevel = E_USER_ERROR)
|
public function query($sql, $errorLevel = E_USER_ERROR)
|
||||||
{
|
{
|
||||||
$this->inspectQuery($sql);
|
|
||||||
return parent::query($sql, $errorLevel);
|
return parent::query($sql, $errorLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
|
public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
|
||||||
{
|
{
|
||||||
$this->inspectQuery($sql);
|
|
||||||
return parent::preparedQuery($sql, $parameters, $errorLevel);
|
return parent::preparedQuery($sql, $parameters, $errorLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inspect a SQL query prior to execution
|
* Inspect a SQL query prior to execution
|
||||||
*
|
* @deprecated 2..3
|
||||||
* @param string $sql
|
* @param string $sql
|
||||||
*/
|
*/
|
||||||
protected function inspectQuery($sql)
|
protected function inspectQuery($sql)
|
||||||
{
|
{
|
||||||
// Any DDL discards transactions.
|
// no-op
|
||||||
$isDDL = $this->getConnector()->isQueryDDL($sql);
|
|
||||||
if ($isDDL) {
|
|
||||||
$this->resetTransactionNesting();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearTable($table)
|
public function clearTable($table)
|
||||||
|
Loading…
Reference in New Issue
Block a user