Switched to DIRECT SQL persistent changes.

This commit is contained in:
Martin Rotter 2013-12-13 11:23:41 +01:00
parent 6ec00ab841
commit 7a9bb69a5d
2 changed files with 116 additions and 26 deletions

View file

@ -21,6 +21,8 @@ MessagesModel::MessagesModel(QObject *parent)
setupHeaderData(); setupHeaderData();
// Set desired table and edit strategy. // 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); setEditStrategy(QSqlTableModel::OnManualSubmit);
setTable("Messages"); setTable("Messages");
@ -31,6 +33,11 @@ MessagesModel::~MessagesModel() {
qDebug("Destroying MessagesModel instance."); qDebug("Destroying MessagesModel instance.");
} }
bool MessagesModel::submitAll() {
qFatal("Submittting changes via model is not allowed.");
return false;
}
void MessagesModel::setupIcons() { void MessagesModel::setupIcons() {
m_favoriteIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-important"); m_favoriteIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-important");
m_readIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-read"); m_readIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-read");
@ -51,9 +58,6 @@ void MessagesModel::setupFonts() {
} }
void MessagesModel::loadMessages(const QList<int> feed_ids) { void MessagesModel::loadMessages(const QList<int> feed_ids) {
// Submit changes first.
submitAll();
// Conversion of parameter. // Conversion of parameter.
m_currentFeeds = feed_ids; m_currentFeeds = feed_ids;
QStringList stringy_ids; QStringList stringy_ids;
@ -104,6 +108,7 @@ void MessagesModel::setupHeaderData() {
Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const { Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const {
Q_UNUSED(idx) Q_UNUSED(idx)
#if QT_VERSION >= 0x050000
if (m_isInEditingMode) { if (m_isInEditingMode) {
// NOTE: Editing of model must be temporarily enabled here. // NOTE: Editing of model must be temporarily enabled here.
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
@ -111,6 +116,9 @@ Qt::ItemFlags MessagesModel::flags(const QModelIndex &idx) const {
else { else {
return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
} }
#else
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
#endif
} }
QVariant MessagesModel::data(int row, int column, int role) const { 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: case Qt::EditRole:
return QSqlTableModel::data(idx, role); 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 ? return record(idx.row()).value(MSG_DB_READ_INDEX).toInt() == 1 ?
m_normalFont : m_normalFont :
m_boldFont; 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: { case Qt::DecorationRole: {
int index_column = idx.column(); 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) { bool MessagesModel::setData(const QModelIndex &idx, const QVariant &value, int role) {
#if QT_VERSION >= 0x050000
m_isInEditingMode = true; m_isInEditingMode = true;
#endif
bool set_data_result = QSqlTableModel::setData(idx, value, role); bool set_data_result = QSqlTableModel::setData(idx, value, role);
#if QT_VERSION >= 0x050000
m_isInEditingMode = false; m_isInEditingMode = false;
#endif
return set_data_result; return set_data_result;
} }
bool MessagesModel::setMessageRead(int row_index, int read) { bool MessagesModel::setMessageRead(int row_index, int read) {
return setData(index(row_index, MSG_DB_READ_INDEX), if (!database().transaction()) {
read); qWarning("Starting transaction for batch message read change.");
} return false;
}
bool MessagesModel::setMessageDeleted(int row_index, int deleted) { // Rewrite "visible" data in the model.
return setData(index(row_index, MSG_DB_DELETED_INDEX), bool working_change = setData(index(row_index, MSG_DB_READ_INDEX),
deleted); 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::switchMessageImportance(int row_index) { bool MessagesModel::switchMessageImportance(int row_index) {
if (!database().transaction()) {
qWarning("Starting transaction for batch message importance switch failed.");
return false;
}
QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX); QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX);
int current_importance = data(target_index, Qt::EditRole).toInt(); int current_importance = data(target_index, Qt::EditRole).toInt();
return current_importance == 1 ? // Rewrite "visible" data in the model.
setData(target_index, 0) : bool working_change = current_importance == 1 ?
setData(target_index, 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) { bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages) {
// Submit changes first.
submitAll();
if (!database().transaction()) { if (!database().transaction()) {
qWarning("Starting transaction for batch message importance switch failed."); qWarning("Starting transaction for batch message importance switch failed.");
return false; return false;
@ -231,9 +320,6 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
} }
bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int deleted) { bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int deleted) {
// Submit changes first.
submitAll();
if (!database().transaction()) { if (!database().transaction()) {
qWarning("Starting transaction for batch message deletion."); qWarning("Starting transaction for batch message deletion.");
return false; return false;
@ -268,9 +354,6 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int
} }
bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int read) { bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int read) {
// Submit changes first.
submitAll();
if (!database().transaction()) { if (!database().transaction()) {
qWarning("Starting transaction for batch message read change."); qWarning("Starting transaction for batch message read change.");
return false; return false;

View file

@ -53,17 +53,21 @@ class MessagesModel : public QSqlTableModel {
void endInsertColumns(); void endInsertColumns();
public slots: public slots:
// To disable persistent changes submissions.
bool submitAll();
// CORE messages manipulators. // CORE messages manipulators.
// NOTE: These are used to change properties of one message. // 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 switchMessageImportance(int row_index);
bool setMessageDeleted(int row_index, int deleted);
bool setMessageRead(int row_index, int read); bool setMessageRead(int row_index, int read);
// BATCH messages manipulators. // BATCH messages manipulators.
// NOTE: These methods are used for changing of attributes of // NOTE: These methods are used for changing of attributes of
// many messages via DIRECT SQL calls. // 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 switchBatchMessageImportance(const QModelIndexList &messages);
bool setBatchMessagesDeleted(const QModelIndexList &messages, int deleted); bool setBatchMessagesDeleted(const QModelIndexList &messages, int deleted);
bool setBatchMessagesRead(const QModelIndexList &messages, int read); bool setBatchMessagesRead(const QModelIndexList &messages, int read);
@ -94,7 +98,10 @@ class MessagesModel : public QSqlTableModel {
QList<int> m_currentFeeds; QList<int> m_currentFeeds;
QList<QString> m_headerData; QList<QString> m_headerData;
#if QT_VERSION >= 0x050000
bool m_isInEditingMode; bool m_isInEditingMode;
#endif
QFont m_normalFont; QFont m_normalFont;
QFont m_boldFont; QFont m_boldFont;