SQL refactoring.

This commit is contained in:
Martin Rotter 2016-04-05 14:13:55 +02:00
parent ebb498f7b2
commit d60ce597ac
5 changed files with 165 additions and 108 deletions

View File

@ -255,7 +255,7 @@ bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) {
return false; return false;
} }
if (DatabaseQueries::markMessagesRead(database(), QStringList() << QString::number(message.m_id), read)) { if (DatabaseQueries::markMessagesReadUnread(database(), QStringList() << QString::number(message.m_id), read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read); return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read);
} }
else { else {
@ -373,7 +373,7 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt
return false; return false;
} }
if (DatabaseQueries::markMessagesRead(database(), message_ids, read)) { if (DatabaseQueries::markMessagesReadUnread(database(), message_ids, read)) {
fetchAllData(); fetchAllData();
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read); return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read);
} }

View File

@ -136,7 +136,7 @@ void MessagePreviewer::markMessageAsRead() {
if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(), if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << m_message, QList<Message>() << m_message,
RootItem::Read)) { RootItem::Read)) {
DatabaseQueries::markMessagesRead(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id), QStringList() << QString::number(m_message.m_id),
RootItem::Read); RootItem::Read);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(), m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
@ -156,7 +156,7 @@ void MessagePreviewer::markMessageAsUnread() {
if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(), if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << m_message, QList<Message>() << m_message,
RootItem::Unread)) { RootItem::Unread)) {
DatabaseQueries::markMessagesRead(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id), QStringList() << QString::number(m_message.m_id),
RootItem::Unread); RootItem::Unread);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(), m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),

View File

@ -22,7 +22,7 @@
#include <QSqlError> #include <QSqlError>
bool DatabaseQueries::markMessagesRead(QSqlDatabase db, const QStringList &ids, RootItem::ReadStatus read) { bool DatabaseQueries::markMessagesReadUnread(QSqlDatabase db, const QStringList &ids, RootItem::ReadStatus read) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
@ -58,6 +58,17 @@ bool DatabaseQueries::markBinReadUnread(QSqlDatabase db, int account_id, RootIte
return q.exec(); return q.exec();
} }
bool DatabaseQueries::markAccountReadUnread(QSqlDatabase db, int account_id, RootItem::ReadStatus read) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id);
q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);
return q.exec();
}
bool DatabaseQueries::switchMessagesImportance(QSqlDatabase db, const QStringList &ids) { bool DatabaseQueries::switchMessagesImportance(QSqlDatabase db, const QStringList &ids) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
@ -312,6 +323,38 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForBin(QSqlDatabase db, int
return messages; return messages;
} }
QList<Message> DatabaseQueries::getUndeletedMessagesForAccount(QSqlDatabase db, int account_id, bool *ok) {
QList<Message> messages;
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare("SELECT * "
"FROM Messages "
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;");
q.bindValue(QSL(":account_id"), account_id);
if (q.exec()) {
while (q.next()) {
bool decoded;
Message message = Message::fromSqlRecord(q.record(), &decoded);
if (decoded) {
messages.append(message);
}
}
if (ok != NULL) {
*ok = true;
}
}
else {
if (ok != NULL) {
*ok = false;
}
}
return messages;
}
int DatabaseQueries::updateMessages(QSqlDatabase db, int DatabaseQueries::updateMessages(QSqlDatabase db,
const QList<Message> &messages, const QList<Message> &messages,
int feed_custom_id, int feed_custom_id,
@ -516,5 +559,99 @@ bool DatabaseQueries::cleanMessagesFromBin(QSqlDatabase db, bool clear_only_read
return query_empty_bin.exec(); return query_empty_bin.exec();
} }
bool DatabaseQueries::deleteAccount(QSqlDatabase db, int account_id) {
QSqlQuery query(db);
query.setForwardOnly(true);
QStringList queries;
queries << QSL("DELETE FROM Messages WHERE account_id = :account_id;") <<
QSL("DELETE FROM Feeds WHERE account_id = :account_id;") <<
QSL("DELETE FROM Categories WHERE account_id = :account_id;") <<
QSL("DELETE FROM Accounts WHERE id = :account_id;");
foreach (const QString &q, queries) {
query.prepare(q);
query.bindValue(QSL(":account_id"), account_id);
if (!query.exec()) {
qCritical("Removing of account from DB failed, this is critical: '%s'.", qPrintable(query.lastError().text()));
return false;
}
else {
query.finish();
}
}
return true;
}
bool DatabaseQueries::deleteAccountData(QSqlDatabase db, int account_id, bool delete_messages_too) {
bool result = true;
QSqlQuery query(db);
query.setForwardOnly(true);
if (delete_messages_too) {
query.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id;"));
query.bindValue(QSL(":account_id"), account_id);
result &= query.exec();
}
query.prepare(QSL("DELETE FROM Feeds WHERE account_id = :account_id;"));
query.bindValue(QSL(":account_id"), account_id);
result &= query.exec();
query.prepare(QSL("DELETE FROM Categories WHERE account_id = :account_id;"));
query.bindValue(QSL(":account_id"), account_id);
result &= query.exec();
return result;
}
bool DatabaseQueries::cleanFeeds(QSqlDatabase db, const QStringList &ids, bool clean_read_only, int account_id) {
QSqlQuery q(db);
q.setForwardOnly(true);
if (clean_read_only) {
q.prepare(QString("UPDATE Messages SET is_deleted = :deleted "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;")
.arg(ids.join(QSL(", "))));
}
else {
q.prepare(QString("UPDATE Messages SET is_deleted = :deleted "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")
.arg(ids.join(QSL(", "))));
}
q.bindValue(QSL(":deleted"), 1);
q.bindValue(QSL(":account_id"), account_id);
if (!q.exec()) {
qDebug("Cleaning of feeds failed: '%s'.", qPrintable(q.lastError().text()));
return false;
}
else {
return true;
}
}
bool DatabaseQueries::deleteLeftoverMessages(QSqlDatabase db, int account_id) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);"));
q.bindValue(QSL(":account_id"), account_id);
if (!q.exec()) {
qWarning("Removing of left over messages failed: '%s'.", qPrintable(q.lastError().text()));
return false;
}
else {
return true;
}
}
DatabaseQueries::DatabaseQueries() { DatabaseQueries::DatabaseQueries() {
} }

View File

@ -25,9 +25,10 @@
class DatabaseQueries { class DatabaseQueries {
public: public:
static bool markMessagesRead(QSqlDatabase db, const QStringList &ids, RootItem::ReadStatus read); static bool markMessagesReadUnread(QSqlDatabase db, const QStringList &ids, RootItem::ReadStatus read);
static bool markMessageImportant(QSqlDatabase db, int id, RootItem::Importance importance); static bool markMessageImportant(QSqlDatabase db, int id, RootItem::Importance importance);
static bool markBinReadUnread(QSqlDatabase db, int account_id, RootItem::ReadStatus read); static bool markBinReadUnread(QSqlDatabase db, int account_id, RootItem::ReadStatus read);
static bool markAccountReadUnread(QSqlDatabase db, int account_id, RootItem::ReadStatus read);
static bool switchMessagesImportance(QSqlDatabase db, const QStringList &ids); static bool switchMessagesImportance(QSqlDatabase db, const QStringList &ids);
static bool permanentlyDeleteMessages(QSqlDatabase db, const QStringList &ids); static bool permanentlyDeleteMessages(QSqlDatabase db, const QStringList &ids);
static bool deleteOrRestoreMessagesToFromBin(QSqlDatabase db, const QStringList &ids, bool deleted); static bool deleteOrRestoreMessagesToFromBin(QSqlDatabase db, const QStringList &ids, bool deleted);
@ -43,9 +44,14 @@ class DatabaseQueries {
static int getMessageCountsForBin(QSqlDatabase db, int account_id, bool including_total_counts, bool *ok = NULL); static int getMessageCountsForBin(QSqlDatabase db, int account_id, bool including_total_counts, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = NULL); static QList<Message> getUndeletedMessagesForFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForBin(QSqlDatabase db, int account_id, bool *ok = NULL); static QList<Message> getUndeletedMessagesForBin(QSqlDatabase db, int account_id, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForAccount(QSqlDatabase db, int account_id, bool *ok = NULL);
static int updateMessages(QSqlDatabase db, const QList<Message> &messages, int feed_custom_id, static int updateMessages(QSqlDatabase db, const QList<Message> &messages, int feed_custom_id,
int account_id, const QString &url, bool *any_message_changed, bool *ok = NULL); int account_id, const QString &url, bool *any_message_changed, bool *ok = NULL);
static bool cleanMessagesFromBin(QSqlDatabase db, bool clear_only_read, int account_id); static bool cleanMessagesFromBin(QSqlDatabase db, bool clear_only_read, int account_id);
static bool deleteAccount(QSqlDatabase db, int account_id);
static bool deleteAccountData(QSqlDatabase db, int account_id, bool delete_messages_too);
static bool cleanFeeds(QSqlDatabase db, const QStringList &ids, bool clean_read_only, int account_id);
static bool deleteLeftoverMessages(QSqlDatabase db, int account_id);
private: private:
explicit DatabaseQueries(); explicit DatabaseQueries();

View File

@ -21,13 +21,12 @@
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h" #include "miscellaneous/textfactory.h"
#include "miscellaneous/databasequeries.h"
#include "services/abstract/category.h" #include "services/abstract/category.h"
#include "services/abstract/feed.h" #include "services/abstract/feed.h"
#include "services/abstract/recyclebin.h" #include "services/abstract/recyclebin.h"
#include <QSqlTableModel> #include <QSqlTableModel>
#include <QSqlQuery>
#include <QSqlError>
ServiceRoot::ServiceRoot(RootItem *parent) : RootItem(parent), m_accountId(NO_PARENT_CATEGORY) { ServiceRoot::ServiceRoot(RootItem *parent) : RootItem(parent), m_accountId(NO_PARENT_CATEGORY) {
@ -39,44 +38,21 @@ ServiceRoot::~ServiceRoot() {
} }
bool ServiceRoot::deleteViaGui() { bool ServiceRoot::deleteViaGui() {
QSqlDatabase connection = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database= qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(connection);
const int account_id = accountId();
query.setForwardOnly(true);
QStringList queries; if (DatabaseQueries::deleteAccount(database, accountId())) {
queries << QSL("DELETE FROM Messages WHERE account_id = :account_id;") << requestItemRemoval(this);
QSL("DELETE FROM Feeds WHERE account_id = :account_id;") << return true;
QSL("DELETE FROM Categories WHERE account_id = :account_id;") << }
QSL("DELETE FROM Accounts WHERE id = :account_id;"); else {
return false;
foreach (const QString &q, queries) {
query.prepare(q);
query.bindValue(QSL(":account_id"), account_id);
if (!query.exec()) {
qCritical("Removing of account from DB failed, this is critical: '%s'.", qPrintable(query.lastError().text()));
return false;
}
else {
query.finish();
}
} }
requestItemRemoval(this);
return true;
} }
bool ServiceRoot::markAsReadUnread(RootItem::ReadStatus status) { bool ServiceRoot::markAsReadUnread(RootItem::ReadStatus status) {
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(db_handle);
query.setForwardOnly(true);
query.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;"));
query.bindValue(QSL(":account_id"), accountId()); if (DatabaseQueries::markAccountReadUnread(database, accountId(), status)) {
query.bindValue(QSL(":read"), status == RootItem::Read ? 1 : 0);
if (query.exec()) {
updateCounts(false); updateCounts(false);
itemChanged(getSubTree()); itemChanged(getSubTree());
requestReloadMessageList(status == RootItem::Read); requestReloadMessageList(status == RootItem::Read);
@ -110,22 +86,8 @@ void ServiceRoot::completelyRemoveAllData() {
void ServiceRoot::removeOldFeedTree(bool including_messages) { void ServiceRoot::removeOldFeedTree(bool including_messages) {
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
query.setForwardOnly(true);
query.prepare(QSL("DELETE FROM Feeds WHERE account_id = :account_id;")); DatabaseQueries::deleteAccountData(database, accountId(), including_messages);
query.bindValue(QSL(":account_id"), accountId());
query.exec();
query.prepare(QSL("DELETE FROM Categories WHERE account_id = :account_id;"));
query.bindValue(QSL(":account_id"), accountId());
query.exec();
if (including_messages) {
query.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id;"));
query.bindValue(QSL(":account_id"), accountId());
query.exec();
}
} }
void ServiceRoot::cleanAllItems() { void ServiceRoot::cleanAllItems() {
@ -136,27 +98,10 @@ void ServiceRoot::cleanAllItems() {
} }
} }
bool ServiceRoot::cleanFeeds(QList<Feed *> items, bool clean_read_only) { bool ServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_delete_msg(db_handle);
int account_id = accountId();
query_delete_msg.setForwardOnly(true);
if (clean_read_only) { if (DatabaseQueries::cleanFeeds(database, textualFeedIds(items), clean_read_only, accountId())) {
query_delete_msg.prepare(QString("UPDATE Messages SET is_deleted = :deleted "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;")
.arg(textualFeedIds(items).join(QSL(", "))));
}
else {
query_delete_msg.prepare(QString("UPDATE Messages SET is_deleted = :deleted "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")
.arg(textualFeedIds(items).join(QSL(", "))));
}
query_delete_msg.bindValue(QSL(":deleted"), 1);
query_delete_msg.bindValue(QSL(":account_id"), account_id);
if (query_delete_msg.exec()) {
// Messages are cleared, now inform model about need to reload data. // Messages are cleared, now inform model about need to reload data.
QList<RootItem*> itemss; QList<RootItem*> itemss;
@ -177,7 +122,6 @@ bool ServiceRoot::cleanFeeds(QList<Feed *> items, bool clean_read_only) {
return true; return true;
} }
else { else {
qDebug("Cleaning of feeds failed: '%s'.", qPrintable(query_delete_msg.lastError().text()));
return false; return false;
} }
} }
@ -233,44 +177,14 @@ void ServiceRoot::storeNewFeedTree(RootItem *root) {
void ServiceRoot::removeLeftOverMessages() { void ServiceRoot::removeLeftOverMessages() {
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
int account_id = accountId();
query.setForwardOnly(true); DatabaseQueries::deleteLeftoverMessages(database, accountId());
query.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);"));
query.bindValue(QSL(":account_id"), account_id);
if (!query.exec()) {
qWarning("Removing of left over messages failed: '%s'.", qPrintable(query.lastError().text()));
}
} }
QList<Message> ServiceRoot::undeletedMessages() const { QList<Message> ServiceRoot::undeletedMessages() const {
QList<Message> messages;
const int account_id = accountId();
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
query.setForwardOnly(true); return DatabaseQueries::getUndeletedMessagesForAccount(database, accountId());
query.prepare("SELECT * "
"FROM Messages "
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;");
query.bindValue(QSL(":account_id"), account_id);
if (query.exec()) {
while (query.next()) {
bool decoded;
Message message = Message::fromSqlRecord(query.record(), &decoded);
if (decoded) {
messages.append(message);
}
messages.append(message);
}
}
return messages;
} }
void ServiceRoot::itemChanged(const QList<RootItem*> &items) { void ServiceRoot::itemChanged(const QList<RootItem*> &items) {