From 73241e4bb7a7f535239642b0bcdf808e9f62899d Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 12 Apr 2016 13:30:31 +0200 Subject: [PATCH] SQL refactoring. --- src/miscellaneous/databasequeries.cpp | 207 +++++++++++++++++- src/miscellaneous/databasequeries.h | 15 ++ src/services/standard/standardfeed.cpp | 85 ++----- .../standard/standardserviceentrypoint.cpp | 37 +--- src/services/standard/standardserviceroot.cpp | 60 +---- 5 files changed, 247 insertions(+), 157 deletions(-) diff --git a/src/miscellaneous/databasequeries.cpp b/src/miscellaneous/databasequeries.cpp index 67a187fde..70b8762d3 100644 --- a/src/miscellaneous/databasequeries.cpp +++ b/src/miscellaneous/databasequeries.cpp @@ -18,11 +18,13 @@ #include "miscellaneous/databasequeries.h" #include "services/abstract/category.h" -#include "services/abstract/feed.h" #include "services/owncloud/owncloudserviceroot.h" #include "services/owncloud/owncloudcategory.h" #include "services/owncloud/owncloudfeed.h" #include "services/owncloud/network/owncloudnetworkfactory.h" +#include "services/standard/standardserviceroot.h" +#include "services/standard/standardcategory.h" +#include "services/standard/standardfeed.h" #include "miscellaneous/textfactory.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" @@ -1067,5 +1069,208 @@ bool DatabaseQueries::editCategory(QSqlDatabase db, int parent_id, int category_ return q.exec(); } +int DatabaseQueries::addFeed(QSqlDatabase db, int parent_id, int account_id, const QString &title, + const QString &description, QDateTime creation_date, const QIcon &icon, + const QString &encoding, const QString &url, bool is_protected, + const QString &username, const QString &password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format, bool *ok) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare("INSERT INTO Feeds " + "(title, description, date_created, icon, category, encoding, url, protected, username, password, update_type, update_interval, type, account_id) " + "VALUES (:title, :description, :date_created, :icon, :category, :encoding, :url, :protected, :username, :password, :update_type, :update_interval, :type, :account_id);"); + q.bindValue(QSL(":title"), title); + q.bindValue(QSL(":description"), description); + q.bindValue(QSL(":date_created"), creation_date.toMSecsSinceEpoch()); + q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon)); + q.bindValue(QSL(":category"), parent_id); + q.bindValue(QSL(":encoding"), encoding); + q.bindValue(QSL(":url"), url); + q.bindValue(QSL(":protected"), is_protected ? 1 : 0); + q.bindValue(QSL(":username"), username); + q.bindValue(QSL(":account_id"), account_id); + + if (password.isEmpty()) { + q.bindValue(QSL(":password"), password); + } + else { + q.bindValue(QSL(":password"), TextFactory::encrypt(password)); + } + + q.bindValue(QSL(":update_type"), (int) auto_update_type); + q.bindValue(QSL(":update_interval"), auto_update_interval); + q.bindValue(QSL(":type"), (int) feed_format); + + if (q.exec()) { + int new_id = q.lastInsertId().toInt(); + + // Now set custom ID in the DB. + q.prepare(QSL("UPDATE Feeds SET custom_id = :custom_id WHERE id = :id;")); + q.bindValue(QSL(":custom_id"), QString::number(new_id)); + q.bindValue(QSL(":id"), new_id); + q.exec(); + + if (ok != NULL) { + *ok = true; + } + + return new_id; + } + else { + if (ok != NULL) { + *ok = false; + } + + qDebug("Failed to add feed to database: '%s'.", qPrintable(q.lastError().text())); + return 0; + } +} + +bool DatabaseQueries::editFeed(QSqlDatabase db, int parent_id, int feed_id, const QString &title, + const QString &description, const QIcon &icon, + const QString &encoding, const QString &url, bool is_protected, + const QString &username, const QString &password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format) { + QSqlQuery q(db); + q.setForwardOnly(true); + + q.prepare("UPDATE Feeds " + "SET title = :title, description = :description, icon = :icon, category = :category, encoding = :encoding, url = :url, protected = :protected, username = :username, password = :password, update_type = :update_type, update_interval = :update_interval, type = :type " + "WHERE id = :id;"); + q.bindValue(QSL(":title"), title); + q.bindValue(QSL(":description"), description); + q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon)); + q.bindValue(QSL(":category"), parent_id); + q.bindValue(QSL(":encoding"), encoding); + q.bindValue(QSL(":url"), url); + q.bindValue(QSL(":protected"), is_protected ? 1 : 0); + q.bindValue(QSL(":username"), username); + + if (password.isEmpty()) { + q.bindValue(QSL(":password"), password); + } + else { + q.bindValue(QSL(":password"), TextFactory::encrypt(password)); + } + + q.bindValue(QSL(":update_type"), (int) auto_update_type); + q.bindValue(QSL(":update_interval"), auto_update_interval); + q.bindValue(QSL(":type"), feed_format); + q.bindValue(QSL(":id"), feed_id); + + return q.exec(); +} + +QList DatabaseQueries::getAccounts(QSqlDatabase db, bool *ok) { + QSqlQuery q(db); + QList roots; + + q.setForwardOnly(true); + q.prepare(QSL("SELECT id FROM Accounts WHERE type = :type;")); + q.bindValue(QSL(":type"), SERVICE_CODE_STD_RSS); + + if (q.exec()) { + while (q.next()) { + StandardServiceRoot *root = new StandardServiceRoot(); + root->setAccountId(q.value(0).toInt()); + roots.append(root); + } + + if (ok != NULL) { + *ok = true; + } + } + else { + if (ok != NULL) { + *ok = false; + } + } + + return roots; +} + +Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool *ok) { + Assignment categories; + + // Obtain data for categories from the database. + QSqlQuery q(db); + q.setForwardOnly(true); + q.prepare(QSL("SELECT * FROM Categories WHERE account_id = :account_id;")); + q.bindValue(QSL(":account_id"), account_id); + + if (!q.exec()) { + qFatal("Query for obtaining categories failed. Error message: '%s'.", + qPrintable(q.lastError().text())); + + if (ok != NULL) { + *ok = false; + } + } + + if (ok != NULL) { + *ok = true; + } + + while (q.next()) { + AssignmentItem pair; + pair.first = q.value(CAT_DB_PARENT_ID_INDEX).toInt(); + pair.second = new StandardCategory(q.record()); + + categories << pair; + } + + return categories; +} + +Assignment DatabaseQueries::getFeeds(QSqlDatabase db, int account_id, bool *ok) { + Assignment feeds; + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); + q.bindValue(QSL(":account_id"), account_id); + + if (!q.exec()) { + qFatal("Query for obtaining feeds failed. Error message: '%s'.", + qPrintable(q.lastError().text())); + + if (ok != NULL) { + *ok = false; + } + } + + if (ok != NULL) { + *ok = true; + } + + while (q.next()) { + // Process this feed. + StandardFeed::Type type = static_cast(q.value(FDS_DB_TYPE_INDEX).toInt()); + + switch (type) { + case StandardFeed::Atom10: + case StandardFeed::Rdf: + case StandardFeed::Rss0X: + case StandardFeed::Rss2X: { + AssignmentItem pair; + pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); + pair.second = new StandardFeed(q.record()); + qobject_cast(pair.second)->setType(type); + + feeds << pair; + break; + } + + default: + break; + } + } + + return feeds; +} + DatabaseQueries::DatabaseQueries() { } diff --git a/src/miscellaneous/databasequeries.h b/src/miscellaneous/databasequeries.h index 2549b9609..548a68bb3 100644 --- a/src/miscellaneous/databasequeries.h +++ b/src/miscellaneous/databasequeries.h @@ -21,6 +21,7 @@ #include "services/abstract/rootitem.h" #include "services/abstract/serviceroot.h" +#include "services/standard/standardfeed.h" #include @@ -74,6 +75,20 @@ class DatabaseQueries { const QString &description, QDateTime creation_date, const QIcon &icon, bool *ok = NULL); static bool editCategory(QSqlDatabase db, int parent_id, int category_id, const QString &title, const QString &description, const QIcon &icon); + static int addFeed(QSqlDatabase db, int parent_id, int account_id, const QString &title, + const QString &description, QDateTime creation_date, const QIcon &icon, + const QString &encoding, const QString &url, bool is_protected, + const QString &username, const QString &password, + Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format, bool *ok = NULL); + static bool editFeed(QSqlDatabase db, int parent_id, int feed_id, const QString &title, + const QString &description, const QIcon &icon, + const QString &encoding, const QString &url, bool is_protected, + const QString &username, const QString &password, Feed::AutoUpdateType auto_update_type, + int auto_update_interval, StandardFeed::Type feed_format); + static QList getAccounts(QSqlDatabase db, bool *ok = NULL); + static Assignment getCategories(QSqlDatabase db, int account_id, bool *ok = NULL); + static Assignment getFeeds(QSqlDatabase db, int account_id, bool *ok = NULL); private: explicit DatabaseQueries(); diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp index d663bd7c8..a28c38782 100755 --- a/src/services/standard/standardfeed.cpp +++ b/src/services/standard/standardfeed.cpp @@ -381,86 +381,35 @@ bool StandardFeed::removeItself() { bool StandardFeed::addItself(RootItem *parent) { // Now, add feed to persistent storage. QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query_add_feed(database); - - query_add_feed.setForwardOnly(true); - query_add_feed.prepare("INSERT INTO Feeds " - "(title, description, date_created, icon, category, encoding, url, protected, username, password, update_type, update_interval, type, account_id) " - "VALUES (:title, :description, :date_created, :icon, :category, :encoding, :url, :protected, :username, :password, :update_type, :update_interval, :type, :account_id);"); - query_add_feed.bindValue(QSL(":title"), title()); - query_add_feed.bindValue(QSL(":description"), description()); - query_add_feed.bindValue(QSL(":date_created"), creationDate().toMSecsSinceEpoch()); - query_add_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon())); - query_add_feed.bindValue(QSL(":category"), parent->id()); - query_add_feed.bindValue(QSL(":encoding"), encoding()); - query_add_feed.bindValue(QSL(":url"), url()); - query_add_feed.bindValue(QSL(":protected"), (int) passwordProtected()); - query_add_feed.bindValue(QSL(":username"), username()); - query_add_feed.bindValue(QSL(":account_id"), parent->getParentServiceRoot()->accountId()); - - if (password().isEmpty()) { - query_add_feed.bindValue(QSL(":password"), password()); - } - else { - query_add_feed.bindValue(QSL(":password"), TextFactory::encrypt(password())); - } - - query_add_feed.bindValue(QSL(":update_type"), (int) autoUpdateType()); - query_add_feed.bindValue(QSL(":update_interval"), autoUpdateInitialInterval()); - 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())); + bool ok; + int new_id = DatabaseQueries::addFeed(database, parent->id(), parent->getParentServiceRoot()->accountId(), title(), + description(), creationDate(), icon(), encoding(), url(), passwordProtected(), + username(), password(), autoUpdateType(), autoUpdateInitialInterval(), type(), &ok); + if (!ok) { // Query failed. return false; } + else { + // New feed was added, fetch is primary id from the database. + setId(new_id); + setCustomId(new_id); - // New feed was added, fetch is primary id from the database. - setId(query_add_feed.lastInsertId().toInt()); - setCustomId(id()); - - // Now set custom ID in the DB. - query_add_feed.prepare(QSL("UPDATE Feeds SET custom_id = :custom_id WHERE id = :id;")); - query_add_feed.bindValue(QSL(":custom_id"), QString::number(customId())); - query_add_feed.bindValue(QSL(":id"), id()); - query_add_feed.exec(); - - return true; + return true; + } } bool StandardFeed::editItself(StandardFeed *new_feed_data) { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query_update_feed(database); StandardFeed *original_feed = this; RootItem *new_parent = new_feed_data->parent(); - query_update_feed.setForwardOnly(true); - query_update_feed.prepare("UPDATE Feeds " - "SET title = :title, description = :description, icon = :icon, category = :category, encoding = :encoding, url = :url, protected = :protected, username = :username, password = :password, update_type = :update_type, update_interval = :update_interval, type = :type " - "WHERE id = :id;"); - query_update_feed.bindValue(QSL(":title"), new_feed_data->title()); - query_update_feed.bindValue(QSL(":description"), new_feed_data->description()); - query_update_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(new_feed_data->icon())); - query_update_feed.bindValue(QSL(":category"), new_parent->id()); - query_update_feed.bindValue(QSL(":encoding"), new_feed_data->encoding()); - query_update_feed.bindValue(QSL(":url"), new_feed_data->url()); - query_update_feed.bindValue(QSL(":protected"), (int) new_feed_data->passwordProtected()); - query_update_feed.bindValue(QSL(":username"), new_feed_data->username()); - - if (password().isEmpty()) { - query_update_feed.bindValue(QSL(":password"), new_feed_data->password()); - } - else { - query_update_feed.bindValue(QSL(":password"), TextFactory::encrypt(new_feed_data->password())); - } - - query_update_feed.bindValue(QSL(":update_type"), (int) new_feed_data->autoUpdateType()); - query_update_feed.bindValue(QSL(":update_interval"), new_feed_data->autoUpdateInitialInterval()); - query_update_feed.bindValue(QSL(":type"), new_feed_data->type()); - query_update_feed.bindValue(QSL(":id"), original_feed->id()); - - if (!query_update_feed.exec()) { + if (!DatabaseQueries::editFeed(database, new_parent->id(), original_feed->id(), new_feed_data->title(), + new_feed_data->description(), new_feed_data->icon(), + new_feed_data->encoding(), new_feed_data->url(), new_feed_data->passwordProtected(), + new_feed_data->username(), new_feed_data->password(), + new_feed_data->autoUpdateType(), new_feed_data->autoUpdateInitialInterval(), + new_feed_data->type())) { // Persistent storage update failed, no way to continue now. return false; } diff --git a/src/services/standard/standardserviceentrypoint.cpp b/src/services/standard/standardserviceentrypoint.cpp index 1b5824f4e..46d7655a3 100755 --- a/src/services/standard/standardserviceentrypoint.cpp +++ b/src/services/standard/standardserviceentrypoint.cpp @@ -20,10 +20,9 @@ #include "definitions/definitions.h" #include "miscellaneous/application.h" +#include "miscellaneous/databasequeries.h" #include "services/standard/standardserviceroot.h" -#include - StandardServiceEntryPoint::StandardServiceEntryPoint() { } @@ -62,22 +61,12 @@ QString StandardServiceEntryPoint::code() const { ServiceRoot *StandardServiceEntryPoint::createNewRoot() const { // Switch DB. QSqlDatabase database = qApp->database()->connection(QSL("StandardServiceEntryPoint"), DatabaseFactory::FromSettings); - QSqlQuery query(database); + bool ok; + int new_id = DatabaseQueries::createAccount(database, code(), &ok); - // First obtain the ID, which can be assigned to this new account. - if (!query.exec("SELECT max(id) FROM Accounts;") || !query.next()) { - return NULL; - } - - int id_to_assign = query.value(0).toInt() + 1; - - query.prepare(QSL("INSERT INTO Accounts (id, type) VALUES (:id, :type);")); - query.bindValue(QSL(":id"), id_to_assign); - query.bindValue(QSL(":type"), code()); - - if (query.exec()) { + if (ok) { StandardServiceRoot *root = new StandardServiceRoot(); - root->setAccountId(id_to_assign); + root->setAccountId(new_id); return root; } else { @@ -88,20 +77,6 @@ ServiceRoot *StandardServiceEntryPoint::createNewRoot() const { QList StandardServiceEntryPoint::initializeSubtree() const { // Check DB if standard account is enabled. QSqlDatabase database = qApp->database()->connection(QSL("StandardServiceEntryPoint"), DatabaseFactory::FromSettings); - QSqlQuery query(database); - QList roots; - query.setForwardOnly(true); - query.prepare(QSL("SELECT id FROM Accounts WHERE type = :type;")); - query.bindValue(QSL(":type"), code()); - - if (query.exec()) { - while (query.next()) { - StandardServiceRoot *root = new StandardServiceRoot(); - root->setAccountId(query.value(0).toInt()); - roots.append(root); - } - } - - return roots; + return DatabaseQueries::getAccounts(database); } diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 551076a12..9f3e00509 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -21,6 +21,7 @@ #include "miscellaneous/application.h" #include "miscellaneous/settings.h" #include "miscellaneous/iconfactory.h" +#include "miscellaneous/databasequeries.h" #include "miscellaneous/mutex.h" #include "core/feedsmodel.h" #include "gui/messagebox.h" @@ -35,8 +36,6 @@ #include "services/standard/gui/formstandardfeeddetails.h" #include "services/standard/gui/formstandardimportexport.h" -#include -#include #include #include #include @@ -173,61 +172,8 @@ RecycleBin *StandardServiceRoot::recycleBin() const { void StandardServiceRoot::loadFromDatabase(){ QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - Assignment categories; - Assignment feeds; - - // Obtain data for categories from the database. - QSqlQuery query_categories(database); - query_categories.setForwardOnly(true); - query_categories.prepare(QSL("SELECT * FROM Categories WHERE account_id = :account_id;")); - query_categories.bindValue(QSL(":account_id"), accountId()); - - if (!query_categories.exec()) { - qFatal("Query for obtaining categories failed. Error message: '%s'.", - qPrintable(query_categories.lastError().text())); - } - - while (query_categories.next()) { - AssignmentItem pair; - pair.first = query_categories.value(CAT_DB_PARENT_ID_INDEX).toInt(); - pair.second = new StandardCategory(query_categories.record()); - - categories << pair; - } - - // All categories are now loaded. - QSqlQuery query_feeds(database); - query_feeds.setForwardOnly(true); - query_feeds.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); - query_feeds.bindValue(QSL(":account_id"), accountId()); - - if (!query_feeds.exec()) { - qFatal("Query for obtaining feeds failed. Error message: '%s'.", - qPrintable(query_feeds.lastError().text())); - } - - while (query_feeds.next()) { - // Process this feed. - StandardFeed::Type type = static_cast(query_feeds.value(FDS_DB_TYPE_INDEX).toInt()); - - switch (type) { - case StandardFeed::Atom10: - case StandardFeed::Rdf: - case StandardFeed::Rss0X: - case StandardFeed::Rss2X: { - AssignmentItem pair; - pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); - pair.second = new StandardFeed(query_feeds.record()); - qobject_cast(pair.second)->setType(type); - - feeds << pair; - break; - } - - default: - break; - } - } + Assignment categories = DatabaseQueries::getCategories(database, accountId()); + Assignment feeds = DatabaseQueries::getFeeds(database, accountId()); // All data are now obtained, lets create the hierarchy. assembleCategories(categories);