Skip to content

Commit

Permalink
Fix transaction detection in SQL import
Browse files Browse the repository at this point in the history
Fix a couple of problems in the detection of transaction statements
during the SQL import. Before this the detection was case-dependent as
well as dependent on the number of spaces you use. Also it did not
detect 'END TRANSACTION', 'COMMIT TRANSACTION', or 'BEGIN <qualifier>
TRANSACTION' at all. Finally, it could modify your statements if you
embed string in them which look like transaction statements. All of this
is, hopefully, fixed in this commit.

See issue sqlitebrowser#1764.
  • Loading branch information
MKleusberg committed Feb 25, 2019
1 parent e436cb2 commit 0f6946c
Showing 1 changed file with 20 additions and 22 deletions.
42 changes: 20 additions & 22 deletions src/sqlitedb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,32 +951,10 @@ bool DBBrowserDB::executeMultiSQL(QByteArray query, bool dirty, bool log)
return false;
}

// Check if this SQL containts any transaction statements. If so remove them and create a savepoint instead by overriding the dirty parameter.
// TODO This should check for 'END TRANSACTION' too. It should be case insensitive and it should work with any amounts of whitespace etc. "Good" news
// is that none of this was ever done correctly before.
if(query.contains("BEGIN TRANSACTION;"))
{
query.replace("BEGIN TRANSACTION;", " ");
dirty = true;
}
if(query.contains("COMMIT;"))
{
query.replace("COMMIT;", " ");
dirty = true;
}

// Log the statement if needed
if(log)
logSQL(query, kLogMsg_App);

// Set DB to dirty/create restore point if necessary
QString savepoint_name;
if(dirty)
{
savepoint_name = generateSavepointName("execmultisql");
setSavepoint(savepoint_name);
}

// Show progress dialog
QProgressDialog progress(tr("Executing SQL..."),
tr("Cancel"), 0, 100);
Expand All @@ -993,6 +971,7 @@ bool DBBrowserDB::executeMultiSQL(QByteArray query, bool dirty, bool log)
unsigned int line = 0;
bool structure_updated = false;
int last_progress_value = -1;
QString savepoint_name;
while(tail && *tail != 0 && (res == SQLITE_OK || res == SQLITE_DONE))
{
line++;
Expand Down Expand Up @@ -1031,6 +1010,25 @@ bool DBBrowserDB::executeMultiSQL(QByteArray query, bool dirty, bool log)
next_statement.compare(0, 4, "DROP") == 0 ||
next_statement.compare(0, 8, "ROLLBACK") == 0)
structure_updated = true;

// Check for transaction statements and skip until the next semicolon
if(next_statement.compare(0, 5, "COMMIT") == 0 ||
next_statement.compare(0, 4, "END ") == 0 ||
next_statement.compare(0, 6, "BEGIN ") == 0)
{
while(tail != tail_end)
{
if(*++tail == ';')
break;
}

// Set DB to dirty and create a restore point if we haven't done that yet
if(dirty && savepoint_name.isNull())
{
savepoint_name = generateSavepointName("execmultisql");
setSavepoint(savepoint_name);
}
}
}

// Execute next statement
Expand Down

0 comments on commit 0f6946c

Please sign in to comment.