save
This commit is contained in:
parent
aef6b14bf2
commit
a10cc039f1
@ -225,40 +225,24 @@ void MessagesModel::setupHeaderData() {
|
||||
m_headerData <<
|
||||
|
||||
/*: Tooltip for ID of message.*/ tr("Id") <<
|
||||
|
||||
/*: Tooltip for "read" column in msg list.*/ tr("Read") <<
|
||||
|
||||
/*: Tooltip for "important" column in msg list.*/ tr("Important") <<
|
||||
|
||||
/*: Tooltip for "deleted" column in msg list.*/ tr("Deleted") <<
|
||||
|
||||
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
|
||||
|
||||
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID") <<
|
||||
|
||||
/*: Tooltip for title of message.*/ tr("Title") <<
|
||||
|
||||
/*: Tooltip for url of message.*/ tr("Url") <<
|
||||
|
||||
/*: Tooltip for author of message.*/ tr("Author") <<
|
||||
|
||||
/*: Tooltip for creation date of message.*/ tr("Date") <<
|
||||
|
||||
/*: Tooltip for contents of message.*/ tr("Contents") <<
|
||||
|
||||
/*: Tooltip for attachments of message.*/ tr("Attachments") <<
|
||||
|
||||
/*: Tooltip for score of message.*/ tr("Score") <<
|
||||
|
||||
/*: Tooltip for account ID of message.*/ tr("Account ID") <<
|
||||
|
||||
/*: Tooltip for custom ID of message.*/ tr("Custom ID") <<
|
||||
|
||||
/*: Tooltip for custom hash string of message.*/ tr("Custom hash") <<
|
||||
|
||||
/*: Tooltip for name of feed for message.*/ tr("Feed") <<
|
||||
|
||||
/*: Tooltip for indication of presence of enclosures.*/ tr("Has enclosures");
|
||||
/*: Tooltip for indication of presence of enclosures.*/ tr("Has enclosures") <<
|
||||
/*: Tooltip for indication of labels of message.*/ tr("Assigned labels");
|
||||
|
||||
m_tooltipData << tr("ID of the article.") << tr("Is article read?") << tr("Is article important?")
|
||||
<< tr("Is article deleted?") << tr("Is article permanently deleted from recycle bin?")
|
||||
@ -267,7 +251,7 @@ void MessagesModel::setupHeaderData() {
|
||||
<< tr("Contents of the article.") << tr("List of attachments.") << tr("Score of the article.")
|
||||
<< tr("Account ID of the article.") << tr("Custom ID of the article.")
|
||||
<< tr("Custom hash of the article.") << tr("Name of feed of the article.")
|
||||
<< tr("Indication of enclosures presence within the article.");
|
||||
<< tr("Indication of enclosures presence within the article.") << tr("Labels assigned to the article.");
|
||||
}
|
||||
|
||||
Qt::ItemFlags MessagesModel::flags(const QModelIndex& index) const {
|
||||
|
@ -37,6 +37,9 @@ QMap<int, QString> DatabaseQueries::messageTableAttributes(bool only_msg_table)
|
||||
"THEN 'true' "
|
||||
"ELSE 'false' "
|
||||
"END AS has_enclosures");
|
||||
field_names[18] = QSL("(SELECT GROUP_CONCAT(Labels.name) FROM Labels WHERE Labels.id IN (SELECT "
|
||||
"LabelsInMessages.label FROM LabelsInMessages WHERE LabelsInMessages.account_id = "
|
||||
"Messages.account_id AND LabelsInMessages.message = Messages.custom_id))");
|
||||
|
||||
return field_names;
|
||||
}
|
||||
@ -270,7 +273,9 @@ bool DatabaseQueries::markLabelledMessagesReadUnread(const QSqlDatabase& db, Lab
|
||||
" is_deleted = 0 AND "
|
||||
" is_pdeleted = 0 AND "
|
||||
" account_id = :account_id AND "
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"));
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND "
|
||||
"Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = "
|
||||
"LabelsInMessages.message);"));
|
||||
q.bindValue(QSL(":read"), read == RootItem::ReadStatus::Read ? 1 : 0);
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
q.bindValue(QSL(":label"), label->customId());
|
||||
@ -278,7 +283,9 @@ bool DatabaseQueries::markLabelledMessagesReadUnread(const QSqlDatabase& db, Lab
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read) {
|
||||
bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db,
|
||||
int account_id,
|
||||
RootItem::ReadStatus read) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -300,7 +307,9 @@ bool DatabaseQueries::markUnreadMessagesRead(const QSqlDatabase& db, int account
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
bool DatabaseQueries::markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read) {
|
||||
bool DatabaseQueries::markMessagesReadUnread(const QSqlDatabase& db,
|
||||
const QStringList& ids,
|
||||
RootItem::ReadStatus read) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -314,24 +323,27 @@ bool DatabaseQueries::markMessageImportant(const QSqlDatabase& db, int id, RootI
|
||||
q.setForwardOnly(true);
|
||||
|
||||
if (!q.prepare(QSL("UPDATE Messages SET is_important = :important WHERE id = :id;"))) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Query preparation failed for message importance switch.";
|
||||
qWarningNN << LOGSEC_DB << "Query preparation failed for message importance switch.";
|
||||
return false;
|
||||
}
|
||||
|
||||
q.bindValue(QSL(":id"), id);
|
||||
q.bindValue(QSL(":important"), (int) importance);
|
||||
q.bindValue(QSL(":important"), (int)importance);
|
||||
|
||||
// Commit changes.
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
bool DatabaseQueries::markFeedsReadUnread(const QSqlDatabase& db, const QStringList& ids, int account_id, RootItem::ReadStatus read) {
|
||||
bool DatabaseQueries::markFeedsReadUnread(const QSqlDatabase& db,
|
||||
const QStringList& ids,
|
||||
int account_id,
|
||||
RootItem::ReadStatus read) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("UPDATE Messages SET is_read = :read "
|
||||
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;").arg(ids.join(QSL(", "))));
|
||||
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")
|
||||
.arg(ids.join(QSL(", "))));
|
||||
q.bindValue(QSL(":read"), read == RootItem::ReadStatus::Read ? 1 : 0);
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
return q.exec();
|
||||
@ -376,9 +388,8 @@ bool DatabaseQueries::deleteOrRestoreMessagesToFromBin(const QSqlDatabase& db, c
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
return q.exec(QSL("UPDATE Messages SET is_deleted = %2, is_pdeleted = %3 WHERE id IN (%1);").arg(ids.join(QSL(", ")),
|
||||
QString::number(deleted ? 1 : 0),
|
||||
QString::number(0)));
|
||||
return q.exec(QSL("UPDATE Messages SET is_deleted = %2, is_pdeleted = %3 WHERE id IN (%1);")
|
||||
.arg(ids.join(QSL(", ")), QString::number(deleted ? 1 : 0), QString::number(0)));
|
||||
}
|
||||
|
||||
bool DatabaseQueries::restoreBin(const QSqlDatabase& db, int account_id) {
|
||||
@ -469,12 +480,14 @@ QMap<QString, QPair<int, int>> DatabaseQueries::getMessageCountsForCategory(cons
|
||||
|
||||
if (only_total_counts) {
|
||||
q.prepare(QSL("SELECT feed, sum((is_read + 1) % 2), count(*) FROM Messages "
|
||||
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
|
||||
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) "
|
||||
"AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
|
||||
"GROUP BY feed;"));
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("SELECT feed, sum((is_read + 1) % 2) FROM Messages "
|
||||
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
|
||||
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) "
|
||||
"AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
|
||||
"GROUP BY feed;"));
|
||||
}
|
||||
|
||||
@ -509,8 +522,10 @@ QMap<QString, QPair<int, int>> DatabaseQueries::getMessageCountsForCategory(cons
|
||||
return counts;
|
||||
}
|
||||
|
||||
QMap<QString, QPair<int, int>> DatabaseQueries::getMessageCountsForAccount(const QSqlDatabase& db, int account_id,
|
||||
bool only_total_counts, bool* ok) {
|
||||
QMap<QString, QPair<int, int>> DatabaseQueries::getMessageCountsForAccount(const QSqlDatabase& db,
|
||||
int account_id,
|
||||
bool only_total_counts,
|
||||
bool* ok) {
|
||||
QMap<QString, QPair<int, int>> counts;
|
||||
QSqlQuery q(db);
|
||||
|
||||
@ -557,8 +572,11 @@ QMap<QString, QPair<int, int>> DatabaseQueries::getMessageCountsForAccount(const
|
||||
return counts;
|
||||
}
|
||||
|
||||
int DatabaseQueries::getMessageCountsForFeed(const QSqlDatabase& db, const QString& feed_custom_id,
|
||||
int account_id, bool only_total_counts, bool* ok) {
|
||||
int DatabaseQueries::getMessageCountsForFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
bool only_total_counts,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -569,7 +587,8 @@ int DatabaseQueries::getMessageCountsForFeed(const QSqlDatabase& db, const QStri
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("SELECT count(*) FROM Messages "
|
||||
"WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 0 AND account_id = :account_id;"));
|
||||
"WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 0 AND account_id = "
|
||||
":account_id;"));
|
||||
}
|
||||
|
||||
q.bindValue(QSL(":feed"), feed_custom_id);
|
||||
@ -591,7 +610,11 @@ int DatabaseQueries::getMessageCountsForFeed(const QSqlDatabase& db, const QStri
|
||||
}
|
||||
}
|
||||
|
||||
int DatabaseQueries::getMessageCountsForLabel(const QSqlDatabase& db, Label* label, int account_id, bool only_total_counts, bool* ok) {
|
||||
int DatabaseQueries::getMessageCountsForLabel(const QSqlDatabase& db,
|
||||
Label* label,
|
||||
int account_id,
|
||||
bool only_total_counts,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -601,7 +624,8 @@ int DatabaseQueries::getMessageCountsForLabel(const QSqlDatabase& db, Label* lab
|
||||
"INNER JOIN LabelsInMessages "
|
||||
"ON "
|
||||
" Messages.is_pdeleted = 0 AND Messages.is_deleted = 0 AND "
|
||||
" LabelsInMessages.account_id = :account_id AND LabelsInMessages.account_id = Messages.account_id AND "
|
||||
" LabelsInMessages.account_id = :account_id AND LabelsInMessages.account_id = Messages.account_id "
|
||||
"AND "
|
||||
" LabelsInMessages.label = :label AND LabelsInMessages.message = Messages.custom_id;"));
|
||||
}
|
||||
else {
|
||||
@ -609,7 +633,8 @@ int DatabaseQueries::getMessageCountsForLabel(const QSqlDatabase& db, Label* lab
|
||||
"INNER JOIN LabelsInMessages "
|
||||
"ON "
|
||||
" Messages.is_pdeleted = 0 AND Messages.is_deleted = 0 AND Messages.is_read = 0 AND "
|
||||
" LabelsInMessages.account_id = :account_id AND LabelsInMessages.account_id = Messages.account_id AND "
|
||||
" LabelsInMessages.account_id = :account_id AND LabelsInMessages.account_id = Messages.account_id "
|
||||
"AND "
|
||||
" LabelsInMessages.label = :label AND LabelsInMessages.message = Messages.custom_id;"));
|
||||
}
|
||||
|
||||
@ -632,7 +657,10 @@ int DatabaseQueries::getMessageCountsForLabel(const QSqlDatabase& db, Label* lab
|
||||
}
|
||||
}
|
||||
|
||||
int DatabaseQueries::getImportantMessageCounts(const QSqlDatabase& db, int account_id, bool only_total_counts, bool* ok) {
|
||||
int DatabaseQueries::getImportantMessageCounts(const QSqlDatabase& db,
|
||||
int account_id,
|
||||
bool only_total_counts,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -643,7 +671,8 @@ int DatabaseQueries::getImportantMessageCounts(const QSqlDatabase& db, int accou
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("SELECT count(*) FROM Messages "
|
||||
"WHERE is_read = 0 AND is_important = 1 AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"));
|
||||
"WHERE is_read = 0 AND is_important = 1 AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = "
|
||||
":account_id;"));
|
||||
}
|
||||
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
@ -689,7 +718,10 @@ int DatabaseQueries::getUnreadMessageCounts(const QSqlDatabase& db, int account_
|
||||
}
|
||||
}
|
||||
|
||||
int DatabaseQueries::getMessageCountsForBin(const QSqlDatabase& db, int account_id, bool including_total_counts, bool* ok) {
|
||||
int DatabaseQueries::getMessageCountsForBin(const QSqlDatabase& db,
|
||||
int account_id,
|
||||
bool including_total_counts,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
@ -728,13 +760,15 @@ QList<Message> DatabaseQueries::getUndeletedMessagesWithLabel(const QSqlDatabase
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"INNER JOIN Feeds "
|
||||
"ON Messages.feed = Feeds.custom_id AND Messages.account_id = :account_id AND Messages.account_id = Feeds.account_id "
|
||||
"ON Messages.feed = Feeds.custom_id AND Messages.account_id = :account_id AND Messages.account_id = "
|
||||
"Feeds.account_id "
|
||||
"INNER JOIN LabelsInMessages "
|
||||
"ON "
|
||||
" Messages.is_pdeleted = 0 AND Messages.is_deleted = 0 AND "
|
||||
" LabelsInMessages.account_id = :account_id AND LabelsInMessages.account_id = Messages.account_id AND "
|
||||
" LabelsInMessages.label = :label AND "
|
||||
" LabelsInMessages.message = Messages.custom_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
" LabelsInMessages.message = Messages.custom_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
q.bindValue(QSL(":label"), label->customId());
|
||||
|
||||
@ -772,7 +806,8 @@ QList<Message> DatabaseQueries::getUndeletedLabelledMessages(const QSqlDatabase&
|
||||
"WHERE Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = :account_id AND "
|
||||
" (SELECT COUNT(*) FROM LabelsInMessages "
|
||||
" WHERE account_id = :account_id AND "
|
||||
" message = Messages.custom_id) > 0;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
" message = Messages.custom_id) > 0;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (q.exec()) {
|
||||
@ -806,7 +841,8 @@ QList<Message> DatabaseQueries::getUndeletedImportantMessages(const QSqlDatabase
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_important = 1 AND is_deleted = 0 AND "
|
||||
" is_pdeleted = 0 AND account_id = :account_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
" is_pdeleted = 0 AND account_id = :account_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (q.exec()) {
|
||||
@ -840,7 +876,8 @@ QList<Message> DatabaseQueries::getUndeletedUnreadMessages(const QSqlDatabase& d
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_read = 0 AND is_deleted = 0 AND "
|
||||
" is_pdeleted = 0 AND account_id = :account_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
" is_pdeleted = 0 AND account_id = :account_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (q.exec()) {
|
||||
@ -866,8 +903,10 @@ QList<Message> DatabaseQueries::getUndeletedUnreadMessages(const QSqlDatabase& d
|
||||
return messages;
|
||||
}
|
||||
|
||||
QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(const QSqlDatabase& db, const QString& feed_custom_id,
|
||||
int account_id, bool* ok) {
|
||||
QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
bool* ok) {
|
||||
QList<Message> messages;
|
||||
QSqlQuery q(db);
|
||||
|
||||
@ -875,7 +914,8 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(const QSqlDatabase&
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND "
|
||||
" feed = :feed AND account_id = :account_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
" feed = :feed AND account_id = :account_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":feed"), feed_custom_id);
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
@ -909,7 +949,8 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForBin(const QSqlDatabase& d
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (q.exec()) {
|
||||
@ -942,7 +983,8 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForAccount(const QSqlDatabas
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("SELECT %1 "
|
||||
"FROM Messages "
|
||||
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;").arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")
|
||||
.arg(messageTableAttributes(true).values().join(QSL(", "))));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (q.exec()) {
|
||||
@ -992,7 +1034,8 @@ QStringList DatabaseQueries::bagOfMessages(const QSqlDatabase& db, ServiceRoot::
|
||||
|
||||
q.prepare(QSL("SELECT custom_id "
|
||||
"FROM Messages "
|
||||
"WHERE %1 AND feed = :feed AND account_id = :account_id;").arg(query));
|
||||
"WHERE %1 AND feed = :feed AND account_id = :account_id;")
|
||||
.arg(query));
|
||||
|
||||
q.bindValue(QSL(":account_id"), feed->getParentServiceRoot()->accountId());
|
||||
q.bindValue(QSL(":feed"), feed->customId());
|
||||
@ -1015,7 +1058,7 @@ QHash<QString, QStringList> DatabaseQueries::bagsOfMessages(const QSqlDatabase&
|
||||
"FROM LabelsInMessages "
|
||||
"WHERE label = :label AND account_id = :account_id;"));
|
||||
|
||||
for (const Label* lbl :labels) {
|
||||
for (const Label* lbl : labels) {
|
||||
q.bindValue(QSL(":label"), lbl->customId());
|
||||
q.bindValue(QSL(":account_id"), lbl->getParentServiceRoot()->accountId());
|
||||
q.exec();
|
||||
@ -1039,11 +1082,11 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
bool* ok) {
|
||||
if (messages.isEmpty()) {
|
||||
*ok = true;
|
||||
return { 0, 0 };
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
bool use_transactions = qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool();
|
||||
QPair<int, int> updated_messages = { 0, 0 };
|
||||
QPair<int, int> updated_messages = {0, 0};
|
||||
int account_id = feed->getParentServiceRoot()->accountId();
|
||||
auto feed_custom_id = feed->customId();
|
||||
|
||||
@ -1065,40 +1108,47 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
// NOTE: This only applies to messages from standard RSS/ATOM/JSON feeds without ID/GUID.
|
||||
query_select_with_url.setForwardOnly(true);
|
||||
query_select_with_url.prepare(QSL("SELECT id, date_created, is_read, is_important, contents, feed FROM Messages "
|
||||
"WHERE feed = :feed AND title = :title AND url = :url AND author = :author AND account_id = :account_id;"));
|
||||
"WHERE feed = :feed AND title = :title AND url = :url AND author = :author AND "
|
||||
"account_id = :account_id;"));
|
||||
|
||||
// When we have custom ID of the message which is service-specific (synchronized services).
|
||||
query_select_with_custom_id.setForwardOnly(true);
|
||||
query_select_with_custom_id.prepare(QSL("SELECT id, date_created, is_read, is_important, contents, feed, title, author FROM Messages "
|
||||
query_select_with_custom_id
|
||||
.prepare(QSL("SELECT id, date_created, is_read, is_important, contents, feed, title, author FROM Messages "
|
||||
"WHERE custom_id = :custom_id AND account_id = :account_id;"));
|
||||
|
||||
// We have custom ID of message, but it is feed-specific not service-specific (standard RSS/ATOM/JSON).
|
||||
query_select_with_custom_id_for_feed.setForwardOnly(true);
|
||||
query_select_with_custom_id_for_feed.prepare(QSL("SELECT id, date_created, is_read, is_important, contents, title, author FROM Messages "
|
||||
query_select_with_custom_id_for_feed
|
||||
.prepare(QSL("SELECT id, date_created, is_read, is_important, contents, title, author FROM Messages "
|
||||
"WHERE feed = :feed AND custom_id = :custom_id AND account_id = :account_id;"));
|
||||
|
||||
// In some case, messages are already stored in the DB and they all have primary DB ID.
|
||||
// This is particularly the case when user runs some message filter manually on existing messages
|
||||
// of some feed.
|
||||
query_select_with_id.setForwardOnly(true);
|
||||
query_select_with_id.prepare(QSL("SELECT date_created, is_read, is_important, contents, feed, title, author FROM Messages "
|
||||
query_select_with_id
|
||||
.prepare(QSL("SELECT date_created, is_read, is_important, contents, feed, title, author FROM Messages "
|
||||
"WHERE id = :id AND account_id = :account_id;"));
|
||||
|
||||
// Used to insert new messages.
|
||||
query_insert.setForwardOnly(true);
|
||||
query_insert.prepare(QSL("INSERT INTO Messages "
|
||||
"(feed, title, is_read, is_important, is_deleted, url, author, score, date_created, contents, enclosures, custom_id, custom_hash, account_id) "
|
||||
"VALUES (:feed, :title, :is_read, :is_important, :is_deleted, :url, :author, :score, :date_created, :contents, :enclosures, :custom_id, :custom_hash, :account_id);"));
|
||||
"(feed, title, is_read, is_important, is_deleted, url, author, score, date_created, "
|
||||
"contents, enclosures, custom_id, custom_hash, account_id) "
|
||||
"VALUES (:feed, :title, :is_read, :is_important, :is_deleted, :url, :author, :score, "
|
||||
":date_created, :contents, :enclosures, :custom_id, :custom_hash, :account_id);"));
|
||||
|
||||
// Used to update existing messages.
|
||||
query_update.setForwardOnly(true);
|
||||
query_update.prepare(QSL("UPDATE Messages "
|
||||
"SET title = :title, is_read = :is_read, is_important = :is_important, is_deleted = :is_deleted, url = :url, author = :author, score = :score, date_created = :date_created, contents = :contents, enclosures = :enclosures, feed = :feed "
|
||||
"SET title = :title, is_read = :is_read, is_important = :is_important, is_deleted = "
|
||||
":is_deleted, url = :url, author = :author, score = :score, date_created = :date_created, "
|
||||
"contents = :contents, enclosures = :enclosures, feed = :feed "
|
||||
"WHERE id = :id;"));
|
||||
|
||||
if (use_transactions && !db.transaction()) {
|
||||
qCriticalNN << LOGSEC_DB
|
||||
<< "Transaction start for message downloader failed:"
|
||||
qCriticalNN << LOGSEC_DB << "Transaction start for message downloader failed:"
|
||||
<< QUOTE_W_SPACE_DOT(query_begin_transaction.lastError().text());
|
||||
return updated_messages;
|
||||
}
|
||||
@ -1121,9 +1171,7 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
query_select_with_id.bindValue(QSL(":id"), message.m_id);
|
||||
query_select_with_id.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Checking if message with primary ID"
|
||||
<< QUOTE_W_SPACE(message.m_id)
|
||||
qDebugNN << LOGSEC_DB << "Checking if message with primary ID" << QUOTE_W_SPACE(message.m_id)
|
||||
<< "is present in DB.";
|
||||
|
||||
if (query_select_with_id.exec() && query_select_with_id.next()) {
|
||||
@ -1136,13 +1184,11 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
title_existing_message = query_select_with_id.value(5).toString();
|
||||
author_existing_message = query_select_with_id.value(6).toString();
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Message with direct DB ID is already present in DB and has DB ID"
|
||||
qDebugNN << LOGSEC_DB << "Message with direct DB ID is already present in DB and has DB ID"
|
||||
<< QUOTE_W_SPACE_DOT(id_existing_message);
|
||||
}
|
||||
else if (query_select_with_id.lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to check for existing message in DB via primary ID:"
|
||||
qWarningNN << LOGSEC_DB << "Failed to check for existing message in DB via primary ID:"
|
||||
<< QUOTE_W_SPACE_DOT(query_select_with_id.lastError().text());
|
||||
}
|
||||
|
||||
@ -1158,13 +1204,8 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
query_select_with_url.bindValue(QSL(":author"), unnulifyString(message.m_author));
|
||||
query_select_with_url.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Checking if message with title "
|
||||
<< QUOTE_NO_SPACE(message.m_title)
|
||||
<< ", url "
|
||||
<< QUOTE_NO_SPACE(message.m_url)
|
||||
<< "' and author "
|
||||
<< QUOTE_NO_SPACE(message.m_author)
|
||||
qDebugNN << LOGSEC_DB << "Checking if message with title " << QUOTE_NO_SPACE(message.m_title) << ", url "
|
||||
<< QUOTE_NO_SPACE(message.m_url) << "' and author " << QUOTE_NO_SPACE(message.m_author)
|
||||
<< " is present in DB.";
|
||||
|
||||
if (query_select_with_url.exec() && query_select_with_url.next()) {
|
||||
@ -1177,13 +1218,11 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
title_existing_message = unnulifyString(message.m_title);
|
||||
author_existing_message = unnulifyString(message.m_author);
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Message with these attributes is already present in DB and has DB ID"
|
||||
qDebugNN << LOGSEC_DB << "Message with these attributes is already present in DB and has DB ID"
|
||||
<< QUOTE_W_SPACE_DOT(id_existing_message);
|
||||
}
|
||||
else if (query_select_with_url.lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to check for existing message in DB via URL/TITLE/AUTHOR:"
|
||||
qWarningNN << LOGSEC_DB << "Failed to check for existing message in DB via URL/TITLE/AUTHOR:"
|
||||
<< QUOTE_W_SPACE_DOT(query_select_with_url.lastError().text());
|
||||
}
|
||||
|
||||
@ -1197,10 +1236,8 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
query_select_with_custom_id.bindValue(QSL(":account_id"), account_id);
|
||||
query_select_with_custom_id.bindValue(QSL(":custom_id"), unnulifyString(message.m_customId));
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Checking if message with service-specific custom ID"
|
||||
<< QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is present in DB.";
|
||||
qDebugNN << LOGSEC_DB << "Checking if message with service-specific custom ID"
|
||||
<< QUOTE_W_SPACE(message.m_customId) << "is present in DB.";
|
||||
|
||||
if (query_select_with_custom_id.exec() && query_select_with_custom_id.next()) {
|
||||
id_existing_message = query_select_with_custom_id.value(0).toInt();
|
||||
@ -1212,16 +1249,11 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
title_existing_message = query_select_with_custom_id.value(6).toString();
|
||||
author_existing_message = query_select_with_custom_id.value(7).toString();
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Message with custom ID"
|
||||
<< QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is already present in DB and has DB ID '"
|
||||
<< id_existing_message
|
||||
<< "'.";
|
||||
qDebugNN << LOGSEC_DB << "Message with custom ID" << QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is already present in DB and has DB ID '" << id_existing_message << "'.";
|
||||
}
|
||||
else if (query_select_with_custom_id.lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to check for existing message in DB via ID:"
|
||||
qWarningNN << LOGSEC_DB << "Failed to check for existing message in DB via ID:"
|
||||
<< QUOTE_W_SPACE_DOT(query_select_with_custom_id.lastError().text());
|
||||
}
|
||||
|
||||
@ -1234,9 +1266,7 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
query_select_with_custom_id_for_feed.bindValue(QSL(":feed"), feed_custom_id);
|
||||
query_select_with_custom_id_for_feed.bindValue(QSL(":custom_id"), unnulifyString(message.m_customId));
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Checking if message with feed-specific custom ID"
|
||||
<< QUOTE_W_SPACE(message.m_customId)
|
||||
qDebugNN << LOGSEC_DB << "Checking if message with feed-specific custom ID" << QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is present in DB.";
|
||||
|
||||
if (query_select_with_custom_id_for_feed.exec() && query_select_with_custom_id_for_feed.next()) {
|
||||
@ -1249,15 +1279,11 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
title_existing_message = query_select_with_custom_id_for_feed.value(5).toString();
|
||||
author_existing_message = query_select_with_custom_id_for_feed.value(6).toString();
|
||||
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Message with custom ID"
|
||||
<< QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is already present in DB and has DB ID"
|
||||
<< QUOTE_W_SPACE_DOT(id_existing_message);
|
||||
qDebugNN << LOGSEC_DB << "Message with custom ID" << QUOTE_W_SPACE(message.m_customId)
|
||||
<< "is already present in DB and has DB ID" << QUOTE_W_SPACE_DOT(id_existing_message);
|
||||
}
|
||||
else if (query_select_with_custom_id_for_feed.lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to check for existing message in DB via ID:"
|
||||
qWarningNN << LOGSEC_DB << "Failed to check for existing message in DB via ID:"
|
||||
<< QUOTE_W_SPACE_DOT(query_select_with_custom_id_for_feed.lastError().text());
|
||||
}
|
||||
|
||||
@ -1286,17 +1312,17 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
// 4) FOR ALL SERVICES:
|
||||
// Message update is forced, we want to overwrite message as some arbitrary atribute was changed,
|
||||
// this particularly happens when manual message filter execution happens.
|
||||
bool ignore_contents_changes = qApp->settings()->value(GROUP(Messages), SETTING(Messages::IgnoreContentsChanges)).toBool();
|
||||
bool cond_1 = !message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() &&
|
||||
bool ignore_contents_changes =
|
||||
qApp->settings()->value(GROUP(Messages), SETTING(Messages::IgnoreContentsChanges)).toBool();
|
||||
bool cond_1 =
|
||||
!message.m_customId.isEmpty() && feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_created.toMSecsSinceEpoch() != date_existing_message ||
|
||||
message.m_isRead != is_read_existing_message ||
|
||||
message.m_isImportant != is_important_existing_message ||
|
||||
message.m_isRead != is_read_existing_message || message.m_isImportant != is_important_existing_message ||
|
||||
(message.m_feedId != feed_id_existing_message && message.m_feedId == feed_custom_id) ||
|
||||
message.m_title != title_existing_message ||
|
||||
(!ignore_contents_changes && message.m_contents != contents_existing_message));
|
||||
bool cond_2 = !message.m_customId.isEmpty() && !feed->getParentServiceRoot()->isSyncable() &&
|
||||
(message.m_title != title_existing_message ||
|
||||
message.m_author != author_existing_message ||
|
||||
(message.m_title != title_existing_message || message.m_author != author_existing_message ||
|
||||
(!ignore_contents_changes && message.m_contents != contents_existing_message));
|
||||
bool cond_3 = (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message) ||
|
||||
(!ignore_contents_changes && message.m_contents != contents_existing_message);
|
||||
@ -1305,7 +1331,8 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
// Message exists and is changed, update it.
|
||||
query_update.bindValue(QSL(":title"), unnulifyString(message.m_title));
|
||||
query_update.bindValue(QSL(":is_read"), int(message.m_isRead));
|
||||
query_update.bindValue(QSL(":is_important"), (feed->getParentServiceRoot()->isSyncable() || message.m_isImportant)
|
||||
query_update.bindValue(QSL(":is_important"),
|
||||
(feed->getParentServiceRoot()->isSyncable() || message.m_isImportant)
|
||||
? int(message.m_isImportant)
|
||||
: is_important_existing_message);
|
||||
query_update.bindValue(QSL(":is_deleted"), int(message.m_isDeleted));
|
||||
@ -1319,12 +1346,8 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
query_update.bindValue(QSL(":id"), id_existing_message);
|
||||
|
||||
if (query_update.exec()) {
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Overwriting message with title"
|
||||
<< QUOTE_W_SPACE(message.m_title)
|
||||
<< "URL"
|
||||
<< QUOTE_W_SPACE(message.m_url)
|
||||
<< "in DB.";
|
||||
qDebugNN << LOGSEC_DB << "Overwriting message with title" << QUOTE_W_SPACE(message.m_title) << "URL"
|
||||
<< QUOTE_W_SPACE(message.m_url) << "in DB.";
|
||||
|
||||
if (!message.m_isRead) {
|
||||
updated_messages.first++;
|
||||
@ -1334,8 +1357,7 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
}
|
||||
else if (query_update.lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to update message in DB:"
|
||||
<< QUOTE_W_SPACE_DOT(query_update.lastError().text());
|
||||
<< "Failed to update message in DB:" << QUOTE_W_SPACE_DOT(query_update.lastError().text());
|
||||
}
|
||||
|
||||
query_update.finish();
|
||||
@ -1354,7 +1376,8 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
|
||||
if (!msgs_to_insert.isEmpty()) {
|
||||
QString bulk_insert = QSL("INSERT INTO Messages "
|
||||
"(feed, title, is_read, is_important, is_deleted, url, author, score, date_created, contents, enclosures, custom_id, custom_hash, account_id) "
|
||||
"(feed, title, is_read, is_important, is_deleted, url, author, score, date_created, "
|
||||
"contents, enclosures, custom_id, custom_hash, account_id) "
|
||||
"VALUES %1;");
|
||||
|
||||
for (int i = 0; i < msgs_to_insert.size(); i += 1000) {
|
||||
@ -1365,9 +1388,7 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
Message* msg = msgs_to_insert[l];
|
||||
|
||||
if (msg->m_title.isEmpty()) {
|
||||
qCriticalNN << LOGSEC_DB
|
||||
<< "Message"
|
||||
<< QUOTE_W_SPACE(msg->m_customId)
|
||||
qCriticalNN << LOGSEC_DB << "Message" << QUOTE_W_SPACE(msg->m_customId)
|
||||
<< "will not be inserted to DB because it does not meet DB constraints.";
|
||||
|
||||
// Message is not inserted to DB at last,
|
||||
@ -1407,9 +1428,7 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
if (bulk_error.isValid()) {
|
||||
QString txt = bulk_error.text() + bulk_error.databaseText() + bulk_error.driverText();
|
||||
|
||||
qCriticalNN << LOGSEC_DB
|
||||
<< "Failed bulk insert of articles:"
|
||||
<< QUOTE_W_SPACE_DOT(txt);
|
||||
qCriticalNN << LOGSEC_DB << "Failed bulk insert of articles:" << QUOTE_W_SPACE_DOT(txt);
|
||||
}
|
||||
else {
|
||||
// OK, we bulk-inserted many messages but the thing is that they do not
|
||||
@ -1431,15 +1450,13 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
}
|
||||
|
||||
// Update labels assigned to message.
|
||||
for (Message& message: messages) {
|
||||
for (Message& message : messages) {
|
||||
if (!message.m_assignedLabels.isEmpty()) {
|
||||
if (!message.m_customId.isEmpty() || message.m_id > 0) {
|
||||
setLabelsForMessage(db, message.m_assignedLabels, message);
|
||||
}
|
||||
else {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Cannot set labels for message"
|
||||
<< QUOTE_W_SPACE(message.m_title)
|
||||
qWarningNN << LOGSEC_DB << "Cannot set labels for message" << QUOTE_W_SPACE(message.m_title)
|
||||
<< "because we don't have ID or custom ID.";
|
||||
}
|
||||
}
|
||||
@ -1449,21 +1466,20 @@ QPair<int, int> DatabaseQueries::updateMessages(QSqlDatabase db,
|
||||
// just to keep the data consistent.
|
||||
if (db.exec("UPDATE Messages "
|
||||
"SET custom_id = id "
|
||||
"WHERE custom_id IS NULL OR custom_id = '';").lastError().isValid()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Failed to set custom ID for all messages:"
|
||||
<< QUOTE_W_SPACE_DOT(db.lastError().text());
|
||||
"WHERE custom_id IS NULL OR custom_id = '';")
|
||||
.lastError()
|
||||
.isValid()) {
|
||||
qWarningNN << LOGSEC_DB << "Failed to set custom ID for all messages:" << QUOTE_W_SPACE_DOT(db.lastError().text());
|
||||
}
|
||||
|
||||
if (use_transactions && !db.commit()) {
|
||||
qCriticalNN << LOGSEC_DB
|
||||
<< "Transaction commit for message downloader failed:"
|
||||
<< QUOTE_W_SPACE_DOT(db.lastError().text());
|
||||
<< "Transaction commit for message downloader failed:" << QUOTE_W_SPACE_DOT(db.lastError().text());
|
||||
db.rollback();
|
||||
|
||||
if (ok != nullptr) {
|
||||
*ok = false;
|
||||
updated_messages = { 0, 0 };
|
||||
updated_messages = {0, 0};
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1481,7 +1497,8 @@ bool DatabaseQueries::purgeMessagesFromBin(const QSqlDatabase& db, bool clear_on
|
||||
q.setForwardOnly(true);
|
||||
|
||||
if (clear_only_read) {
|
||||
q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_read = 1 AND is_deleted = 1 AND account_id = :account_id;"));
|
||||
q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_read = 1 AND is_deleted = 1 AND account_id = "
|
||||
":account_id;"));
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1 AND account_id = :account_id;"));
|
||||
@ -1512,9 +1529,7 @@ bool DatabaseQueries::deleteAccount(const QSqlDatabase& db, ServiceRoot* account
|
||||
query.bindValue(QSL(":account_id"), account->accountId());
|
||||
|
||||
if (!query.exec()) {
|
||||
qCriticalNN << LOGSEC_DB
|
||||
<< "Removing of account from DB failed, this is critical: '"
|
||||
<< query.lastError().text()
|
||||
qCriticalNN << LOGSEC_DB << "Removing of account from DB failed, this is critical: '" << query.lastError().text()
|
||||
<< "'.";
|
||||
return false;
|
||||
}
|
||||
@ -1576,7 +1591,9 @@ bool DatabaseQueries::cleanLabelledMessages(const QSqlDatabase& db, bool clean_r
|
||||
" is_pdeleted = 0 AND "
|
||||
" is_read = 1 AND "
|
||||
" account_id = :account_id AND "
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"));
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND "
|
||||
"Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = "
|
||||
"LabelsInMessages.message);"));
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("UPDATE Messages SET is_deleted = :deleted "
|
||||
@ -1584,7 +1601,9 @@ bool DatabaseQueries::cleanLabelledMessages(const QSqlDatabase& db, bool clean_r
|
||||
" is_deleted = 0 AND "
|
||||
" is_pdeleted = 0 AND "
|
||||
" account_id = :account_id AND "
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"));
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND "
|
||||
"Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = "
|
||||
"LabelsInMessages.message);"));
|
||||
}
|
||||
|
||||
q.bindValue(QSL(":deleted"), 1);
|
||||
@ -1592,10 +1611,7 @@ bool DatabaseQueries::cleanLabelledMessages(const QSqlDatabase& db, bool clean_r
|
||||
q.bindValue(QSL(":label"), label->customId());
|
||||
|
||||
if (!q.exec()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Cleaning of labelled messages failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Cleaning of labelled messages failed: '" << q.lastError().text() << "'.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -1610,7 +1626,8 @@ bool DatabaseQueries::cleanImportantMessages(const QSqlDatabase& db, bool clean_
|
||||
|
||||
if (clean_read_only) {
|
||||
q.prepare(QSL("UPDATE Messages SET is_deleted = :deleted "
|
||||
"WHERE is_important = 1 AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;"));
|
||||
"WHERE is_important = 1 AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = "
|
||||
":account_id;"));
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("UPDATE Messages SET is_deleted = :deleted "
|
||||
@ -1621,10 +1638,7 @@ bool DatabaseQueries::cleanImportantMessages(const QSqlDatabase& db, bool clean_
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (!q.exec()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Cleaning of important messages failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Cleaning of important messages failed: '" << q.lastError().text() << "'.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -1643,10 +1657,7 @@ bool DatabaseQueries::cleanUnreadMessages(const QSqlDatabase& db, int account_id
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (!q.exec()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Cleaning of unread messages failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Cleaning of unread messages failed: '" << q.lastError().text() << "'.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -1661,7 +1672,8 @@ bool DatabaseQueries::cleanFeeds(const QSqlDatabase& db, const QStringList& ids,
|
||||
|
||||
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;")
|
||||
"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 {
|
||||
@ -1674,10 +1686,7 @@ bool DatabaseQueries::cleanFeeds(const QSqlDatabase& db, const QStringList& ids,
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (!q.exec()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Cleaning of feeds failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Cleaning of feeds failed: '" << q.lastError().text() << "'.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -1689,16 +1698,13 @@ bool DatabaseQueries::purgeLeftoverMessageFilterAssignments(const QSqlDatabase&
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(
|
||||
QSL("DELETE FROM MessageFiltersInFeeds "
|
||||
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()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Removing of leftover message filter assignments failed: '"
|
||||
<< q.lastError().text()
|
||||
qWarningNN << LOGSEC_DB << "Removing of leftover message filter assignments failed: '" << q.lastError().text()
|
||||
<< "'.";
|
||||
return false;
|
||||
}
|
||||
@ -1712,14 +1718,12 @@ bool DatabaseQueries::purgeLeftoverMessages(const QSqlDatabase& db, int account_
|
||||
|
||||
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);"));
|
||||
"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()) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Removing of leftover messages failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Removing of leftover messages failed: '" << q.lastError().text() << "'.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -1733,10 +1737,11 @@ bool DatabaseQueries::purgeLeftoverLabelAssignments(const QSqlDatabase& db, int
|
||||
|
||||
if (account_id <= 0) {
|
||||
succ = q.exec(QSL("DELETE FROM LabelsInMessages "
|
||||
"WHERE NOT EXISTS (SELECT * FROM Messages WHERE Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"))
|
||||
&&
|
||||
"WHERE NOT EXISTS (SELECT * FROM Messages WHERE Messages.account_id = "
|
||||
"LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);")) &&
|
||||
q.exec(QSL("DELETE FROM LabelsInMessages "
|
||||
"WHERE NOT EXISTS (SELECT * FROM Labels WHERE Labels.account_id = LabelsInMessages.account_id AND Labels.custom_id = LabelsInMessages.label);"));
|
||||
"WHERE NOT EXISTS (SELECT * FROM Labels WHERE Labels.account_id = LabelsInMessages.account_id "
|
||||
"AND Labels.custom_id = LabelsInMessages.label);"));
|
||||
}
|
||||
else {
|
||||
q.prepare(QSL("DELETE FROM LabelsInMessages "
|
||||
@ -1748,10 +1753,7 @@ bool DatabaseQueries::purgeLeftoverLabelAssignments(const QSqlDatabase& db, int
|
||||
}
|
||||
|
||||
if (!succ) {
|
||||
qWarningNN << LOGSEC_DB
|
||||
<< "Removing of leftover label assignments failed: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
qWarningNN << LOGSEC_DB << "Removing of leftover label assignments failed: '" << q.lastError().text() << "'.";
|
||||
}
|
||||
|
||||
return succ;
|
||||
@ -1827,7 +1829,9 @@ QStringList DatabaseQueries::customIdsOfMessagesFromLabel(const QSqlDatabase& db
|
||||
" is_deleted = 0 AND "
|
||||
" is_pdeleted = 0 AND "
|
||||
" account_id = :account_id AND "
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"));
|
||||
" EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND "
|
||||
"Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = "
|
||||
"LabelsInMessages.message);"));
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
q.bindValue(QSL(":label"), label->customId());
|
||||
|
||||
@ -1896,7 +1900,8 @@ QStringList DatabaseQueries::customIdsOfMessagesFromBin(const QSqlDatabase& db,
|
||||
QStringList ids;
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"));
|
||||
q.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = "
|
||||
":account_id;"));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (ok != nullptr) {
|
||||
@ -1913,12 +1918,16 @@ QStringList DatabaseQueries::customIdsOfMessagesFromBin(const QSqlDatabase& db,
|
||||
return ids;
|
||||
}
|
||||
|
||||
QStringList DatabaseQueries::customIdsOfMessagesFromFeed(const QSqlDatabase& db, const QString& feed_custom_id, int account_id, bool* ok) {
|
||||
QStringList DatabaseQueries::customIdsOfMessagesFromFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int account_id,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
QStringList ids;
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND account_id = :account_id;"));
|
||||
q.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND "
|
||||
"account_id = :account_id;"));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
q.bindValue(QSL(":feed"), feed_custom_id);
|
||||
|
||||
@ -1936,12 +1945,14 @@ QStringList DatabaseQueries::customIdsOfMessagesFromFeed(const QSqlDatabase& db,
|
||||
return ids;
|
||||
}
|
||||
|
||||
void DatabaseQueries::createOverwriteCategory(const QSqlDatabase& db, Category* category, int account_id, int new_parent_id) {
|
||||
void DatabaseQueries::createOverwriteCategory(const QSqlDatabase& db,
|
||||
Category* category,
|
||||
int account_id,
|
||||
int new_parent_id) {
|
||||
QSqlQuery q(db);
|
||||
int next_sort_order;
|
||||
|
||||
if (category->id() <= 0 ||
|
||||
(category->parent() != nullptr && category->parent()->id() != new_parent_id)) {
|
||||
if (category->id() <= 0 || (category->parent() != nullptr && category->parent()->id() != new_parent_id)) {
|
||||
q.prepare(QSL("SELECT MAX(ordr) FROM Categories WHERE account_id = :account_id AND parent_id = :parent_id;"));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
q.bindValue(QSL(":parent_id"), new_parent_id);
|
||||
@ -1961,7 +1972,8 @@ void DatabaseQueries::createOverwriteCategory(const QSqlDatabase& db, Category*
|
||||
// We need to insert category first.
|
||||
q.prepare(QSL("INSERT INTO "
|
||||
"Categories (parent_id, ordr, title, date_created, account_id) "
|
||||
"VALUES (0, 0, 'new', 0, %1);").arg(QString::number(account_id)));
|
||||
"VALUES (0, 0, 'new', 0, %1);")
|
||||
.arg(QString::number(account_id)));
|
||||
|
||||
if (!q.exec()) {
|
||||
throw ApplicationException(q.lastError().text());
|
||||
@ -1984,7 +1996,8 @@ void DatabaseQueries::createOverwriteCategory(const QSqlDatabase& db, Category*
|
||||
category->setSortOrder(next_sort_order);
|
||||
|
||||
q.prepare("UPDATE Categories "
|
||||
"SET parent_id = :parent_id, ordr = :ordr, title = :title, description = :description, date_created = :date_created, "
|
||||
"SET parent_id = :parent_id, ordr = :ordr, title = :title, description = :description, date_created = "
|
||||
":date_created, "
|
||||
" icon = :icon, account_id = :account_id, custom_id = :custom_id "
|
||||
"WHERE id = :id;");
|
||||
q.bindValue(QSL(":parent_id"), new_parent_id);
|
||||
@ -2006,8 +2019,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
|
||||
QSqlQuery q(db);
|
||||
int next_sort_order;
|
||||
|
||||
if (feed->id() <= 0 ||
|
||||
(feed->parent() != nullptr && feed->parent()->id() != new_parent_id)) {
|
||||
if (feed->id() <= 0 || (feed->parent() != nullptr && feed->parent()->id() != new_parent_id)) {
|
||||
// We either insert completely new feed or we move feed
|
||||
// to new parent. Get new viable sort order.
|
||||
q.prepare(QSL("SELECT MAX(ordr) FROM Feeds WHERE account_id = :account_id AND category = :category;"));
|
||||
@ -2029,7 +2041,8 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
|
||||
// We need to insert feed first.
|
||||
q.prepare(QSL("INSERT INTO "
|
||||
"Feeds (title, ordr, date_created, category, update_type, update_interval, account_id, custom_id) "
|
||||
"VALUES ('new', 0, 0, 0, 0, 1, %1, 'new');").arg(QString::number(account_id)));
|
||||
"VALUES ('new', 0, 0, 0, 0, 1, %1, 'new');")
|
||||
.arg(QString::number(account_id)));
|
||||
|
||||
if (!q.exec()) {
|
||||
throw ApplicationException(q.lastError().text());
|
||||
@ -2160,8 +2173,7 @@ bool DatabaseQueries::deleteFeed(const QSqlDatabase& db, Feed* feed, int account
|
||||
q.bindValue(QSL(":feed"), feed->customId());
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
return q.exec() &&
|
||||
purgeLeftoverMessageFilterAssignments(db, account_id) &&
|
||||
return q.exec() && purgeLeftoverMessageFilterAssignments(db, account_id) &&
|
||||
purgeLeftoverLabelAssignments(db, account_id);
|
||||
}
|
||||
|
||||
@ -2177,21 +2189,27 @@ bool DatabaseQueries::deleteCategory(const QSqlDatabase& db, Category* category)
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
void DatabaseQueries::moveItem(RootItem* item, bool move_top, bool move_bottom, int move_index, const QSqlDatabase& db) {
|
||||
if (item->kind() != RootItem::Kind::Feed &&
|
||||
item->kind() != RootItem::Kind::Category &&
|
||||
void DatabaseQueries::moveItem(RootItem* item,
|
||||
bool move_top,
|
||||
bool move_bottom,
|
||||
int move_index,
|
||||
const QSqlDatabase& db) {
|
||||
if (item->kind() != RootItem::Kind::Feed && item->kind() != RootItem::Kind::Category &&
|
||||
item->kind() != RootItem::Kind::ServiceRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto neighbors = item->parent()->childItems();
|
||||
int max_sort_order = boolinq::from(neighbors).select([=](RootItem* it) {
|
||||
int max_sort_order = boolinq::from(neighbors)
|
||||
.select([=](RootItem* it) {
|
||||
return it->kind() == item->kind() ? it->sortOrder() : 0;
|
||||
}).max();
|
||||
})
|
||||
.max();
|
||||
|
||||
if ((!move_top && !move_bottom && item->sortOrder() == move_index) || /* Item is already sorted OK. */
|
||||
(!move_top && !move_bottom && move_index < 0 ) || /* Order cannot be smaller than 0 if we do not move to begin/end. */
|
||||
(!move_top && !move_bottom && move_index > max_sort_order ) || /* Cannot move past biggest sort order. */
|
||||
(!move_top && !move_bottom &&
|
||||
move_index < 0) || /* Order cannot be smaller than 0 if we do not move to begin/end. */
|
||||
(!move_top && !move_bottom && move_index > max_sort_order) || /* Cannot move past biggest sort order. */
|
||||
(move_top && item->sortOrder() == 0) || /* Item is already on top. */
|
||||
(move_bottom && item->sortOrder() == max_sort_order) || /* Item is already on bottom. */
|
||||
max_sort_order <= 0) { /* We only have 1 item, nothing to sort. */
|
||||
@ -2261,7 +2279,8 @@ void DatabaseQueries::moveItem(RootItem* item, bool move_top, bool move_bottom,
|
||||
}
|
||||
|
||||
q.prepare(QSL("UPDATE %1 SET ordr = :ordr WHERE id = :id;").arg(table_name));
|
||||
q.bindValue(QSL(":id"), item->kind() == RootItem::Kind::ServiceRoot ? item->toServiceRoot()->accountId() : item->id());
|
||||
q.bindValue(QSL(":id"),
|
||||
item->kind() == RootItem::Kind::ServiceRoot ? item->toServiceRoot()->accountId() : item->id());
|
||||
q.bindValue(QSL(":ordr"), move_index);
|
||||
|
||||
if (!q.exec()) {
|
||||
@ -2270,16 +2289,20 @@ void DatabaseQueries::moveItem(RootItem* item, bool move_top, bool move_bottom,
|
||||
|
||||
// Fix live sort orders.
|
||||
if (item->sortOrder() > move_index) {
|
||||
boolinq::from(neighbors).where([=](RootItem* it) {
|
||||
boolinq::from(neighbors)
|
||||
.where([=](RootItem* it) {
|
||||
return it->kind() == item->kind() && it->sortOrder() < move_high && it->sortOrder() >= move_low;
|
||||
}).for_each([](RootItem* it) {
|
||||
})
|
||||
.for_each([](RootItem* it) {
|
||||
it->setSortOrder(it->sortOrder() + 1);
|
||||
});
|
||||
}
|
||||
else {
|
||||
boolinq::from(neighbors).where([=](RootItem* it) {
|
||||
boolinq::from(neighbors)
|
||||
.where([=](RootItem* it) {
|
||||
return it->kind() == item->kind() && it->sortOrder() > move_low && it->sortOrder() <= move_high;
|
||||
}).for_each([](RootItem* it) {
|
||||
})
|
||||
.for_each([](RootItem* it) {
|
||||
it->setSortOrder(it->sortOrder() - 1);
|
||||
});
|
||||
}
|
||||
@ -2287,10 +2310,10 @@ void DatabaseQueries::moveItem(RootItem* item, bool move_top, bool move_bottom,
|
||||
item->setSortOrder(move_index);
|
||||
}
|
||||
|
||||
MessageFilter* DatabaseQueries::addMessageFilter(const QSqlDatabase& db, const QString& title,
|
||||
const QString& script) {
|
||||
MessageFilter* DatabaseQueries::addMessageFilter(const QSqlDatabase& db, const QString& title, const QString& script) {
|
||||
if (!db.driver()->hasFeature(QSqlDriver::DriverFeature::LastInsertId)) {
|
||||
throw ApplicationException(QObject::tr("Cannot insert article filter, because current database cannot return last inserted row ID."));
|
||||
throw ApplicationException(QObject::tr("Cannot insert article filter, because current database cannot return last "
|
||||
"inserted row ID."));
|
||||
}
|
||||
|
||||
QSqlQuery q(db);
|
||||
@ -2414,8 +2437,11 @@ QMultiMap<QString, int> DatabaseQueries::messageFiltersInFeeds(const QSqlDatabas
|
||||
return filters_in_feeds;
|
||||
}
|
||||
|
||||
void DatabaseQueries::assignMessageFilterToFeed(const QSqlDatabase& db, const QString& feed_custom_id,
|
||||
int filter_id, int account_id, bool* ok) {
|
||||
void DatabaseQueries::assignMessageFilterToFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int filter_id,
|
||||
int account_id,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.prepare(QSL("INSERT INTO MessageFiltersInFeeds (filter, feed_custom_id, account_id) "
|
||||
@ -2460,8 +2486,11 @@ void DatabaseQueries::updateMessageFilter(const QSqlDatabase& db, MessageFilter*
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseQueries::removeMessageFilterFromFeed(const QSqlDatabase& db, const QString& feed_custom_id,
|
||||
int filter_id, int account_id, bool* ok) {
|
||||
void DatabaseQueries::removeMessageFilterFromFeed(const QSqlDatabase& db,
|
||||
const QString& feed_custom_id,
|
||||
int filter_id,
|
||||
int account_id,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.prepare(QSL("DELETE FROM MessageFiltersInFeeds "
|
||||
@ -2506,16 +2535,14 @@ QStringList DatabaseQueries::getAllGmailRecipients(const QSqlDatabase& db, int a
|
||||
return rec;
|
||||
}
|
||||
|
||||
bool DatabaseQueries::storeNewOauthTokens(const QSqlDatabase& db,
|
||||
const QString& refresh_token, int account_id) {
|
||||
bool DatabaseQueries::storeNewOauthTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id) {
|
||||
QSqlQuery query(db);
|
||||
|
||||
query.prepare(QSL("SELECT custom_data FROM Accounts WHERE id = :id;"));
|
||||
query.bindValue(QSL(":id"), account_id);
|
||||
|
||||
if (!query.exec() || !query.next()) {
|
||||
qWarningNN << LOGSEC_OAUTH
|
||||
<< "Cannot fetch custom data column for storing of OAuth tokens, because of error:"
|
||||
qWarningNN << LOGSEC_OAUTH << "Cannot fetch custom data column for storing of OAuth tokens, because of error:"
|
||||
<< QUOTE_W_SPACE_DOT(query.lastError().text());
|
||||
return false;
|
||||
}
|
||||
@ -2531,8 +2558,7 @@ bool DatabaseQueries::storeNewOauthTokens(const QSqlDatabase& db,
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarningNN << LOGSEC_OAUTH
|
||||
<< "Cannot store OAuth tokens, because of error:"
|
||||
<< QUOTE_W_SPACE_DOT(query.lastError().text());
|
||||
<< "Cannot store OAuth tokens, because of error:" << QUOTE_W_SPACE_DOT(query.lastError().text());
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user