FIX correct handwritten logic for transactions to use new API instead

Code in the field alteration logic had a queries defiend as strings to
begin and commit transactions involve with changing table or column names.
This was causing fatal errors as BEGIN is not a valid keyword within
a trasaction (see SQLite documentation excerpt below).

A new api has been introduced to deal with transactions programmatically,
and this module was updated to support this a few months ago. This is a
tidy up of some missed portions - consuming this API which correctly uses
SAVEPOINT when a nested transaction is required automatically.

https://www.sqlite.org/lang_transaction.html
Transactions created using BEGIN...COMMIT do not nest. For nested
transactions, use the SAVEPOINT and RELEASE commands.
This commit is contained in:
NightjarNZ 2018-10-09 22:22:53 +13:00
parent 4167d9fd1a
commit 0efd40e5c2

View File

@ -275,21 +275,22 @@ class SQLite3SchemaManager extends DBSchemaManager
} }
$queries = array( $queries = array(
"BEGIN TRANSACTION",
"CREATE TABLE \"{$tableName}_alterfield_{$fieldName}\"(" . implode(',', $newColsSpec) . ")", "CREATE TABLE \"{$tableName}_alterfield_{$fieldName}\"(" . implode(',', $newColsSpec) . ")",
"INSERT INTO \"{$tableName}_alterfield_{$fieldName}\" SELECT {$fieldNameList} FROM \"$tableName\"", "INSERT INTO \"{$tableName}_alterfield_{$fieldName}\" SELECT {$fieldNameList} FROM \"$tableName\"",
"DROP TABLE \"$tableName\"", "DROP TABLE \"$tableName\"",
"ALTER TABLE \"{$tableName}_alterfield_{$fieldName}\" RENAME TO \"$tableName\"", "ALTER TABLE \"{$tableName}_alterfield_{$fieldName}\" RENAME TO \"$tableName\"",
"COMMIT"
); );
// Remember original indexes // Remember original indexes
$indexList = $this->indexList($tableName); $indexList = $this->indexList($tableName);
// Then alter the table column // Then alter the table column
$database = $this->database;
$database->withTransaction(function() use ($database, $queries, $indexList) {
foreach ($queries as $query) { foreach ($queries as $query) {
$this->query($query.';'); $database->query($query . ';');
} }
});
// Recreate the indexes // Recreate the indexes
foreach ($indexList as $indexName => $indexSpec) { foreach ($indexList as $indexName => $indexSpec) {
@ -318,21 +319,22 @@ class SQLite3SchemaManager extends DBSchemaManager
$oldColsStr = implode(',', $oldCols); $oldColsStr = implode(',', $oldCols);
$newColsSpecStr = implode(',', $newColsSpec); $newColsSpecStr = implode(',', $newColsSpec);
$queries = array( $queries = array(
"BEGIN TRANSACTION",
"CREATE TABLE \"{$tableName}_renamefield_{$oldName}\" ({$newColsSpecStr})", "CREATE TABLE \"{$tableName}_renamefield_{$oldName}\" ({$newColsSpecStr})",
"INSERT INTO \"{$tableName}_renamefield_{$oldName}\" SELECT {$oldColsStr} FROM \"$tableName\"", "INSERT INTO \"{$tableName}_renamefield_{$oldName}\" SELECT {$oldColsStr} FROM \"$tableName\"",
"DROP TABLE \"$tableName\"", "DROP TABLE \"$tableName\"",
"ALTER TABLE \"{$tableName}_renamefield_{$oldName}\" RENAME TO \"$tableName\"", "ALTER TABLE \"{$tableName}_renamefield_{$oldName}\" RENAME TO \"$tableName\"",
"COMMIT"
); );
// Remember original indexes // Remember original indexes
$oldIndexList = $this->indexList($tableName); $oldIndexList = $this->indexList($tableName);
// Then alter the table column // Then alter the table column
$database = $this->database;
$database->withTransaction(function() use ($database, $queries) {
foreach ($queries as $query) { foreach ($queries as $query) {
$this->query($query.';'); $database->query($query . ';');
} }
});
// Recreate the indexes // Recreate the indexes
foreach ($oldIndexList as $indexName => $indexSpec) { foreach ($oldIndexList as $indexName => $indexSpec) {