Fix updating records after changing the primary key

In the Browse Data tab updating a row after having updated its primary
key or part of it before was broken for multi-column primary keys. When
updating the value of a primary key column and then updating any part of
the row afterwards, we were still using the old value until the view was
refreshed. With this commit it is possible to immediately update the
row using the updated primary key values.

See issue #1834.
This commit is contained in:
Martin Kleusberg
2019-05-02 14:18:16 +02:00
parent 9c0b36d7b7
commit 29ca549f2f

View File

@@ -13,9 +13,12 @@
#include <QUrl>
#include <QtConcurrent/QtConcurrentRun>
#include <QProgressDialog>
#include <json.hpp>
#include "RowLoader.h"
using json = nlohmann::json;
SqliteTableModel::SqliteTableModel(DBBrowserDB& db, QObject* parent, size_t chunkSize, const QString& encoding)
: QAbstractTableModel(parent)
, m_db(db)
@@ -466,8 +469,26 @@ bool SqliteTableModel::setTypedData(const QModelIndex& index, bool isBlob, const
if(m_db.updateRecord(m_query.table(), m_headers.at(column), cached_row.at(0), newValue, isBlob, m_query.rowIdColumns()))
{
cached_row[column] = newValue;
if(m_headers.at(column) == sqlb::joinStringVector(m_query.rowIdColumns(), ",")) {
cached_row[0] = newValue;
// After updating the value itself in the cache, we need to check if we need to update the rowid too.
if(contains(m_query.rowIdColumns(), m_headers.at(column)))
{
// When the cached rowid column needs to be updated as well, we need to distinguish between single-column and multi-column primary keys.
// For the former ones, we can just overwrite the existing value with the new value.
// For the latter ones, we need to make a new JSON object of the values of all primary key columns, not just the updated one.
if(m_query.rowIdColumns().size() == 1)
{
cached_row[0] = newValue;
} else {
json array;
assert(m_headers.size() == cached_row.size());
for(size_t i=0;i<m_query.rowIdColumns().size();i++)
{
auto it = std::find(m_headers.begin()+1, m_headers.end(), m_query.rowIdColumns().at(i)); // +1 in order to omit the rowid column itself
array.push_back(cached_row[static_cast<size_t>(std::distance(m_headers.begin(), it))]);
}
cached_row[0] = QByteArray::fromStdString(array.dump());
}
const QModelIndex& rowidIndex = index.sibling(index.row(), 0);
lock.unlock();
emit dataChanged(rowidIndex, rowidIndex);