Allow setting PRAGMAs from the Execute SQL tab

As per popular request, this adds support for setting PRAGMAs from the
Execute SQL tab. Since most PRAGMAs won't work inside a transaction we
make sure that we're not in one while the PRAGMA statement is executed.
If this means we need to commit any pending changes, the user get a
message box.

See issues #1021, #980, #966.
This commit is contained in:
Martin Kleusberg
2017-06-30 21:59:47 +02:00
parent c6deca1242
commit 26ddcf2c04

View File

@@ -948,17 +948,12 @@ void MainWindow::executeQuery()
bool modified = false;
bool wasdirty = db.getDirty();
bool structure_updated = false;
// there is no choice, we have to start a transaction before
// we create the prepared statement, otherwise every executed
// statement will get committed after the prepared statement
// gets finalized, see http://www.sqlite.org/lang_transaction.html
db.setSavepoint();
bool savepoint_created = false;
// Remove any error indicators
sqlWidget->getEditor()->clearErrorIndicators();
//Accept multi-line queries, by looping until the tail is empty
// Accept multi-line queries, by looping until the tail is empty
QElapsedTimer timer;
timer.start();
while( tail && *tail != 0 && (sql3status == SQLITE_OK || sql3status == SQLITE_DONE))
@@ -971,6 +966,41 @@ void MainWindow::executeQuery()
qtail.startsWith("ROLLBACK", Qt::CaseInsensitive)))
structure_updated = true;
// Check whether this is trying to set a pragma
if(qtail.startsWith("PRAGMA", Qt::CaseInsensitive) && qtail.contains('='))
{
// We're trying to set a pragma. If the database has been modified it needs to be committed first. We'll need to ask the
// user about that
if(db.getDirty())
{
if(QMessageBox::question(this,
QApplication::applicationName(),
tr("Setting PRAGMA values will commit your current transaction.\nAre you sure?"),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape) == QMessageBox::Yes)
{
// Commit all changes
db.releaseAllSavepoints();
} else {
// Abort
statusMessage = tr("Execution aborted by user");
break;
}
}
} else {
// We're not trying to set a pragma. In this case make sure a savepoint has been created in order to avoid committing
// all changes to the database immediately. Don't set more than one savepoint.
if(!savepoint_created)
{
// there is no choice, we have to start a transaction before we create the prepared statement,
// otherwise every executed statement will get committed after the prepared statement gets finalized,
// see http://www.sqlite.org/lang_transaction.html
db.setSavepoint();
savepoint_created = true;
}
}
// Execute next statement
int tail_length_before = tail_length;
const char* qbegin = tail;
@@ -1054,7 +1084,7 @@ void MainWindow::executeQuery()
connect(sqlWidget->getTableResult(), &ExtendedTableWidget::activated, this, &MainWindow::dataTableSelectionChanged);
connect(sqlWidget->getTableResult(), SIGNAL(doubleClicked(QModelIndex)), this, SLOT(doubleClickTable(QModelIndex)));
if(!modified && !wasdirty)
if(!modified && !wasdirty && savepoint_created)
db.revertToSavepoint(); // better rollback, if the logic is not enough we can tune it.
// If the DB structure was changed by some command in this SQL script, update our schema representations