This commit is contained in:
Martin Rotter 2022-12-03 09:28:26 +01:00
parent b3959a648d
commit d5a02c098f
12 changed files with 161 additions and 56 deletions

View File

@ -3,9 +3,11 @@
<file>sql/db_init_mysql.sql</file> <file>sql/db_init_mysql.sql</file>
<file>sql/db_update_mysql_1_2.sql</file> <file>sql/db_update_mysql_1_2.sql</file>
<file>sql/db_update_mysql_2_3.sql</file> <file>sql/db_update_mysql_2_3.sql</file>
<file>sql/db_update_mysql_3_4.sql</file>
<file>sql/db_init_sqlite.sql</file> <file>sql/db_init_sqlite.sql</file>
<file>sql/db_update_sqlite_1_2.sql</file> <file>sql/db_update_sqlite_1_2.sql</file>
<file>sql/db_update_sqlite_2_3.sql</file> <file>sql/db_update_sqlite_2_3.sql</file>
<file>sql/db_update_sqlite_3_4.sql</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -42,6 +42,7 @@ CREATE TABLE Feeds (
update_type INTEGER NOT NULL CHECK (update_type >= 0), update_type INTEGER NOT NULL CHECK (update_type >= 0),
update_interval INTEGER NOT NULL DEFAULT 900 CHECK (update_interval >= 1), update_interval INTEGER NOT NULL DEFAULT 900 CHECK (update_interval >= 1),
is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1), is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1),
is_quiet INTEGER NOT NULL DEFAULT 0 CHECK (is_quiet >= 0 AND is_quiet <= 1),
open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1), open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1),
account_id INTEGER NOT NULL, account_id INTEGER NOT NULL,
custom_id TEXT NOT NULL CHECK (custom_id != ''), /* Custom ID cannot be empty, it must contain either service-specific ID, or Feeds/id. */ custom_id TEXT NOT NULL CHECK (custom_id != ''), /* Custom ID cannot be empty, it must contain either service-specific ID, or Feeds/id. */

View File

@ -0,0 +1,8 @@
USE ##;
-- !
SET FOREIGN_KEY_CHECKS = 0;
-- !
!! db_update_sqlite_3_4.sql
-- !
SET FOREIGN_KEY_CHECKS = 1;
-- !

View File

@ -0,0 +1,29 @@
ALTER TABLE Feeds RENAME TO backup_Feeds;
-- !
CREATE TABLE Feeds (
id $$,
ordr INTEGER NOT NULL CHECK (ordr >= 0),
title TEXT NOT NULL CHECK (title != ''),
description TEXT,
date_created BIGINT,
icon ^^,
category INTEGER NOT NULL CHECK (category >= -1), /* Physical category ID, also root feeds contain -1 here. */
source TEXT,
update_type INTEGER NOT NULL CHECK (update_type >= 0),
update_interval INTEGER NOT NULL DEFAULT 900 CHECK (update_interval >= 1),
is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1),
is_quiet INTEGER NOT NULL DEFAULT 0 CHECK (is_quiet >= 0 AND is_quiet <= 1),
open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1),
account_id INTEGER NOT NULL,
custom_id TEXT NOT NULL CHECK (custom_id != ''), /* Custom ID cannot be empty, it must contain either service-specific ID, or Feeds/id. */
/* Custom column for (serialized) custom account-specific data. */
custom_data TEXT,
FOREIGN KEY (account_id) REFERENCES Accounts (id) ON DELETE CASCADE
);
-- !
INSERT INTO Feeds (id, ordr, title, description, date_created, icon, category, source, update_type, update_interval, is_off, open_articles, account_id, custom_id, custom_data)
SELECT id, ordr, title, description, date_created, icon, category, source, update_type, update_interval, is_off, open_articles, account_id, custom_id, custom_data
FROM backup_Feeds;
-- !
DROP TABLE backup_Feeds;

View File

@ -2072,7 +2072,8 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
q.prepare("UPDATE Feeds " q.prepare("UPDATE Feeds "
"SET title = :title, ordr = :ordr, description = :description, date_created = :date_created, " "SET title = :title, ordr = :ordr, description = :description, date_created = :date_created, "
" icon = :icon, category = :category, source = :source, update_type = :update_type, " " icon = :icon, category = :category, source = :source, update_type = :update_type, "
" update_interval = :update_interval, is_off = :is_off, open_articles = :open_articles, " " update_interval = :update_interval, is_off = :is_off, is_quiet = :is_quiet, open_articles = "
":open_articles, "
" account_id = :account_id, custom_id = :custom_id, custom_data = :custom_data " " account_id = :account_id, custom_id = :custom_id, custom_data = :custom_data "
"WHERE id = :id;"); "WHERE id = :id;");
q.bindValue(QSL(":title"), feed->title()); q.bindValue(QSL(":title"), feed->title());
@ -2088,6 +2089,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
q.bindValue(QSL(":id"), feed->id()); q.bindValue(QSL(":id"), feed->id());
q.bindValue(QSL(":ordr"), feed->sortOrder()); q.bindValue(QSL(":ordr"), feed->sortOrder());
q.bindValue(QSL(":is_off"), feed->isSwitchedOff()); q.bindValue(QSL(":is_off"), feed->isSwitchedOff());
q.bindValue(QSL(":is_quiet"), feed->isQuiet());
q.bindValue(QSL(":open_articles"), feed->openArticlesDirectly()); q.bindValue(QSL(":open_articles"), feed->openArticlesDirectly());
auto custom_data = feed->customDatabaseData(); auto custom_data = feed->customDatabaseData();

View File

@ -34,7 +34,9 @@ class DatabaseQueries {
static bool assignLabelToMessage(const QSqlDatabase& db, Label* label, const Message& msg); static bool assignLabelToMessage(const QSqlDatabase& db, Label* label, const Message& msg);
static bool setLabelsForMessage(const QSqlDatabase& db, const QList<Label*>& labels, const Message& msg); static bool setLabelsForMessage(const QSqlDatabase& db, const QList<Label*>& labels, const Message& msg);
static QList<Label*> getLabelsForAccount(const QSqlDatabase& db, int account_id); static QList<Label*> getLabelsForAccount(const QSqlDatabase& db, int account_id);
static QList<Label*> getLabelsForMessage(const QSqlDatabase& db, const Message& msg, const QList<Label*> installed_labels); static QList<Label*> getLabelsForMessage(const QSqlDatabase& db,
const Message& msg,
const QList<Label*> installed_labels);
static bool updateLabel(const QSqlDatabase& db, Label* label); static bool updateLabel(const QSqlDatabase& db, Label* label);
static bool deleteLabel(const QSqlDatabase& db, Label* label); static bool deleteLabel(const QSqlDatabase& db, Label* label);
static bool createLabel(const QSqlDatabase& db, Label* label, int account_id); static bool createLabel(const QSqlDatabase& db, Label* label, int account_id);
@ -45,7 +47,10 @@ class DatabaseQueries {
static bool markUnreadMessagesRead(const QSqlDatabase& db, int account_id); static bool markUnreadMessagesRead(const QSqlDatabase& db, int account_id);
static bool markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read); static bool markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read);
static bool markMessageImportant(const QSqlDatabase& db, int id, RootItem::Importance importance); static bool markMessageImportant(const QSqlDatabase& db, int id, RootItem::Importance importance);
static bool markFeedsReadUnread(const QSqlDatabase& db, const QStringList& ids, int account_id, RootItem::ReadStatus read); static bool markFeedsReadUnread(const QSqlDatabase& db,
const QStringList& ids,
int account_id,
RootItem::ReadStatus read);
static bool markBinReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read); static bool markBinReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read);
static bool markAccountReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read); static bool markAccountReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read);
static bool switchMessagesImportance(const QSqlDatabase& db, const QStringList& ids); static bool switchMessagesImportance(const QSqlDatabase& db, const QStringList& ids);
@ -68,27 +73,44 @@ class DatabaseQueries {
static bool purgeLabelsAndLabelAssignments(const QSqlDatabase& db, int account_id); static bool purgeLabelsAndLabelAssignments(const QSqlDatabase& db, int account_id);
// Counts of unread/all messages. // Counts of unread/all messages.
static QMap<QString, QPair<int, int>> getMessageCountsForCategory(const QSqlDatabase& db, const QString& custom_id, static QMap<QString, QPair<int, int>> getMessageCountsForCategory(const QSqlDatabase& db,
int account_id, bool only_total_counts, const QString& custom_id,
int account_id,
bool only_total_counts,
bool* ok = nullptr); bool* ok = nullptr);
static QMap<QString, QPair<int, int>> getMessageCountsForAccount(const QSqlDatabase& db, int account_id, static QMap<QString, QPair<int, int>> getMessageCountsForAccount(const QSqlDatabase& db,
bool only_total_counts, bool* ok = nullptr); int account_id,
static int getMessageCountsForFeed(const QSqlDatabase& db, const QString& feed_custom_id, int account_id, bool only_total_counts,
bool only_total_counts, bool* ok = nullptr); bool* ok = nullptr);
static int getMessageCountsForLabel(const QSqlDatabase& db, Label* label, int account_id, static int getMessageCountsForFeed(const QSqlDatabase& db,
bool only_total_counts, bool* ok = nullptr); const QString& feed_custom_id,
static int getImportantMessageCounts(const QSqlDatabase& db, int account_id, int account_id,
bool only_total_counts, bool* ok = nullptr); bool only_total_counts,
bool* ok = nullptr);
static int getMessageCountsForLabel(const QSqlDatabase& db,
Label* label,
int account_id,
bool only_total_counts,
bool* ok = nullptr);
static int getImportantMessageCounts(const QSqlDatabase& db,
int account_id,
bool only_total_counts,
bool* ok = nullptr);
static int getUnreadMessageCounts(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static int getUnreadMessageCounts(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static int getMessageCountsForBin(const QSqlDatabase& db, int account_id, bool including_total_counts, bool* ok = nullptr); static int getMessageCountsForBin(const QSqlDatabase& db,
int account_id,
bool including_total_counts,
bool* ok = nullptr);
// Get messages (for newspaper view for example). // Get messages (for newspaper view for example).
static QList<Message> getUndeletedMessagesWithLabel(const QSqlDatabase& db, const Label* label, bool* ok = nullptr); static QList<Message> getUndeletedMessagesWithLabel(const QSqlDatabase& db, const Label* label, bool* ok = nullptr);
static QList<Message> getUndeletedLabelledMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QList<Message> getUndeletedLabelledMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QList<Message> getUndeletedImportantMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QList<Message> getUndeletedImportantMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QList<Message> getUndeletedUnreadMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QList<Message> getUndeletedUnreadMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QList<Message> getUndeletedMessagesForFeed(const QSqlDatabase& db, const QString& feed_custom_id, static QList<Message> getUndeletedMessagesForFeed(const QSqlDatabase& db,
int account_id, bool* ok = nullptr); const QString& feed_custom_id,
int account_id,
bool* ok = nullptr);
static QList<Message> getUndeletedMessagesForBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QList<Message> getUndeletedMessagesForBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QList<Message> getUndeletedMessagesForAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QList<Message> getUndeletedMessagesForAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
@ -100,23 +122,30 @@ class DatabaseQueries {
static QStringList customIdsOfUnreadMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QStringList customIdsOfUnreadMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QStringList customIdsOfMessagesFromAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QStringList customIdsOfMessagesFromAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QStringList customIdsOfMessagesFromBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QStringList customIdsOfMessagesFromBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static QStringList customIdsOfMessagesFromFeed(const QSqlDatabase& db, const QString& feed_custom_id, int account_id, static QStringList customIdsOfMessagesFromFeed(const QSqlDatabase& db,
const QString& feed_custom_id,
int account_id,
bool* ok = nullptr); bool* ok = nullptr);
// Common account methods. // Common account methods.
template<typename T> template <typename T>
static QList<ServiceRoot*> getAccounts(const QSqlDatabase& db, const QString& code, bool* ok = nullptr); static QList<ServiceRoot*> getAccounts(const QSqlDatabase& db, const QString& code, bool* ok = nullptr);
template<typename Categ, typename Fee> template <typename Categ, typename Fee> static void loadRootFromDatabase(ServiceRoot* root);
static void loadRootFromDatabase(ServiceRoot* root);
static bool storeNewOauthTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id); static bool storeNewOauthTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id);
static void createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account); static void createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account);
// Returns counts of updated messages <unread, all>. // Returns counts of updated messages <unread, all>.
static QPair<int, int> updateMessages(QSqlDatabase db, QList<Message>& messages, static QPair<int, int> updateMessages(QSqlDatabase db,
Feed* feed, bool force_update, bool* ok = nullptr); QList<Message>& messages,
Feed* feed,
bool force_update,
bool* ok = nullptr);
static bool deleteAccount(const QSqlDatabase& db, ServiceRoot* account); static bool deleteAccount(const QSqlDatabase& db, ServiceRoot* account);
static bool deleteAccountData(const QSqlDatabase& db, int account_id, bool delete_messages_too, bool delete_labels_too); static bool deleteAccountData(const QSqlDatabase& db,
int account_id,
bool delete_messages_too,
bool delete_labels_too);
static bool cleanLabelledMessages(const QSqlDatabase& db, bool clean_read_only, Label* label); static bool cleanLabelledMessages(const QSqlDatabase& db, bool clean_read_only, Label* label);
static bool cleanImportantMessages(const QSqlDatabase& db, bool clean_read_only, int account_id); static bool cleanImportantMessages(const QSqlDatabase& db, bool clean_read_only, int account_id);
static bool cleanUnreadMessages(const QSqlDatabase& db, int account_id); static bool cleanUnreadMessages(const QSqlDatabase& db, int account_id);
@ -127,12 +156,13 @@ class DatabaseQueries {
static bool deleteFeed(const QSqlDatabase& db, Feed* feed, int account_id); static bool deleteFeed(const QSqlDatabase& db, Feed* feed, int account_id);
static bool deleteCategory(const QSqlDatabase& db, Category* category); static bool deleteCategory(const QSqlDatabase& db, Category* category);
template<typename T> template <typename T> static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
template<typename T> template <typename T>
static Assignment getFeeds(const QSqlDatabase& db, const QList<MessageFilter*>& global_filters, static Assignment getFeeds(const QSqlDatabase& db,
int account_id, bool* ok = nullptr); const QList<MessageFilter*>& global_filters,
int account_id,
bool* ok = nullptr);
// Item order methods. // Item order methods.
static void moveItem(RootItem* item, bool move_top, bool move_bottom, int move_index, const QSqlDatabase& db); static void moveItem(RootItem* item, bool move_top, bool move_bottom, int move_index, const QSqlDatabase& db);
@ -144,11 +174,17 @@ class DatabaseQueries {
static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr); static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr);
static QList<MessageFilter*> getMessageFilters(const QSqlDatabase& db, bool* ok = nullptr); static QList<MessageFilter*> getMessageFilters(const QSqlDatabase& db, bool* ok = nullptr);
static QMultiMap<QString, int> messageFiltersInFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QMultiMap<QString, int> messageFiltersInFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static void assignMessageFilterToFeed(const QSqlDatabase& db, const QString& feed_custom_id, int filter_id, static void assignMessageFilterToFeed(const QSqlDatabase& db,
int account_id, bool* ok = nullptr); const QString& feed_custom_id,
int filter_id,
int account_id,
bool* ok = nullptr);
static void updateMessageFilter(const QSqlDatabase& db, MessageFilter* filter, bool* ok = nullptr); static void updateMessageFilter(const QSqlDatabase& db, MessageFilter* filter, bool* ok = nullptr);
static void removeMessageFilterFromFeed(const QSqlDatabase& db, const QString& feed_custom_id, int filter_id, static void removeMessageFilterFromFeed(const QSqlDatabase& db,
int account_id, bool* ok = nullptr); const QString& feed_custom_id,
int filter_id,
int account_id,
bool* ok = nullptr);
// Gmail account. // Gmail account.
static QStringList getAllGmailRecipients(const QSqlDatabase& db, int account_id); static QStringList getAllGmailRecipients(const QSqlDatabase& db, int account_id);
@ -159,7 +195,7 @@ class DatabaseQueries {
explicit DatabaseQueries() = default; explicit DatabaseQueries() = default;
}; };
template<typename T> template <typename T>
QList<ServiceRoot*> DatabaseQueries::getAccounts(const QSqlDatabase& db, const QString& code, bool* ok) { QList<ServiceRoot*> DatabaseQueries::getAccounts(const QSqlDatabase& db, const QString& code, bool* ok) {
QSqlQuery query(db); QSqlQuery query(db);
QList<ServiceRoot*> roots; QList<ServiceRoot*> roots;
@ -189,11 +225,8 @@ QList<ServiceRoot*> DatabaseQueries::getAccounts(const QSqlDatabase& db, const Q
} }
} }
else { else {
qWarningNN << LOGSEC_DB qWarningNN << LOGSEC_DB << "Loading of accounts with code" << QUOTE_W_SPACE(code)
<< "Loading of accounts with code" << "failed with error:" << QUOTE_W_SPACE_DOT(query.lastError().text());
<< QUOTE_W_SPACE(code)
<< "failed with error:"
<< QUOTE_W_SPACE_DOT(query.lastError().text());
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -203,8 +236,7 @@ QList<ServiceRoot*> DatabaseQueries::getAccounts(const QSqlDatabase& db, const Q
return roots; return roots;
} }
template<typename T> template <typename T> Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id, bool* ok) {
Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id, bool* ok) {
Assignment categories; Assignment categories;
// Obtain data for categories from the database. // Obtain data for categories from the database.
@ -215,7 +247,8 @@ Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id
query_categories.bindValue(QSL(":account_id"), account_id); query_categories.bindValue(QSL(":account_id"), account_id);
if (!query_categories.exec()) { if (!query_categories.exec()) {
qFatal("Query for obtaining categories failed. Error message: '%s'.", qPrintable(query_categories.lastError().text())); qFatal("Query for obtaining categories failed. Error message: '%s'.",
qPrintable(query_categories.lastError().text()));
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -254,7 +287,7 @@ Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id
return categories; return categories;
} }
template<typename T> template <typename T>
Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db, Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
const QList<MessageFilter*>& global_filters, const QList<MessageFilter*>& global_filters,
int account_id, int account_id,
@ -306,11 +339,10 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(query.value(FDS_DB_UPDATE_TYPE_INDEX).toInt())); feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(query.value(FDS_DB_UPDATE_TYPE_INDEX).toInt()));
feed->setAutoUpdateInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt()); feed->setAutoUpdateInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt());
feed->setIsSwitchedOff(query.value(FDS_DB_IS_OFF_INDEX).toBool()); feed->setIsSwitchedOff(query.value(FDS_DB_IS_OFF_INDEX).toBool());
feed->setIsQuiet(query.value(FDS_DB_IS_QUIET_INDEX).toBool());
feed->setOpenArticlesDirectly(query.value(FDS_DB_OPEN_ARTICLES_INDEX).toBool()); feed->setOpenArticlesDirectly(query.value(FDS_DB_OPEN_ARTICLES_INDEX).toBool());
qDebugNN << LOGSEC_CORE qDebugNN << LOGSEC_CORE << "Custom ID of feed when loading from DB is" << QUOTE_W_SPACE_DOT(feed->customId());
<< "Custom ID of feed when loading from DB is"
<< QUOTE_W_SPACE_DOT(feed->customId());
// Load custom data. // Load custom data.
feed->setCustomDatabaseData(deserializeCustomData(query.value(FDS_DB_CUSTOM_DATA_INDEX).toString())); feed->setCustomDatabaseData(deserializeCustomData(query.value(FDS_DB_CUSTOM_DATA_INDEX).toString()));
@ -333,8 +365,7 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
return feeds; return feeds;
} }
template<typename Categ, typename Fee> template <typename Categ, typename Fee> void DatabaseQueries::loadRootFromDatabase(ServiceRoot* root) {
void DatabaseQueries::loadRootFromDatabase(ServiceRoot* root) {
QSqlDatabase database = qApp->database()->driver()->connection(root->metaObject()->className()); QSqlDatabase database = qApp->database()->driver()->connection(root->metaObject()->className());
Assignment categories = DatabaseQueries::getCategories<Categ>(database, root->accountId()); Assignment categories = DatabaseQueries::getCategories<Categ>(database, root->accountId());
Assignment feeds = DatabaseQueries::getFeeds<Fee>(database, qApp->feedReader()->messageFilters(), root->accountId()); Assignment feeds = DatabaseQueries::getFeeds<Fee>(database, qApp->feedReader()->messageFilters(), root->accountId());

View File

@ -205,7 +205,7 @@
#define APP_DB_SQLITE_FILE "database.db" #define APP_DB_SQLITE_FILE "database.db"
// Keep this in sync with schema versions declared in SQL initialization code. // Keep this in sync with schema versions declared in SQL initialization code.
#define APP_DB_SCHEMA_VERSION "3" #define APP_DB_SCHEMA_VERSION "4"
#define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql" #define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql"
#define APP_DB_COMMENT_SPLIT "-- !\n" #define APP_DB_COMMENT_SPLIT "-- !\n"
#define APP_DB_INCLUDE_PLACEHOLDER "!!" #define APP_DB_INCLUDE_PLACEHOLDER "!!"
@ -284,10 +284,11 @@
#define FDS_DB_UPDATE_TYPE_INDEX 8 #define FDS_DB_UPDATE_TYPE_INDEX 8
#define FDS_DB_UPDATE_INTERVAL_INDEX 9 #define FDS_DB_UPDATE_INTERVAL_INDEX 9
#define FDS_DB_IS_OFF_INDEX 10 #define FDS_DB_IS_OFF_INDEX 10
#define FDS_DB_OPEN_ARTICLES_INDEX 11 #define FDS_DB_IS_QUIET_INDEX 11
#define FDS_DB_ACCOUNT_ID_INDEX 12 #define FDS_DB_OPEN_ARTICLES_INDEX 12
#define FDS_DB_CUSTOM_ID_INDEX 13 #define FDS_DB_ACCOUNT_ID_INDEX 13
#define FDS_DB_CUSTOM_DATA_INDEX 14 #define FDS_DB_CUSTOM_ID_INDEX 14
#define FDS_DB_CUSTOM_DATA_INDEX 15
// Indexes of columns for feed models. // Indexes of columns for feed models.
#define FDS_MODEL_TITLE_INDEX 0 #define FDS_MODEL_TITLE_INDEX 0

View File

@ -22,8 +22,8 @@
Feed::Feed(RootItem* parent) Feed::Feed(RootItem* parent)
: RootItem(parent), m_source(QString()), m_status(Status::Normal), m_statusString(QString()), : RootItem(parent), m_source(QString()), m_status(Status::Normal), m_statusString(QString()),
m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInterval(DEFAULT_AUTO_UPDATE_INTERVAL),
m_lastUpdated(QDateTime::currentDateTimeUtc()), m_isSwitchedOff(false), m_openArticlesDirectly(false), m_lastUpdated(QDateTime::currentDateTimeUtc()), m_isSwitchedOff(false), m_isQuiet(false),
m_messageFilters(QList<QPointer<MessageFilter>>()) { m_openArticlesDirectly(false), m_messageFilters(QList<QPointer<MessageFilter>>()) {
setKind(RootItem::Kind::Feed); setKind(RootItem::Kind::Feed);
} }
@ -46,6 +46,7 @@ Feed::Feed(const Feed& other) : RootItem(other) {
setMessageFilters(other.messageFilters()); setMessageFilters(other.messageFilters());
setOpenArticlesDirectly(other.openArticlesDirectly()); setOpenArticlesDirectly(other.openArticlesDirectly());
setIsSwitchedOff(other.isSwitchedOff()); setIsSwitchedOff(other.isSwitchedOff());
setIsQuiet(other.isQuiet());
} }
QList<Message> Feed::undeletedMessages() const { QList<Message> Feed::undeletedMessages() const {
@ -283,6 +284,14 @@ QString Feed::getStatusDescription() const {
} }
} }
bool Feed::isQuiet() const {
return m_isQuiet;
}
void Feed::setIsQuiet(bool quiet) {
m_isQuiet = quiet;
}
QDateTime Feed::lastUpdated() const { QDateTime Feed::lastUpdated() const {
return m_lastUpdated; return m_lastUpdated;
} }

View File

@ -72,6 +72,9 @@ class Feed : public RootItem {
bool isSwitchedOff() const; bool isSwitchedOff() const;
void setIsSwitchedOff(bool switched_off); void setIsSwitchedOff(bool switched_off);
bool isQuiet() const;
void setIsQuiet(bool quiet);
void appendMessageFilter(MessageFilter* filter); void appendMessageFilter(MessageFilter* filter);
QList<QPointer<MessageFilter>> messageFilters() const; QList<QPointer<MessageFilter>> messageFilters() const;
void setMessageFilters(const QList<QPointer<MessageFilter>>& messageFilters); void setMessageFilters(const QList<QPointer<MessageFilter>>& messageFilters);
@ -79,7 +82,6 @@ class Feed : public RootItem {
QDateTime lastUpdated() const; QDateTime lastUpdated() const;
void setLastUpdated(const QDateTime& last_updated); void setLastUpdated(const QDateTime& last_updated);
public slots: public slots:
virtual void updateCounts(bool including_total_count); virtual void updateCounts(bool including_total_count);
@ -95,6 +97,7 @@ class Feed : public RootItem {
int m_autoUpdateInterval{}; // In seconds. int m_autoUpdateInterval{}; // In seconds.
QDateTime m_lastUpdated; QDateTime m_lastUpdated;
bool m_isSwitchedOff; bool m_isSwitchedOff;
bool m_isQuiet;
bool m_openArticlesDirectly; bool m_openArticlesDirectly;
int m_totalCount{}; int m_totalCount{};
int m_unreadCount{}; int m_unreadCount{};

View File

@ -50,6 +50,7 @@ void FormFeedDetails::apply() {
m_feed->setAutoUpdateInterval(int(m_ui->m_spinAutoUpdateInterval->value())); m_feed->setAutoUpdateInterval(int(m_ui->m_spinAutoUpdateInterval->value()));
m_feed->setOpenArticlesDirectly(m_ui->m_cbOpenArticlesAutomatically->isChecked()); m_feed->setOpenArticlesDirectly(m_ui->m_cbOpenArticlesAutomatically->isChecked());
m_feed->setIsSwitchedOff(m_ui->m_cbDisableFeed->isChecked()); m_feed->setIsSwitchedOff(m_ui->m_cbDisableFeed->isChecked());
m_feed->setIsQuiet(m_ui->m_cbSuppressFeed->isChecked());
if (!m_creatingNew) { if (!m_creatingNew) {
// We need to make sure that common data are saved. // We need to make sure that common data are saved.
@ -97,6 +98,7 @@ void FormFeedDetails::loadFeedData() {
m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInterval()); m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInterval());
m_ui->m_cbOpenArticlesAutomatically->setChecked(m_feed->openArticlesDirectly()); m_ui->m_cbOpenArticlesAutomatically->setChecked(m_feed->openArticlesDirectly());
m_ui->m_cbDisableFeed->setChecked(m_feed->isSwitchedOff()); m_ui->m_cbDisableFeed->setChecked(m_feed->isSwitchedOff());
m_ui->m_cbSuppressFeed->setChecked(m_feed->isQuiet());
} }
void FormFeedDetails::acceptIfPossible() { void FormFeedDetails::acceptIfPossible() {

View File

@ -66,13 +66,20 @@
<string>Miscellaneous</string> <string>Miscellaneous</string>
</attribute> </attribute>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="m_cbDisableFeed"> <widget class="QCheckBox" name="m_cbDisableFeed">
<property name="text"> <property name="text">
<string>Disable this feed</string> <string>Disable this feed</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="m_cbSuppressFeed">
<property name="text">
<string>Suppress this feed</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
@ -99,6 +106,14 @@
<header>timespinbox.h</header> <header>timespinbox.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>m_tabWidget</tabstop>
<tabstop>m_cmbAutoUpdateType</tabstop>
<tabstop>m_spinAutoUpdateInterval</tabstop>
<tabstop>m_cbOpenArticlesAutomatically</tabstop>
<tabstop>m_cbSuppressFeed</tabstop>
<tabstop>m_cbDisableFeed</tabstop>
</tabstops>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>

View File

@ -374,6 +374,7 @@ QMap<QString, QVariantMap> ServiceRoot::storeCustomFeedsData() {
feed_custom_data.insert(QSL("auto_update_type"), int(feed->autoUpdateType())); feed_custom_data.insert(QSL("auto_update_type"), int(feed->autoUpdateType()));
feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters())); feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters()));
feed_custom_data.insert(QSL("is_off"), feed->isSwitchedOff()); feed_custom_data.insert(QSL("is_off"), feed->isSwitchedOff());
feed_custom_data.insert(QSL("is_quiet"), feed->isQuiet());
feed_custom_data.insert(QSL("open_articles_directly"), feed->openArticlesDirectly()); feed_custom_data.insert(QSL("open_articles_directly"), feed->openArticlesDirectly());
// NOTE: These are here specifically to be able to restore custom sort order. // NOTE: These are here specifically to be able to restore custom sort order.
@ -406,6 +407,7 @@ void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariantMap>& data,
feed->setMessageFilters(feed_custom_data.value(QSL("msg_filters")).value<QList<QPointer<MessageFilter>>>()); feed->setMessageFilters(feed_custom_data.value(QSL("msg_filters")).value<QList<QPointer<MessageFilter>>>());
feed->setIsSwitchedOff(feed_custom_data.value(QSL("is_off")).toBool()); feed->setIsSwitchedOff(feed_custom_data.value(QSL("is_off")).toBool());
feed->setIsQuiet(feed_custom_data.value(QSL("is_quiet")).toBool());
feed->setOpenArticlesDirectly(feed_custom_data.value(QSL("open_articles_directly")).toBool()); feed->setOpenArticlesDirectly(feed_custom_data.value(QSL("open_articles_directly")).toBool());
} }
} }