From 17369b66a62f748aba6106ce59554096dec38667 Mon Sep 17 00:00:00 2001 From: Oleg Prutz Date: Fri, 25 Nov 2016 12:44:47 +0300 Subject: [PATCH] Fix hanging when deleting large number of records (#856) (#870) --- .travis.yml | 4 ++-- src/MainWindow.cpp | 7 +++++-- src/sqlitedb.cpp | 11 ++++++++--- src/sqlitedb.h | 2 +- src/sqlitetablemodel.cpp | 15 ++++++++------- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index cac83a05..6b99b8fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,8 @@ before_install: - sudo add-apt-repository ppa:likemartinma/devel -y - sudo add-apt-repository --yes ppa:beineri/opt-qt57-trusty - sudo apt-get update -qq - - sudo apt-get --force-yes install -qq qt57-meta-full - - sudo apt-get --force-yes install -qq libsqlite3-dev libsqlcipher-dev libantlr-dev + - sudo apt-get --force-yes install qt57-meta-full + - sudo apt-get --force-yes install libsqlite3-dev libsqlcipher-dev libantlr-dev - QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh') - source $QT_ENV_SCRIPT diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index a58b7482..bfc9b1d3 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -585,8 +585,11 @@ void MainWindow::deleteRecord() int old_row = ui->dataTable->currentIndex().row(); while(ui->dataTable->selectionModel()->hasSelection()) - { - if(!m_browseTableModel->removeRow(ui->dataTable->selectionModel()->selectedIndexes().first().row())) + { + int first_selected_row = ui->dataTable->selectionModel()->selectedIndexes().first().row(); + int last_selected_row = ui->dataTable->selectionModel()->selectedIndexes().last().row(); + int selected_rows_count = last_selected_row - first_selected_row + 1; + if(!m_browseTableModel->removeRows(first_selected_row, selected_rows_count)) { QMessageBox::warning(this, QApplication::applicationName(), tr("Error deleting record:\n%1").arg(db.lastErrorMessage)); break; diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index 7203eb75..ce3c24b5 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -865,15 +865,20 @@ QString DBBrowserDB::addRecord(const QString& sTableName) } } -bool DBBrowserDB::deleteRecord(const QString& table, const QString& rowid) +bool DBBrowserDB::deleteRecords(const QString& table, const QStringList& rowids) { if (!isOpen()) return false; bool ok = false; - QString statement = QString("DELETE FROM %1 WHERE %2='%3';") + QStringList quoted_rowids; + foreach(QString rowid, rowids) + { + quoted_rowids.append("'" + rowid + "'"); + } + QString statement = QString("DELETE FROM %1 WHERE %2 IN (%3);") .arg(sqlb::escapeIdentifier(table)) .arg(sqlb::escapeIdentifier(getObjectByName(table).table.rowidColumn())) - .arg(rowid); + .arg(quoted_rowids.join(", ")); if(executeSQL(statement)) ok = true; else diff --git a/src/sqlitedb.h b/src/sqlitedb.h index ac612948..ee5f6717 100644 --- a/src/sqlitedb.h +++ b/src/sqlitedb.h @@ -85,7 +85,7 @@ public: * @return An sqlite conform INSERT INTO statement with empty values. (NULL,'',0) */ QString emptyInsertStmt(const sqlb::Table& t, const QString& pk_value = QString()) const; - bool deleteRecord(const QString& table, const QString& rowid); + bool deleteRecords(const QString& table, const QStringList& rowids); bool updateRecord(const QString& table, const QString& column, const QString& rowid, const QByteArray& value, bool itsBlob); bool createTable(const QString& name, const sqlb::FieldVector& structure); diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index 2c2e5d14..a41dad8f 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -410,15 +410,16 @@ bool SqliteTableModel::removeRows(int row, int count, const QModelIndex& parent) bool ok = true; + QStringList rowids; for(int i=count-1;i>=0;i--) { - if(m_db->deleteRecord(m_sTable, m_data.at(row + i).at(0))) - { - m_data.removeAt(row + i); - --m_rowCount; - } else { - ok = false; - } + rowids.append(m_data.at(row + i).at(0)); + m_data.removeAt(row + i); + --m_rowCount; + } + if(!m_db->deleteRecords(m_sTable, rowids)) + { + ok = false; } endRemoveRows();