From 7a9bb69a5d2d0e46e0d5562b9addeb838c4adc42 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 13 Dec 2013 11:23:41 +0100 Subject: [PATCH] Switched to DIRECT SQL persistent changes. --- src/core/messagesmodel.cpp | 129 ++++++++++++++++++++++++++++++------- src/core/messagesmodel.h | 13 +++- 2 files changed, 116 insertions(+), 26 deletions(-) diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index 95f0c8b9e..43f1e90b1 100644 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -21,6 +21,8 @@ MessagesModel::MessagesModel(QObject *parent) setupHeaderData(); // Set desired table and edit strategy. + // NOTE: Changes to the database are actually NOT submitted + // via model, but DIRECT SQL calls are used to do persistent messages. setEditStrategy(QSqlTableModel::OnManualSubmit); setTable("Messages"); @@ -31,6 +33,11 @@ MessagesModel::~MessagesModel() { qDebug("Destroying MessagesModel instance."); } +bool MessagesModel::submitAll() { + qFatal("Submittting changes via model is not allowed."); + return false; +} + void MessagesModel::setupIcons() { m_favoriteIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-important"); m_readIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-read"); @@ -51,9 +58,6 @@ void MessagesModel::setupFonts() { } void MessagesModel::loadMessages(const QList feed_ids) { - // Submit changes first. - submitAll(); - // Conversion of parameter. m_currentFeeds = feed_ids; QStringList stringy_ids; @@ -104,6 +108,7 @@ void MessagesModel::setupHeaderData() { Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const { Q_UNUSED(idx) +#if QT_VERSION >= 0x050000 if (m_isInEditingMode) { // NOTE: Editing of model must be temporarily enabled here. return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; @@ -111,6 +116,9 @@ Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const { else { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } +#else + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +#endif } QVariant MessagesModel::data(int row, int column, int role) const { @@ -131,7 +139,7 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const { } } - // Return RAW data for EditRole. + // Return RAW data for EditRole. case Qt::EditRole: return QSqlTableModel::data(idx, role); @@ -139,6 +147,12 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const { return record(idx.row()).value(MSG_DB_READ_INDEX).toInt() == 1 ? m_normalFont : m_boldFont; + /* + case Qt::BackgroundRole: + return record(idx.row()).value(MSG_DB_DELETED_INDEX).toInt() == 1 ? + QColor(255, 0, 0, 100) : + QVariant(); + */ case Qt::DecorationRole: { int index_column = idx.column(); @@ -164,36 +178,111 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const { } bool MessagesModel::setData(const QModelIndex &idx, const QVariant &value, int role) { + +#if QT_VERSION >= 0x050000 m_isInEditingMode = true; +#endif + bool set_data_result = QSqlTableModel::setData(idx, value, role); + +#if QT_VERSION >= 0x050000 m_isInEditingMode = false; +#endif return set_data_result; } bool MessagesModel::setMessageRead(int row_index, int read) { - return setData(index(row_index, MSG_DB_READ_INDEX), - read); + if (!database().transaction()) { + qWarning("Starting transaction for batch message read change."); + return false; + } + + // Rewrite "visible" data in the model. + bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), + read); + + if (!working_change) { + // If rewriting in the model failed, then cancel all actions. + return false; + } + + QSqlDatabase db_handle = database(); + int message_id; + QSqlQuery query_delete_msg(db_handle); + if (!query_delete_msg.prepare("UPDATE messages SET read = :read " + "WHERE id = :id")) { + qWarning("Query preparation failed for message read change."); + return false; + } + + // Rewrite the actual data in the database itself. + message_id = messageId(row_index); + query_delete_msg.bindValue(":id", message_id); + query_delete_msg.bindValue(":read", read); + query_delete_msg.exec(); + + // Commit changes. + if (db_handle.commit()) { + // If commit succeeded, then emit changes, so that view + // can reflect. + emit dataChanged(index(row_index, 0), + index(row_index, columnCount() - 1)); + return true; + } + else { + return db_handle.rollback();; + } } -bool MessagesModel::setMessageDeleted(int row_index, int deleted) { - return setData(index(row_index, MSG_DB_DELETED_INDEX), - deleted); -} +bool MessagesModel::switchMessageImportance(int row_index) { + if (!database().transaction()) { + qWarning("Starting transaction for batch message importance switch failed."); + return false; + } -bool MessagesModel::switchMessageImportance(int row_index) { QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX); int current_importance = data(target_index, Qt::EditRole).toInt(); - return current_importance == 1 ? - setData(target_index, 0) : - setData(target_index, 1); + // Rewrite "visible" data in the model. + bool working_change = current_importance == 1 ? + setData(target_index, 0) : + setData(target_index, 1); + + if (!working_change) { + // If rewriting in the model failed, then cancel all actions. + return false; + } + + QSqlDatabase db_handle = database(); + int message_id; + QSqlQuery query_delete_msg(db_handle); + if (!query_delete_msg.prepare("UPDATE messages SET important = :important " + "WHERE id = :id")) { + qWarning("Query preparation failed for message importance switch."); + return false; + } + + message_id = messageId(row_index); + query_delete_msg.bindValue(":id", message_id); + query_delete_msg.bindValue(":important", + current_importance == 1 ? 0 : 1); + query_delete_msg.exec(); + + // Commit changes. + if (db_handle.commit()) { + // If commit succeeded, then emit changes, so that view + // can reflect. + emit dataChanged(index(row_index, 0), + index(row_index, columnCount() - 1)); + return true; + } + else { + return db_handle.rollback(); + } } bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages) { - // Submit changes first. - submitAll(); - if (!database().transaction()) { qWarning("Starting transaction for batch message importance switch failed."); return false; @@ -231,9 +320,6 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages } bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int deleted) { - // Submit changes first. - submitAll(); - if (!database().transaction()) { qWarning("Starting transaction for batch message deletion."); return false; @@ -268,9 +354,6 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int } bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int read) { - // Submit changes first. - submitAll(); - if (!database().transaction()) { qWarning("Starting transaction for batch message read change."); return false; diff --git a/src/core/messagesmodel.h b/src/core/messagesmodel.h index ac266b944..dfc660e2f 100644 --- a/src/core/messagesmodel.h +++ b/src/core/messagesmodel.h @@ -53,17 +53,21 @@ class MessagesModel : public QSqlTableModel { void endInsertColumns(); public slots: + // To disable persistent changes submissions. + bool submitAll(); + // CORE messages manipulators. // NOTE: These are used to change properties of one message. - // NOTE: Model is NOT reset after one of these methods are applied. + // NOTE: Model is NOT reset after one of these methods are applied + // but changes ARE written to the database. bool switchMessageImportance(int row_index); - bool setMessageDeleted(int row_index, int deleted); bool setMessageRead(int row_index, int read); // BATCH messages manipulators. // NOTE: These methods are used for changing of attributes of // many messages via DIRECT SQL calls. - // NOTE: Model is reset after one of these methods is applied. + // NOTE: Model is reset after one of these methods is applied and + // changes ARE written to the database. bool switchBatchMessageImportance(const QModelIndexList &messages); bool setBatchMessagesDeleted(const QModelIndexList &messages, int deleted); bool setBatchMessagesRead(const QModelIndexList &messages, int read); @@ -94,7 +98,10 @@ class MessagesModel : public QSqlTableModel { QList m_currentFeeds; QList m_headerData; + +#if QT_VERSION >= 0x050000 bool m_isInEditingMode; +#endif QFont m_normalFont; QFont m_boldFont;