From dd1d7be8b0c17aba7ae2eaad6db52e127fb11f5d Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Sun, 20 Dec 2015 19:02:29 +0100 Subject: [PATCH] DB refactoring. --- src/core/messagesmodel.cpp | 1 - src/gui/feedsview.cpp | 2 +- src/miscellaneous/databasecleaner.cpp | 3 +- src/miscellaneous/databasefactory.cpp | 3 +- src/miscellaneous/databasefactory.h | 1 + src/services/abstract/recyclebin.cpp | 64 ++----------- src/services/abstract/serviceroot.cpp | 90 ++++++++----------- src/services/standard/standardcategory.cpp | 3 +- src/services/standard/standardfeed.cpp | 32 +++---- .../standard/standardserviceentrypoint.cpp | 13 ++- src/services/standard/standardserviceroot.cpp | 15 +--- 11 files changed, 81 insertions(+), 146 deletions(-) diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp index baacb58ab..3eb615baa 100755 --- a/src/core/messagesmodel.cpp +++ b/src/core/messagesmodel.cpp @@ -33,7 +33,6 @@ MessagesModel::MessagesModel(QObject *parent) : QSqlTableModel(parent, qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings)), m_messageHighlighter(NoHighlighting), m_customDateFormat(QString()) { - setObjectName(QSL("MessagesModel")); setupFonts(); setupIcons(); setupHeaderData(); diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp index b930714e9..bbf5ca1bb 100755 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -273,7 +273,7 @@ void FeedsView::openSelectedItemsInNewspaperMode() { if (!messages.isEmpty()) { emit openMessagesInNewspaperView(messages); - QTimer::singleShot(0, this, SLOT(markSelectedItemRead())); + QTimer::singleShot(150, this, SLOT(markSelectedItemRead())); } } diff --git a/src/miscellaneous/databasecleaner.cpp b/src/miscellaneous/databasecleaner.cpp index f0bc3e115..379ac8bdd 100755 --- a/src/miscellaneous/databasecleaner.cpp +++ b/src/miscellaneous/databasecleaner.cpp @@ -27,7 +27,6 @@ DatabaseCleaner::DatabaseCleaner(QObject *parent) : QObject(parent) { - setObjectName("DatabaseCleaner"); } DatabaseCleaner::~DatabaseCleaner() { @@ -42,7 +41,7 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) { bool result = true; int difference = 99 / 8; int progress = 0; - QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings); + QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); if (which_data.m_removeReadMessages) { progress += difference; diff --git a/src/miscellaneous/databasefactory.cpp b/src/miscellaneous/databasefactory.cpp index 374dcf71e..c60962a73 100755 --- a/src/miscellaneous/databasefactory.cpp +++ b/src/miscellaneous/databasefactory.cpp @@ -41,8 +41,7 @@ DatabaseFactory::~DatabaseFactory() { qint64 DatabaseFactory::getDatabaseSize() { if (m_activeDatabaseDriver == SQLITE || m_activeDatabaseDriver == SQLITE_MEMORY) { - qint64 size = QFileInfo(sqliteDatabaseFilePath()).size(); - return size; + return QFileInfo(sqliteDatabaseFilePath()).size(); } else { return 0; diff --git a/src/miscellaneous/databasefactory.h b/src/miscellaneous/databasefactory.h index 453d8e61f..1fee92613 100755 --- a/src/miscellaneous/databasefactory.h +++ b/src/miscellaneous/databasefactory.h @@ -60,6 +60,7 @@ class DatabaseFactory : public QObject { // Destructor. virtual ~DatabaseFactory(); + // Returns size of DB file. qint64 getDatabaseSize(); // If in-memory is true, then :memory: database is returned diff --git a/src/services/abstract/recyclebin.cpp b/src/services/abstract/recyclebin.cpp index 7f0ad4fc1..9cfdbce4b 100755 --- a/src/services/abstract/recyclebin.cpp +++ b/src/services/abstract/recyclebin.cpp @@ -118,35 +118,17 @@ QList RecycleBin::undeletedMessages() const { bool RecycleBin::markAsReadUnread(RootItem::ReadStatus status) { QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - - if (!db_handle.transaction()) { - qWarning("Starting transaction for recycle bin read change."); - return false; - } - QSqlQuery query_read_msg(db_handle); ServiceRoot *parent_root = getParentServiceRoot(); query_read_msg.setForwardOnly(true); - - if (!query_read_msg.prepare("UPDATE Messages SET is_read = :read " - "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;")) { - qWarning("Query preparation failed for recycle bin read change."); - - db_handle.rollback(); - return false; - } + query_read_msg.prepare("UPDATE Messages SET is_read = :read " + "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); query_read_msg.bindValue(QSL(":read"), status == RootItem::Read ? 1 : 0); query_read_msg.bindValue(QSL(":account_id"), parent_root->accountId()); - if (!query_read_msg.exec()) { - qDebug("Query execution for recycle bin read change failed."); - db_handle.rollback(); - } - - // Commit changes. - if (db_handle.commit()) { + if (query_read_msg.exec()) { updateCounts(false); parent_root->itemChanged(QList() << this); @@ -154,18 +136,12 @@ bool RecycleBin::markAsReadUnread(RootItem::ReadStatus status) { return true; } else { - return db_handle.rollback(); + return false; } } bool RecycleBin::cleanMessages(bool clear_only_read) { QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - - if (!db_handle.transaction()) { - qWarning("Starting transaction for recycle bin emptying."); - return false; - } - ServiceRoot *parent_root = getParentServiceRoot(); QSqlQuery query_empty_bin(db_handle); @@ -181,22 +157,14 @@ bool RecycleBin::cleanMessages(bool clear_only_read) { query_empty_bin.bindValue(QSL(":account_id"), parent_root->accountId()); - if (!query_empty_bin.exec()) { - qWarning("Query execution failed for recycle bin emptying."); - - db_handle.rollback(); - return false; - } - - // Commit changes. - if (db_handle.commit()) { + if (query_empty_bin.exec()) { updateCounts(true); parent_root->itemChanged(QList() << this); parent_root->requestReloadMessageList(true); - return true; + return true;; } else { - return db_handle.rollback(); + return false; } } @@ -206,12 +174,6 @@ bool RecycleBin::empty() { bool RecycleBin::restore() { QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - - if (!db_handle.transaction()) { - qWarning("Starting transaction for recycle bin restoring."); - return false; - } - ServiceRoot *parent_root = getParentServiceRoot(); QSqlQuery query_empty_bin(db_handle); @@ -220,15 +182,7 @@ bool RecycleBin::restore() { "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); query_empty_bin.bindValue(QSL(":account_id"), parent_root->accountId()); - if (!query_empty_bin.exec()) { - qWarning("Query execution failed for recycle bin restoring."); - - db_handle.rollback(); - return false; - } - - // Commit changes. - if (db_handle.commit()) { + if (query_empty_bin.exec()) { parent_root->updateCounts(true); parent_root->itemChanged(parent_root->getSubTree()); parent_root->requestReloadMessageList(true); @@ -236,6 +190,6 @@ bool RecycleBin::restore() { return true; } else { - return db_handle.rollback(); + return false; } } diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index d83bfa2d4..1f229a9f0 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -23,6 +23,7 @@ #include "services/abstract/category.h" #include +#include ServiceRoot::ServiceRoot(RootItem *parent) : RootItem(parent), m_accountId(NO_PARENT_CATEGORY) { @@ -34,61 +35,50 @@ ServiceRoot::~ServiceRoot() { bool ServiceRoot::deleteViaGui() { QSqlDatabase connection = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); + QSqlQuery query(connection); + int account_id = accountId(); + query.setForwardOnly(true); - // Remove all messages. - if (!QSqlQuery(connection).exec(QString("DELETE FROM Messages WHERE account_id = %1;").arg(accountId()))) { - return false; + QStringList queries; + queries << QSL("DELETE FROM Messages WHERE account_id = :account_id;") << + QSL("DELETE FROM Feeds WHERE account_id = :account_id;") << + QSL("DELETE FROM Categories WHERE account_id = :account_id;") << + QSL("DELETE FROM Accounts WHERE id = :account_id;"); + + foreach (const QString &q, queries) { + query.prepare(q); + query.bindValue(QSL(":account_id"), account_id); + + if (!query.exec()) { + qCritical("Removing of account from DB failed, this is critical: '%s'.", qPrintable(query.lastError().text())); + return false; + } + else { + query.finish(); + } } - // Remove all feeds. - if (!QSqlQuery(connection).exec(QString("DELETE FROM Feeds WHERE account_id = %1;").arg(accountId()))) { - return false; - } - - // Remove all categories. - if (!QSqlQuery(connection).exec(QString("DELETE FROM Categories WHERE account_id = %1;").arg(accountId()))) { - return false; - } - - // Switch "existence" flag. - bool data_removed = QSqlQuery(connection).exec(QString("DELETE FROM Accounts WHERE id = %1;").arg(accountId())); - - if (data_removed) { - requestItemRemoval(this); - } - - return data_removed; + requestItemRemoval(this); + return true; } bool ServiceRoot::markAsReadUnread(RootItem::ReadStatus status) { QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); + QSqlQuery query(db_handle); + query.setForwardOnly(true); + query.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;")); - if (!db_handle.transaction()) { - qWarning("Starting transaction for feeds read change."); - return false; - } + query.bindValue(QSL(":account_id"), accountId()); + query.bindValue(QSL(":read"), status == RootItem::Read ? 1 : 0); - QSqlQuery query_read_msg(db_handle); - query_read_msg.setForwardOnly(true); - query_read_msg.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;")); - - query_read_msg.bindValue(QSL(":account_id"), accountId()); - query_read_msg.bindValue(QSL(":read"), status == RootItem::Read ? 1 : 0); - - if (!query_read_msg.exec()) { - qDebug("Query execution for feeds read change failed."); - db_handle.rollback(); - } - - // Commit changes. - if (db_handle.commit()) { + if (query.exec()) { updateCounts(false); itemChanged(getSubTree()); requestReloadMessageList(status == RootItem::Read); return true; } else { - return db_handle.rollback(); + return false; } } @@ -96,20 +86,18 @@ QList ServiceRoot::undeletedMessages() const { QList messages; int account_id = accountId(); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query_read_msg(database); + QSqlQuery query(database); - query_read_msg.setForwardOnly(true); - query_read_msg.prepare("SELECT * " - "FROM Messages " - "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"); - query_read_msg.bindValue(QSL(":account_id"), account_id); + query.setForwardOnly(true); + query.prepare("SELECT * " + "FROM Messages " + "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"); + query.bindValue(QSL(":account_id"), account_id); - // FIXME: Fix those const functions, this is fucking ugly. - - if (query_read_msg.exec()) { - while (query_read_msg.next()) { + if (query.exec()) { + while (query.next()) { bool decoded; - Message message = Message::fromSqlRecord(query_read_msg.record(), &decoded); + Message message = Message::fromSqlRecord(query.record(), &decoded); if (decoded) { messages.append(message); diff --git a/src/services/standard/standardcategory.cpp b/src/services/standard/standardcategory.cpp index 9cbe45021..d00baa51a 100755 --- a/src/services/standard/standardcategory.cpp +++ b/src/services/standard/standardcategory.cpp @@ -173,14 +173,13 @@ bool StandardCategory::addItself(RootItem *parent) { query_add.bindValue(QSL(":account_id"), parent->getParentServiceRoot()->accountId()); if (!query_add.exec()) { - qDebug("Failed to add category to database: %s.", qPrintable(query_add.lastError().text())); + qDebug("Failed to add category to database: '%s'.", qPrintable(query_add.lastError().text())); // Query failed. return false; } setId(query_add.lastInsertId().toInt()); - return true; } diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp index 48a8ede25..5f2f1e1ff 100755 --- a/src/services/standard/standardfeed.cpp +++ b/src/services/standard/standardfeed.cpp @@ -227,21 +227,26 @@ QString StandardFeed::typeToString(StandardFeed::Type type) { void StandardFeed::updateCounts(bool including_total_count) { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query_all(database); - - query_all.setForwardOnly(true); + QSqlQuery query(database); + query.setForwardOnly(true); if (including_total_count) { - if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = '%1' AND is_deleted = 0 AND account_id = %2;").arg(QString::number(id()), - QString::number(const_cast(this)->serviceRoot()->accountId()))) && query_all.next()) { - m_totalCount = query_all.value(0).toInt(); + query.prepare(QSL("SELECT count(*) FROM Messages WHERE feed = :feed AND is_pdeleted = 0 AND is_deleted = 0 AND account_id = :account_id;")); + query.bindValue(QSL(":feed"), id()); + query.bindValue(QSL(":account_id"), serviceRoot()->accountId()); + + if (query.exec() && query.next()) { + m_totalCount = query.value(0).toInt(); } } // Obtain count of unread messages. - if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = '%1' AND is_deleted = 0 AND is_read = 0 AND account_id = %2;").arg(QString::number(id()), - QString::number(const_cast(this)->serviceRoot()->accountId()))) && query_all.next()) { - int new_unread_count = query_all.value(0).toInt(); + query.prepare(QSL("SELECT count(*) FROM Messages WHERE feed = :feed AND is_pdeleted = 0 AND is_deleted = 0 AND is_read = 0 AND account_id = :account_id;")); + query.bindValue(QSL(":feed"), id()); + query.bindValue(QSL(":account_id"), serviceRoot()->accountId()); + + if (query.exec() && query.next()) { + int new_unread_count = query.value(0).toInt(); if (status() == NewMessages && new_unread_count < m_unreadCount) { setStatus(Normal); @@ -544,7 +549,7 @@ bool StandardFeed::addItself(RootItem *parent) { query_add_feed.bindValue(QSL(":type"), (int) type()); if (!query_add_feed.exec()) { - qDebug("Failed to add feed to database: %s.", qPrintable(query_add_feed.lastError().text())); + qDebug("Failed to add feed to database: '%s'.", qPrintable(query_add_feed.lastError().text())); // Query failed. return false; @@ -641,7 +646,7 @@ int StandardFeed::updateMessages(const QList &messages) { if (!database.transaction()) { database.rollback(); - qDebug("Transaction start for message downloader failed."); + qDebug("Transaction start for message downloader failed: '%s'.", qPrintable(database.lastError().text())); return updated_messages; } @@ -692,7 +697,6 @@ int StandardFeed::updateMessages(const QList &messages) { } query_insert.finish(); - qDebug("Adding new message '%s' to DB.", qPrintable(message.m_title)); } else if (message.m_createdFromFeed && !datetime_stamps.contains(message.m_created.toMSecsSinceEpoch())) { @@ -704,7 +708,6 @@ int StandardFeed::updateMessages(const QList &messages) { query_update.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); query_update.exec(); query_update.finish(); - qDebug("Updating contents of duplicate message '%s'.", qPrintable(message.m_title)); } else { @@ -723,7 +726,6 @@ int StandardFeed::updateMessages(const QList &messages) { } query_insert.finish(); - qDebug("Adding new duplicate (with potentially updated contents) message '%s' to DB.", qPrintable(message.m_title)); } } @@ -735,7 +737,6 @@ int StandardFeed::updateMessages(const QList &messages) { if (!database.commit()) { database.rollback(); - qDebug("Transaction commit for message downloader failed."); } else { @@ -768,7 +769,6 @@ StandardFeed::StandardFeed(const QSqlRecord &record) : Feed(NULL) { setPassword(TextFactory::decrypt(record.value(FDS_DB_PASSWORD_INDEX).toString())); } - setAutoUpdateType(static_cast(record.value(FDS_DB_UPDATE_TYPE_INDEX).toInt())); setAutoUpdateInitialInterval(record.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt()); } diff --git a/src/services/standard/standardserviceentrypoint.cpp b/src/services/standard/standardserviceentrypoint.cpp index 74a4bfee4..75deae2d7 100755 --- a/src/services/standard/standardserviceentrypoint.cpp +++ b/src/services/standard/standardserviceentrypoint.cpp @@ -71,8 +71,11 @@ ServiceRoot *StandardServiceEntryPoint::createNewRoot() { int id_to_assign = query.value(0).toInt() + 1; - if (query.exec(QString("INSERT INTO Accounts (id, type) VALUES (%1, '%2');").arg(QString::number(id_to_assign), - SERVICE_CODE_STD_RSS))) { + query.prepare(QSL("INSERT INTO Accounts (id, type) VALUES (:id, :type);")); + query.bindValue(QSL(":id"), id_to_assign); + query.bindValue(QSL(":type"), SERVICE_CODE_STD_RSS); + + if (query.exec()) { StandardServiceRoot *root = new StandardServiceRoot(); root->setAccountId(id_to_assign); return root; @@ -88,7 +91,11 @@ QList StandardServiceEntryPoint::initializeSubtree() { QSqlQuery query(database); QList roots; - if (query.exec(QString("SELECT id FROM Accounts WHERE type = '%1';").arg(SERVICE_CODE_STD_RSS))) { + query.setForwardOnly(true); + query.prepare(QSL("SELECT id FROM Accounts WHERE type = :type;")); + query.bindValue(QSL(":type"), SERVICE_CODE_STD_RSS); + + if (query.exec()) { while (query.next()) { StandardServiceRoot *root = new StandardServiceRoot(); root->setAccountId(query.value(0).toInt()); diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 5ee6f22c5..9c544b972 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -149,22 +149,11 @@ RecycleBin *StandardServiceRoot::recycleBin() { bool StandardServiceRoot::markFeedsReadUnread(QList items, ReadStatus read) { QSqlDatabase db_handle = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - - if (!db_handle.transaction()) { - qWarning("Starting transaction for feeds read change."); - return false; - } - QSqlQuery query_read_msg(db_handle); query_read_msg.setForwardOnly(true); - if (!query_read_msg.prepare(QString("UPDATE Messages SET is_read = :read " - "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0;").arg(textualFeedIds(items).join(QSL(", "))))) { - qWarning("Query preparation failed for feeds read change."); - - db_handle.rollback(); - return false; - } + query_read_msg.prepare(QString("UPDATE Messages SET is_read = :read " + "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0;").arg(textualFeedIds(items).join(QSL(", ")))); query_read_msg.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);