From 9695bb2316d2f67c5a8618a4843421a7a4c0462a Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 10 Jul 2020 07:50:16 +0200 Subject: [PATCH] initial experimental full implementation of #31 --- .../miscellaneous/databasequeries.cpp | 19 ++++++++++++++ .../miscellaneous/databasequeries.h | 1 + .../services/abstract/serviceroot.cpp | 25 ++++++++++++------- .../services/abstract/serviceroot.h | 11 ++++++-- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp index 306220e8f..037d4e2bf 100755 --- a/src/librssguard/miscellaneous/databasequeries.cpp +++ b/src/librssguard/miscellaneous/databasequeries.cpp @@ -866,6 +866,25 @@ bool DatabaseQueries::cleanFeeds(const QSqlDatabase& db, const QStringList& ids, } } +bool DatabaseQueries::purgeLeftoverMessageFilterAssignments(const QSqlDatabase& db, int account_id) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare( + QSL("DELETE FROM MessageFiltersInFeeds " + "WHERE account_id = :account_id AND " + "feed_custom_id 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 message filter assignments failed: '%s'.", qPrintable(q.lastError().text())); + return false; + } + else { + return true; + } +} + bool DatabaseQueries::purgeLeftoverMessages(const QSqlDatabase& db, int account_id) { QSqlQuery q(db); diff --git a/src/librssguard/miscellaneous/databasequeries.h b/src/librssguard/miscellaneous/databasequeries.h index 284578a16..1f0aea30d 100644 --- a/src/librssguard/miscellaneous/databasequeries.h +++ b/src/librssguard/miscellaneous/databasequeries.h @@ -87,6 +87,7 @@ class DatabaseQueries { int account_id, bool* ok = nullptr); // Message filters operators. + static bool purgeLeftoverMessageFilterAssignments(const QSqlDatabase& db, int account_id); static MessageFilter* addMessageFilter(const QSqlDatabase& db, const QString& title, const QString& script); static void removeMessageFilter(const QSqlDatabase& db, int filter_id, bool* ok = nullptr); static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr); diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index b676634e4..802558281 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -207,6 +207,12 @@ void ServiceRoot::removeLeftOverMessages() { DatabaseQueries::purgeLeftoverMessages(database, accountId()); } +void ServiceRoot::removeLeftOverMessageFilterAssignments() { + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + + DatabaseQueries::purgeLeftoverMessageFilterAssignments(database, accountId()); +} + QList ServiceRoot::undeletedMessages() const { QSqlDatabase database = qApp->database()->connection(metaObject()->className()); @@ -251,22 +257,23 @@ void ServiceRoot::addNewFeed(const QString& url) { void ServiceRoot::addNewCategory() {} -QMap ServiceRoot::storeCustomFeedsData() { - QMap custom_data; +QMap ServiceRoot::storeCustomFeedsData() { + QMap custom_data; for (const Feed* feed : getSubTreeFeeds()) { QVariantMap feed_custom_data; feed_custom_data.insert(QSL("auto_update_interval"), feed->autoUpdateInitialInterval()); feed_custom_data.insert(QSL("auto_update_type"), feed->autoUpdateType()); + feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters())); custom_data.insert(feed->customId(), feed_custom_data); } return custom_data; } -void ServiceRoot::restoreCustomFeedsData(const QMap& data, const QHash& feeds) { - QMapIterator i(data); +void ServiceRoot::restoreCustomFeedsData(const QMap& data, const QHash& feeds) { + QMapIterator i(data); while (i.hasNext()) { i.next(); @@ -274,10 +281,11 @@ void ServiceRoot::restoreCustomFeedsData(const QMap& data, co if (feeds.contains(custom_id)) { Feed* feed = feeds.value(custom_id); - QVariantMap feed_custom_data = i.value().toMap(); + QVariantMap feed_custom_data = i.value(); feed->setAutoUpdateInitialInterval(feed_custom_data.value(QSL("auto_update_interval")).toInt()); feed->setAutoUpdateType(static_cast(feed_custom_data.value(QSL("auto_update_type")).toInt())); + feed->setMessageFilters(feed_custom_data.value(QSL("msg_filters")).value>>()); } } } @@ -298,9 +306,7 @@ void ServiceRoot::syncIn() { RootItem* new_tree = obtainNewTreeForSyncIn(); if (new_tree != nullptr) { - // TODO: Store msg filter assignments and then restore it and - // also remove any leftover assignments. - QMap feed_custom_data = storeCustomFeedsData(); + auto feed_custom_data = storeCustomFeedsData(); // Remove from feeds model, then from SQL but leave messages intact. cleanAllItemsFromModel(); @@ -312,8 +318,9 @@ void ServiceRoot::syncIn() { storeNewFeedTree(new_tree); // We have new feed, some feeds were maybe removed, - // so remove left over messages. + // so remove left over messages and filter assignments. removeLeftOverMessages(); + removeLeftOverMessageFilterAssignments(); for (RootItem* top_level_item : new_tree->childItems()) { top_level_item->setParent(nullptr); diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index 3117cf907..796b81c62 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -175,6 +175,13 @@ class ServiceRoot : public RootItem { // from another machine and then performs sync-in on this machine. void removeLeftOverMessages(); + // Removes all msg. filter assignments which are (within this account) + // assigned to feed (via custom ID) which does not exist anymore. + // + // NOTE: This situation may happen if user deletes some feed + // from another machine and then performs sync-in on this machine. + void removeLeftOverMessageFilterAssignments(); + QStringList textualFeedUrls(const QList& feeds) const; QStringList textualFeedIds(const QList& feeds) const; QStringList customIDsOfMessages(const QList& changes); @@ -194,8 +201,8 @@ class ServiceRoot : public RootItem { void itemRemovalRequested(RootItem* item); private: - virtual QMap storeCustomFeedsData(); - virtual void restoreCustomFeedsData(const QMap& data, const QHash& feeds); + virtual QMap storeCustomFeedsData(); + virtual void restoreCustomFeedsData(const QMap& data, const QHash& feeds); private: RecycleBin* m_recycleBin;