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;
}
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);
}
else {
@ -373,7 +373,7 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt
return false;
}
if (DatabaseQueries::markMessagesRead(database(), message_ids, read)) {
if (DatabaseQueries::markMessagesReadUnread(database(), message_ids, read)) {
fetchAllData();
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(),
QList<Message>() << m_message,
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),
RootItem::Read);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
@ -156,7 +156,7 @@ void MessagePreviewer::markMessageAsUnread() {
if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << m_message,
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),
RootItem::Unread);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),

View File

@ -22,7 +22,7 @@
#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);
q.setForwardOnly(true);
@ -58,6 +58,17 @@ bool DatabaseQueries::markBinReadUnread(QSqlDatabase db, int account_id, RootIte
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) {
QSqlQuery q(db);
q.setForwardOnly(true);
@ -312,6 +323,38 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForBin(QSqlDatabase db, int
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,
const QList<Message> &messages,
int feed_custom_id,
@ -516,5 +559,99 @@ bool DatabaseQueries::cleanMessagesFromBin(QSqlDatabase db, bool clear_only_read
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() {
}

View File

@ -25,9 +25,10 @@
class DatabaseQueries {
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 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 permanentlyDeleteMessages(QSqlDatabase db, const QStringList &ids);
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 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> getUndeletedMessagesForAccount(QSqlDatabase db, int account_id, bool *ok = NULL);
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);
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:
explicit DatabaseQueries();

View File

@ -21,13 +21,12 @@
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/databasequeries.h"
#include "services/abstract/category.h"
#include "services/abstract/feed.h"
#include "services/abstract/recyclebin.h"
#include <QSqlTableModel>
#include <QSqlQuery>
#include <QSqlError>
ServiceRoot::ServiceRoot(RootItem *parent) : RootItem(parent), m_accountId(NO_PARENT_CATEGORY) {
@ -39,44 +38,21 @@ ServiceRoot::~ServiceRoot() {
}
bool ServiceRoot::deleteViaGui() {
QSqlDatabase connection = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(connection);
const int account_id = accountId();
query.setForwardOnly(true);
QSqlDatabase database= qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
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();
}
if (DatabaseQueries::deleteAccount(database, accountId())) {
requestItemRemoval(this);
return true;
}
else {
return false;
}
requestItemRemoval(this);
return true;
}
bool ServiceRoot::markAsReadUnread(RootItem::ReadStatus status) {
QSqlDatabase db_handle = 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;"));
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
query.bindValue(QSL(":account_id"), accountId());
query.bindValue(QSL(":read"), status == RootItem::Read ? 1 : 0);
if (query.exec()) {
if (DatabaseQueries::markAccountReadUnread(database, accountId(), status)) {
updateCounts(false);
itemChanged(getSubTree());
requestReloadMessageList(status == RootItem::Read);
@ -110,22 +86,8 @@ void ServiceRoot::completelyRemoveAllData() {
void ServiceRoot::removeOldFeedTree(bool including_messages) {
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;"));
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();
}
DatabaseQueries::deleteAccountData(database, accountId(), including_messages);
}
void ServiceRoot::cleanAllItems() {
@ -136,27 +98,10 @@ void ServiceRoot::cleanAllItems() {
}
}
bool ServiceRoot::cleanFeeds(QList<Feed *> items, bool clean_read_only) {
QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query_delete_msg(db_handle);
int account_id = accountId();
query_delete_msg.setForwardOnly(true);
bool ServiceRoot::cleanFeeds(QList<Feed*> items, bool clean_read_only) {
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
if (clean_read_only) {
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()) {
if (DatabaseQueries::cleanFeeds(database, textualFeedIds(items), clean_read_only, accountId())) {
// Messages are cleared, now inform model about need to reload data.
QList<RootItem*> itemss;
@ -177,7 +122,6 @@ bool ServiceRoot::cleanFeeds(QList<Feed *> items, bool clean_read_only) {
return true;
}
else {
qDebug("Cleaning of feeds failed: '%s'.", qPrintable(query_delete_msg.lastError().text()));
return false;
}
}
@ -233,44 +177,14 @@ void ServiceRoot::storeNewFeedTree(RootItem *root) {
void ServiceRoot::removeLeftOverMessages() {
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
int account_id = accountId();
query.setForwardOnly(true);
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()));
}
DatabaseQueries::deleteLeftoverMessages(database, accountId());
}
QList<Message> ServiceRoot::undeletedMessages() const {
QList<Message> messages;
const int account_id = accountId();
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
query.setForwardOnly(true);
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;
return DatabaseQueries::getUndeletedMessagesForAccount(database, accountId());
}
void ServiceRoot::itemChanged(const QList<RootItem*> &items) {