Skip to content

Commit

Permalink
Better error handling in import CSV dialog
Browse files Browse the repository at this point in the history
Make sure to show the correct error message when there is an error
during CSV import.

Make sure to release the DB handle used for the import before rolling
back to the last savepoint in case of an error in the CSV import. This
avoids a deadlock situation.

See issue #1590.
  • Loading branch information
MKleusberg committed Oct 23, 2018
1 parent 5ec03ba commit f11b1a0
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/ImportCsvDialog.cpp
Expand Up @@ -100,10 +100,15 @@ namespace {
void rollback(
ImportCsvDialog* dialog,
DBBrowserDB* pdb,
DBBrowserDB::db_pointer_type* db_ptr,
const QString& savepointName,
size_t nRecord,
const QString& message)
{
// Release DB handle. This needs to be done before calling revertToSavepoint as that function needs to be able to acquire its own handle.
if(db_ptr)
*db_ptr = nullptr;

QApplication::restoreOverrideCursor(); // restore original cursor
if(!message.isEmpty())
{
Expand Down Expand Up @@ -533,7 +538,7 @@ bool ImportCsvDialog::importCsv(const QString& fileName, const QString& name)
QString restorepointName = pdb->generateSavepointName("csvimport");
if(!pdb->setSavepoint(restorepointName))
{
rollback(this, pdb, restorepointName, 0, tr("Creating restore point failed: %1").arg(pdb->lastError()));
rollback(this, pdb, nullptr, restorepointName, 0, tr("Creating restore point failed: %1").arg(pdb->lastError()));
return false;
}

Expand All @@ -546,7 +551,7 @@ bool ImportCsvDialog::importCsv(const QString& fileName, const QString& name)
{
if(!pdb->createTable(sqlb::ObjectIdentifier("main", tableName), fieldList))
{
rollback(this, pdb, restorepointName, 0, tr("Creating the table failed: %1").arg(pdb->lastError()));
rollback(this, pdb, nullptr, restorepointName, 0, tr("Creating the table failed: %1").arg(pdb->lastError()));
return false;
}

Expand Down Expand Up @@ -672,13 +677,15 @@ bool ImportCsvDialog::importCsv(const QString& fileName, const QString& name)
// Some error occurred or the user cancelled the action

// Rollback the entire import. If the action was cancelled, don't show an error message. If it errored, show an error message.
sqlite3_finalize(stmt);
if(result == CSVParser::ParserResult::ParserResultCancelled)
{
rollback(this, pdb, restorepointName, 0, QString());
sqlite3_finalize(stmt);
rollback(this, pdb, &pDb, restorepointName, 0, QString());
return false;
} else {
rollback(this, pdb, restorepointName, lastRowNum, tr("Inserting row failed: %1").arg(pdb->lastError()));
QString error(sqlite3_errmsg(pDb.get()));
sqlite3_finalize(stmt);
rollback(this, pdb, &pDb, restorepointName, lastRowNum, tr("Inserting row failed: %1").arg(error));
return false;
}
}
Expand Down

0 comments on commit f11b1a0

Please sign in to comment.