diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG
index 610574796..6a393c070 100644
--- a/resources/text/CHANGELOG
+++ b/resources/text/CHANGELOG
@@ -2,6 +2,7 @@
2.4.0 (not yet released)
Added:
+- Initial support for databse cleaning. See menu 'Tools -> Cleanup database'. (issue #101)
- RSS Guard is now able to export/import feed/category icons to/from OPML 2.0 files.
- Localizations now load their titles for localization list automatically.
- All feeds are by default checked when exporting/importing them.
@@ -14,6 +15,7 @@ Added:
Fixed:
+- Marking feed(s) unread now correctly marks also selected message unread.
- Threads for feed updating are created only when really needed.
- Reworked DB initialization scripts which allow to use OPML to do initial feed population.
- Titles and descriptions of feeds are now fetched correctly in feed add/edit dialog.
diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp
index a5ba491ef..df67cc134 100755
--- a/src/gui/feedmessageviewer.cpp
+++ b/src/gui/feedmessageviewer.cpp
@@ -443,10 +443,12 @@ void FeedMessageViewer::showDbCleanupAssistant() {
QPointer form_pointer = new FormDatabaseCleanup(this);
form_pointer.data()->setCleaner(databaseCleaner());
form_pointer.data()->exec();
+
delete form_pointer.data();
qApp->feedUpdateLock()->unlock();
- m_messagesView->reloadSelections(true);
+ m_messagesView->reloadSelections(false);
+ m_feedsView->updateCountsOfAllFeeds(true);
}
else {
qApp->showGuiMessage(tr("Cannot cleanup database"),
diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h
old mode 100644
new mode 100755
index 1993bb026..9faa48cce
--- a/src/gui/feedsview.h
+++ b/src/gui/feedsview.h
@@ -135,7 +135,9 @@ class FeedsView : public QTreeView {
// Notifies other components about messages
// counts.
inline void notifyWithCounts() {
- emit messageCountsChanged(m_sourceModel->countOfUnreadMessages(), m_sourceModel->countOfAllMessages(), m_sourceModel->hasAnyFeedNewMessages());
+ emit messageCountsChanged(m_sourceModel->countOfUnreadMessages(),
+ m_sourceModel->countOfAllMessages(),
+ m_sourceModel->hasAnyFeedNewMessages());
}
// Selects next/previous item (feed/category) in the list.
diff --git a/src/gui/formdatabasecleanup.cpp b/src/gui/formdatabasecleanup.cpp
old mode 100644
new mode 100755
index 7969d6825..b41ab2cb3
--- a/src/gui/formdatabasecleanup.cpp
+++ b/src/gui/formdatabasecleanup.cpp
@@ -81,6 +81,7 @@ void FormDatabaseCleanup::updateDaysSuffix(int number) {
void FormDatabaseCleanup::startPurging() {
CleanerOrders orders;
+ orders.m_removeRecycleBin = m_ui->m_checkRemoveRecycleBin->isChecked();
orders.m_removeOldMessages = m_ui->m_checkRemoveOldMessages->isChecked();
orders.m_barrierForRemovingOldMessagesInDays = m_ui->m_spinDays->value();
orders.m_removeReadMessages = m_ui->m_checkRemoveReadMessages->isChecked();
diff --git a/src/gui/formdatabasecleanup.ui b/src/gui/formdatabasecleanup.ui
index 375ac7003..3c3c65061 100755
--- a/src/gui/formdatabasecleanup.ui
+++ b/src/gui/formdatabasecleanup.ui
@@ -6,8 +6,8 @@
0
0
- 400
- 313
+ 444
+ 359
@@ -17,17 +17,10 @@
-
- Cleanup settings
+ Cleanup settings (all checked items are completely erased from database)
-
-
-
-
- Shrink database file
-
-
-
- -
+
-
Qt::Horizontal
@@ -40,27 +33,7 @@
- -
-
-
- Remove all messages older than
-
-
- true
-
-
-
- -
-
-
- Remove all read messages
-
-
- true
-
-
-
- -
+
-
1
@@ -73,6 +46,43 @@
+ -
+
+
+ Remove all messages older than
+
+
+ true
+
+
+
+ -
+
+
+ Remove all messages from recycle bin
+
+
+ true
+
+
+
+ -
+
+
+ Remove all read messages (not those from recycle bin)
+
+
+ true
+
+
+
+ -
+
+
+ Shrink database file
+
+
+
@@ -87,6 +97,9 @@
Database file size
+
+ m_txtFileSize
+
-
@@ -101,6 +114,9 @@
Database type
+
+ m_txtDatabaseType
+
-
@@ -172,6 +188,15 @@
1
+
+ m_checkRemoveReadMessages
+ m_checkRemoveRecycleBin
+ m_checkShrink
+ m_checkRemoveOldMessages
+ m_spinDays
+ m_txtFileSize
+ m_txtDatabaseType
+
diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp
index 271cb1058..359ba2310 100755
--- a/src/gui/messagesview.cpp
+++ b/src/gui/messagesview.cpp
@@ -89,7 +89,7 @@ void MessagesView::reloadSelections(bool mark_current_index_read) {
current_index = m_proxyModel->mapFromSource(m_sourceModel->index(mapped_current_index.row(), mapped_current_index.column()));
if (current_index.isValid()) {
- if (mark_current_index_read) {
+ if (!mark_current_index_read) {
// User selected to mark some messages as unread, if one
// of them will be marked as current, then it will be read again.
m_batchUnreadSwitch = true;
diff --git a/src/miscellaneous/databasecleaner.cpp b/src/miscellaneous/databasecleaner.cpp
old mode 100644
new mode 100755
index 9ee694e97..2b6edbb4c
--- a/src/miscellaneous/databasecleaner.cpp
+++ b/src/miscellaneous/databasecleaner.cpp
@@ -21,10 +21,13 @@
#include "miscellaneous/databasefactory.h"
#include
+#include
+#include
#include
DatabaseCleaner::DatabaseCleaner(QObject *parent) : QObject(parent) {
+ setObjectName("DatabaseCleaner");
}
DatabaseCleaner::~DatabaseCleaner() {
@@ -33,20 +36,91 @@ DatabaseCleaner::~DatabaseCleaner() {
void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) {
qDebug().nospace() << "Performing database cleanup in thread: \'" << QThread::currentThreadId() << "\'.";
- bool result = true;
- int progress = 0;
-
+ // Inform everyone about the start of the process.
emit purgeStarted();
+ bool result = true;
+ int difference = 99 / 8;
+ int progress = 0;
+ QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
+
+ if (which_data.m_removeReadMessages) {
+ progress += difference;
+ emit purgeProgress(progress, tr("Removing read messages..."));
+
+ // Remove read messages.
+ result &= purgeReadMessages(database);
+
+ progress += difference;
+ emit purgeProgress(progress, tr("Read messages purged..."));
+ }
+
+ if (which_data.m_removeRecycleBin) {
+ progress += difference;
+ emit purgeProgress(progress, tr("Purgin recycle bin..."));
+
+ // Remove read messages.
+ result &= purgeRecycleBin(database);
+
+ progress += difference;
+ emit purgeProgress(progress, tr("Recycle bin purged..."));
+ }
+
+ if (which_data.m_removeOldMessages) {
+ progress += difference;
+ emit purgeProgress(progress, tr("Removing old messages..."));
+
+ // Remove old messages.
+ result &= purgeOldMessages(database, which_data.m_barrierForRemovingOldMessagesInDays);
+
+ progress += difference;
+ emit purgeProgress(progress, tr("Read old purged..."));
+ }
+
if (which_data.m_shrinkDatabase) {
- progress += 25;
+ progress += difference;
emit purgeProgress(progress, tr("Shrinking database file..."));
+ // Call driver-specific vacuuming function.
result &= qApp->database()->vacuumDatabase();
- progress += 25;
+ progress += difference;
emit purgeProgress(progress, tr("Database file shrinked..."));
}
emit purgeFinished(result);
}
+
+bool DatabaseCleaner::purgeReadMessages(const QSqlDatabase &database) {
+ QSqlQuery query = QSqlQuery(database);
+
+ query.setForwardOnly(true);
+ query.prepare("DELETE FROM Messages WHERE is_deleted = :is_deleted AND is_read = :is_read;");
+ query.bindValue(":is_read", 1);
+
+ // Remove only messages which are NOT in recycle bin.
+ query.bindValue(":is_deleted", 0);
+
+ return query.exec();
+}
+
+bool DatabaseCleaner::purgeOldMessages(const QSqlDatabase &database, int days) {
+ QSqlQuery query = QSqlQuery(database);
+ qint64 since_epoch = QDateTime::currentDateTimeUtc().addDays(-days).toMSecsSinceEpoch();
+
+ query.setForwardOnly(true);
+ query.prepare("DELETE FROM Messages WHERE date_created < :date_created;");
+ query.bindValue(":date_created", since_epoch);
+
+ return query.exec();
+}
+
+bool DatabaseCleaner::purgeRecycleBin(const QSqlDatabase &database) {
+ QSqlQuery query = QSqlQuery(database);
+
+ query.setForwardOnly(true);
+ query.prepare("DELETE FROM Messages WHERE is_deleted = :is_deleted;");
+ query.bindValue(":is_deleted", 1);
+
+ return query.exec();
+}
diff --git a/src/miscellaneous/databasecleaner.h b/src/miscellaneous/databasecleaner.h
old mode 100644
new mode 100755
index 17974c0ab..62f019708
--- a/src/miscellaneous/databasecleaner.h
+++ b/src/miscellaneous/databasecleaner.h
@@ -20,11 +20,14 @@
#include
+#include
+
struct CleanerOrders {
bool m_removeReadMessages;
bool m_shrinkDatabase;
bool m_removeOldMessages;
+ bool m_removeRecycleBin;
int m_barrierForRemovingOldMessagesInDays;
};
@@ -32,6 +35,7 @@ class DatabaseCleaner : public QObject {
Q_OBJECT
public:
+ // Constructors.
explicit DatabaseCleaner(QObject *parent = 0);
virtual ~DatabaseCleaner();
@@ -42,6 +46,11 @@ class DatabaseCleaner : public QObject {
public slots:
void purgeDatabaseData(const CleanerOrders &which_data);
+
+ private:
+ bool purgeReadMessages(const QSqlDatabase &database);
+ bool purgeOldMessages(const QSqlDatabase &database, int days);
+ bool purgeRecycleBin(const QSqlDatabase &database);
};
#endif // DATABASECLEANER_H