initial experimental full implementation of #31

This commit is contained in:
Martin Rotter 2020-07-10 07:50:16 +02:00
parent 5d4c4dd1d9
commit 9695bb2316
4 changed files with 45 additions and 11 deletions

View File

@ -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) { bool DatabaseQueries::purgeLeftoverMessages(const QSqlDatabase& db, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);

View File

@ -87,6 +87,7 @@ class DatabaseQueries {
int account_id, bool* ok = nullptr); int account_id, bool* ok = nullptr);
// Message filters operators. // 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 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 removeMessageFilter(const QSqlDatabase& db, int filter_id, bool* ok = nullptr);
static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr); static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr);

View File

@ -207,6 +207,12 @@ void ServiceRoot::removeLeftOverMessages() {
DatabaseQueries::purgeLeftoverMessages(database, accountId()); DatabaseQueries::purgeLeftoverMessages(database, accountId());
} }
void ServiceRoot::removeLeftOverMessageFilterAssignments() {
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
DatabaseQueries::purgeLeftoverMessageFilterAssignments(database, accountId());
}
QList<Message> ServiceRoot::undeletedMessages() const { QList<Message> ServiceRoot::undeletedMessages() const {
QSqlDatabase database = qApp->database()->connection(metaObject()->className()); QSqlDatabase database = qApp->database()->connection(metaObject()->className());
@ -251,22 +257,23 @@ void ServiceRoot::addNewFeed(const QString& url) {
void ServiceRoot::addNewCategory() {} void ServiceRoot::addNewCategory() {}
QMap<QString, QVariant> ServiceRoot::storeCustomFeedsData() { QMap<QString, QVariantMap> ServiceRoot::storeCustomFeedsData() {
QMap<QString, QVariant> custom_data; QMap<QString, QVariantMap> custom_data;
for (const Feed* feed : getSubTreeFeeds()) { for (const Feed* feed : getSubTreeFeeds()) {
QVariantMap feed_custom_data; QVariantMap feed_custom_data;
feed_custom_data.insert(QSL("auto_update_interval"), feed->autoUpdateInitialInterval()); 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("auto_update_type"), feed->autoUpdateType());
feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters()));
custom_data.insert(feed->customId(), feed_custom_data); custom_data.insert(feed->customId(), feed_custom_data);
} }
return custom_data; return custom_data;
} }
void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariant>& data, const QHash<QString, Feed*>& feeds) { void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariantMap>& data, const QHash<QString, Feed*>& feeds) {
QMapIterator<QString, QVariant> i(data); QMapIterator<QString, QVariantMap> i(data);
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
@ -274,10 +281,11 @@ void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariant>& data, co
if (feeds.contains(custom_id)) { if (feeds.contains(custom_id)) {
Feed* feed = feeds.value(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->setAutoUpdateInitialInterval(feed_custom_data.value(QSL("auto_update_interval")).toInt());
feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(feed_custom_data.value(QSL("auto_update_type")).toInt())); feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(feed_custom_data.value(QSL("auto_update_type")).toInt()));
feed->setMessageFilters(feed_custom_data.value(QSL("msg_filters")).value<QList<QPointer<MessageFilter>>>());
} }
} }
} }
@ -298,9 +306,7 @@ void ServiceRoot::syncIn() {
RootItem* new_tree = obtainNewTreeForSyncIn(); RootItem* new_tree = obtainNewTreeForSyncIn();
if (new_tree != nullptr) { if (new_tree != nullptr) {
// TODO: Store msg filter assignments and then restore it and auto feed_custom_data = storeCustomFeedsData();
// also remove any leftover assignments.
QMap<QString, QVariant> feed_custom_data = storeCustomFeedsData();
// Remove from feeds model, then from SQL but leave messages intact. // Remove from feeds model, then from SQL but leave messages intact.
cleanAllItemsFromModel(); cleanAllItemsFromModel();
@ -312,8 +318,9 @@ void ServiceRoot::syncIn() {
storeNewFeedTree(new_tree); storeNewFeedTree(new_tree);
// We have new feed, some feeds were maybe removed, // We have new feed, some feeds were maybe removed,
// so remove left over messages. // so remove left over messages and filter assignments.
removeLeftOverMessages(); removeLeftOverMessages();
removeLeftOverMessageFilterAssignments();
for (RootItem* top_level_item : new_tree->childItems()) { for (RootItem* top_level_item : new_tree->childItems()) {
top_level_item->setParent(nullptr); top_level_item->setParent(nullptr);

View File

@ -175,6 +175,13 @@ class ServiceRoot : public RootItem {
// from another machine and then performs sync-in on this machine. // from another machine and then performs sync-in on this machine.
void removeLeftOverMessages(); 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<Feed*>& feeds) const; QStringList textualFeedUrls(const QList<Feed*>& feeds) const;
QStringList textualFeedIds(const QList<Feed*>& feeds) const; QStringList textualFeedIds(const QList<Feed*>& feeds) const;
QStringList customIDsOfMessages(const QList<ImportanceChange>& changes); QStringList customIDsOfMessages(const QList<ImportanceChange>& changes);
@ -194,8 +201,8 @@ class ServiceRoot : public RootItem {
void itemRemovalRequested(RootItem* item); void itemRemovalRequested(RootItem* item);
private: private:
virtual QMap<QString, QVariant> storeCustomFeedsData(); virtual QMap<QString, QVariantMap> storeCustomFeedsData();
virtual void restoreCustomFeedsData(const QMap<QString, QVariant>& data, const QHash<QString, Feed*>& feeds); virtual void restoreCustomFeedsData(const QMap<QString, QVariantMap>& data, const QHash<QString, Feed*>& feeds);
private: private:
RecycleBin* m_recycleBin; RecycleBin* m_recycleBin;