Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor DB code with Database(Holder|Helper) #245

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
2 changes: 2 additions & 0 deletions YACReaderLibrary/YACReaderLibrary.pro
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ HEADERS += comic_flow.h \
import_comics_info_dialog.h \
server_config_dialog.h \
comic_flow_widget.h \
database_helper.h \
db_helper.h \
./db/data_base_management.h \
./db/folder_item.h \
Expand Down Expand Up @@ -171,6 +172,7 @@ SOURCES += comic_flow.cpp \
import_comics_info_dialog.cpp \
server_config_dialog.cpp \
comic_flow_widget.cpp \
database_helper.cpp \
db_helper.cpp \
./db/data_base_management.cpp \
./db/folder_item.cpp \
Expand Down
33 changes: 33 additions & 0 deletions YACReaderLibrary/database_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "database_helper.h"

#include "data_base_management.h"

#include "QsLog.h"

using namespace YACReader;

DatabaseHolder::DatabaseHolder(const QString &path)
: DatabaseHolder { DataBaseManagement::loadDatabase(path) }
{
}

DatabaseHolder::DatabaseHolder(const QSqlDatabase &db)
: db { db }
{
remover.setDb(this->db);
}

void DatabaseHolder::Remover::setDb(const QSqlDatabase &db)
{
connectionName = db.connectionName();
Q_ASSERT(!connectionName.isEmpty());
}

DatabaseHolder::Remover::~Remover()
{
if (connectionName.isEmpty()) {
QLOG_WARN() << "DatabaseHolder::Remover cannot remove a database: empty connection name.";
return;
}
QSqlDatabase::removeDatabase(connectionName);
}
124 changes: 124 additions & 0 deletions YACReaderLibrary/database_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#ifndef DATABASE_HELPER_H
#define DATABASE_HELPER_H

#include "comic_db.h"
#include "db_helper.h"
#include "folder.h"

#include <QList>
#include <QSqlDatabase>
#include <QString>

#include <utility>

namespace YACReader {

//! A RAII class that adds or adopts a QSqlDatabase connection in its constructors
//! and removes this connection via QSqlDatabase::removeDatabase() in the destructor.
class DatabaseHolder
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
Q_DISABLE_COPY_MOVE(DatabaseHolder)
#else
Q_DISABLE_COPY(DatabaseHolder)
#endif
public:
explicit DatabaseHolder(const QString &path);
explicit DatabaseHolder(const QSqlDatabase &db);

QSqlDatabase &operator*() { return db; }
QSqlDatabase *operator->() { return &db; }

private:
class Remover
{
public:
void setDb(const QSqlDatabase &db);
~Remover();

private:
QString connectionName;
};

// The order of the data members is important: remover must be destroyed after
// db to avoid the Qt warning in log - "QSqlDatabasePrivate::removeDatabase:
// connection '<name>' is still in use, all queries will cease to work."
Remover remover;
QSqlDatabase db;
};

//! A wrapper around DatabaseHolder that makes access to the managed QSqlDatabase
//! object a bit more verbose, but provides convenience forwarding functions for
//! all DBHelper's member functions that take a QSqlDatabase & argument.
class DatabaseHelper
{
public:
//! @note Access to DatabaseHolder(const QSqlDatabase &db) is intentionally
//! restricted to prevent its use by mistake. The QString constructor
//! overload is much more common and should be used most of the time. Use
//! DatabaseHolder directly if you need to load a database differently.
explicit DatabaseHelper(const QString &path)
: holder(path) { }

QSqlDatabase &db() { return *holder; }

// All public member functions below simply forward their arguments and db() to DBHelper.

//objects management
//deletes
void removeFromDB(LibraryItem *item) { DBHelper::removeFromDB(item, db()); }
void removeFromDB(Folder *folder) { DBHelper::removeFromDB(folder, db()); }
void removeFromDB(ComicDB *comic) { DBHelper::removeFromDB(comic, db()); }
void removeLabelFromDB(qulonglong id) { DBHelper::removeLabelFromDB(id, db()); }
void removeListFromDB(qulonglong id) { DBHelper::removeListFromDB(id, db()); }
//logic deletes
void deleteComicsFromFavorites(const QList<ComicDB> &comicsList) { DBHelper::deleteComicsFromFavorites(comicsList, db()); }
void deleteComicsFromLabel(const QList<ComicDB> &comicsList, qulonglong labelId) { DBHelper::deleteComicsFromLabel(comicsList, labelId, db()); }
void deleteComicsFromReadingList(const QList<ComicDB> &comicsList, qulonglong readingListId) { DBHelper::deleteComicsFromReadingList(comicsList, readingListId, db()); }
//inserts
qulonglong insert(Folder *folder) { return DBHelper::insert(folder, db()); }
qulonglong insert(ComicDB *comic) { return DBHelper::insert(comic, db()); }
qulonglong insertLabel(const QString &name, YACReader::LabelColors color) { return DBHelper::insertLabel(name, color, db()); }
qulonglong insertReadingList(const QString &name) { return DBHelper::insertReadingList(name, db()); }
qulonglong insertReadingSubList(const QString &name, qulonglong parentId, int ordering) { return DBHelper::insertReadingSubList(name, parentId, ordering, db()); }
void insertComicsInFavorites(const QList<ComicDB> &comicsList) { DBHelper::insertComicsInFavorites(comicsList, db()); }
void insertComicsInLabel(const QList<ComicDB> &comicsList, qulonglong labelId) { DBHelper::insertComicsInLabel(comicsList, labelId, db()); }
void insertComicsInReadingList(const QList<ComicDB> &comicsList, qulonglong readingListId) { DBHelper::insertComicsInReadingList(comicsList, readingListId, db()); }
//updates
void update(ComicDB *comics) { DBHelper::update(comics, db()); }
void update(ComicInfo *comicInfo) { DBHelper::update(comicInfo, db()); }
void updateRead(ComicInfo *comicInfo) { DBHelper::updateRead(comicInfo, db()); }
void update(const Folder &folder) { DBHelper::update(folder, db()); }
void updateChildrenInfo(const Folder &folder) { DBHelper::updateChildrenInfo(folder, db()); }
void updateChildrenInfo(qulonglong folderId) { DBHelper::updateChildrenInfo(folderId, db()); }
void updateChildrenInfo() { DBHelper::updateChildrenInfo(db()); }
void updateReadingRemoteProgress(const ComicInfo &comicInfo) { DBHelper::updateReadingRemoteProgress(comicInfo, db()); }
void renameLabel(qulonglong id, const QString &name) { DBHelper::renameLabel(id, name, db()); }
void renameList(qulonglong id, const QString &name) { DBHelper::renameList(id, name, db()); }
void reassignOrderToSublists(const QList<qulonglong> &ids) { DBHelper::reassignOrderToSublists(ids, db()); }
void reassignOrderToComicsInFavorites(const QList<qulonglong> &comicIds) { DBHelper::reassignOrderToComicsInFavorites(comicIds, db()); }
void reassignOrderToComicsInLabel(qulonglong labelId, const QList<qulonglong> &comicIds) { DBHelper::reassignOrderToComicsInLabel(labelId, comicIds, db()); }
void reassignOrderToComicsInReadingList(qulonglong readingListId, const QList<qulonglong> &comicIds) { DBHelper::reassignOrderToComicsInReadingList(readingListId, comicIds, db()); }

QList<LibraryItem *> getFoldersFromParent(qulonglong parentId, bool sort = true) { return DBHelper::getFoldersFromParent(parentId, db(), sort); }
QList<ComicDB> getSortedComicsFromParent(qulonglong parentId) { return DBHelper::getSortedComicsFromParent(parentId, db()); }
QList<LibraryItem *> getComicsFromParent(qulonglong parentId, bool sort = true) { return DBHelper::getComicsFromParent(parentId, db(), sort); }

void updateFolderTreeManga(qulonglong id, bool manga) { DBHelper::updateFolderTreeManga(id, manga, db()); }

//load
Folder loadFolder(qulonglong id) { return DBHelper::loadFolder(id, db()); }
Folder loadFolder(const QString &folderName, qulonglong parentId) { return DBHelper::loadFolder(folderName, parentId, db()); }
ComicDB loadComic(qulonglong id) { return DBHelper::loadComic(id, db()); }
ComicDB loadComic(QString cname, QString cpath, const QString &chash) { return DBHelper::loadComic(std::move(cname), std::move(cpath), chash, db()); }
ComicInfo loadComicInfo(const QString &hash) { return DBHelper::loadComicInfo(hash, db()); }
QList<QString> loadSubfoldersNames(qulonglong folderId) { return DBHelper::loadSubfoldersNames(folderId, db()); }
//queries
bool isFavoriteComic(qulonglong id) { return DBHelper::isFavoriteComic(id, db()); }

private:
DatabaseHolder holder;
};
} // namespace YACReader

#endif // DATABASE_HELPER_H
6 changes: 3 additions & 3 deletions YACReaderLibrary/db/comic_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
switch (mode) {
case Favorites:
DBHelper::reasignOrderToComicsInFavorites(allComicIds, db);
DBHelper::reassignOrderToComicsInFavorites(allComicIds, db);
break;
case Label:
DBHelper::reasignOrderToComicsInLabel(sourceId, allComicIds, db);
DBHelper::reassignOrderToComicsInLabel(sourceId, allComicIds, db);
break;
case ReadingList:
DBHelper::reasignOrderToComicsInReadingList(sourceId, allComicIds, db);
DBHelper::reassignOrderToComicsInReadingList(sourceId, allComicIds, db);
break;
default:
break;
Expand Down
1 change: 0 additions & 1 deletion YACReaderLibrary/db/comic_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <QModelIndex>
#include <QVariant>
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QUrl>

#include "yacreader_global_gui.h"
Expand Down
4 changes: 4 additions & 0 deletions YACReaderLibrary/db/comic_query_result_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

#include "QsLog.h"

#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>

QString getLastExecutedQuery(const QSqlQuery &query)
{
QString str = query.lastQuery();
Expand Down
Loading