CatalogueController.cpp
329 lines
| 10.7 KiB
| text/x-c
|
CppLexer
r1059 | #include <Catalogue/CatalogueController.h> | |||
#include <Variable/Variable.h> | ||||
#include <CatalogueDao.h> | ||||
r1125 | #include <ComparaisonPredicate.h> | |||
#include <CompoundPredicate.h> | ||||
#include <DBCatalogue.h> | ||||
#include <DBEvent.h> | ||||
r1159 | #include <DBEventProduct.h> | |||
r1125 | #include <DBTag.h> | |||
#include <IRequestPredicate.h> | ||||
r1059 | #include <QMutex> | |||
#include <QThread> | ||||
#include <QDir> | ||||
#include <QStandardPaths> | ||||
Q_LOGGING_CATEGORY(LOG_CatalogueController, "CatalogueController") | ||||
r1126 | namespace { | |||
r1125 | ||||
r1224 | static QString REPOSITORY_WORK_SUFFIX = QString{"_work"}; | |||
static QString REPOSITORY_TRASH_SUFFIX = QString{"_trash"}; | ||||
r1125 | } | |||
r1059 | class CatalogueController::CatalogueControllerPrivate { | |||
r1159 | ||||
r1059 | public: | |||
r1159 | explicit CatalogueControllerPrivate(CatalogueController *parent) : m_Q{parent} {} | |||
r1059 | QMutex m_WorkingMutex; | |||
CatalogueDao m_CatalogueDao; | ||||
r1125 | ||||
r1159 | QStringList m_RepositoryList; | |||
CatalogueController *m_Q; | ||||
void copyDBtoDB(const QString &dbFrom, const QString &dbTo); | ||||
QString toWorkRepository(QString repository); | ||||
QString toSyncRepository(QString repository); | ||||
r1224 | void savAllDB(); | |||
void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true); | ||||
void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist = true); | ||||
r1059 | }; | |||
CatalogueController::CatalogueController(QObject *parent) | ||||
r1159 | : impl{spimpl::make_unique_impl<CatalogueControllerPrivate>(this)} | |||
r1059 | { | |||
qCDebug(LOG_CatalogueController()) << tr("CatalogueController construction") | ||||
<< QThread::currentThread(); | ||||
} | ||||
CatalogueController::~CatalogueController() | ||||
{ | ||||
qCDebug(LOG_CatalogueController()) << tr("CatalogueController destruction") | ||||
<< QThread::currentThread(); | ||||
this->waitForFinish(); | ||||
} | ||||
r1159 | QStringList CatalogueController::getRepositories() const | |||
{ | ||||
return impl->m_RepositoryList; | ||||
} | ||||
r1125 | void CatalogueController::addDB(const QString &dbPath) | |||
{ | ||||
QDir dbDir(dbPath); | ||||
if (dbDir.exists()) { | ||||
auto dirName = dbDir.dirName(); | ||||
if (std::find(impl->m_RepositoryList.cbegin(), impl->m_RepositoryList.cend(), dirName) | ||||
!= impl->m_RepositoryList.cend()) { | ||||
qCCritical(LOG_CatalogueController()) | ||||
<< tr("Impossible to addDB that is already loaded"); | ||||
} | ||||
if (!impl->m_CatalogueDao.addDB(dbPath, dirName)) { | ||||
qCCritical(LOG_CatalogueController()) | ||||
<< tr("Impossible to addDB %1 from %2 ").arg(dirName, dbPath); | ||||
} | ||||
r1126 | else { | |||
r1159 | impl->m_RepositoryList << dirName; | |||
impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName)); | ||||
r1125 | } | |||
} | ||||
else { | ||||
qCCritical(LOG_CatalogueController()) << tr("Impossible to addDB that not exists: ") | ||||
<< dbPath; | ||||
} | ||||
} | ||||
void CatalogueController::saveDB(const QString &destinationPath, const QString &repository) | ||||
{ | ||||
if (!impl->m_CatalogueDao.saveDB(destinationPath, repository)) { | ||||
qCCritical(LOG_CatalogueController()) | ||||
<< tr("Impossible to saveDB %1 from %2 ").arg(repository, destinationPath); | ||||
} | ||||
} | ||||
std::list<std::shared_ptr<DBEvent> > | ||||
CatalogueController::retrieveEvents(const QString &repository) const | ||||
{ | ||||
r1159 | QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository; | |||
r1125 | auto eventsShared = std::list<std::shared_ptr<DBEvent> >{}; | |||
r1159 | auto events = impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName)); | |||
r1125 | for (auto event : events) { | |||
eventsShared.push_back(std::make_shared<DBEvent>(event)); | ||||
} | ||||
return eventsShared; | ||||
} | ||||
std::list<std::shared_ptr<DBEvent> > CatalogueController::retrieveAllEvents() const | ||||
{ | ||||
auto eventsShared = std::list<std::shared_ptr<DBEvent> >{}; | ||||
for (auto repository : impl->m_RepositoryList) { | ||||
eventsShared.splice(eventsShared.end(), retrieveEvents(repository)); | ||||
} | ||||
return eventsShared; | ||||
} | ||||
r1128 | std::list<std::shared_ptr<DBEvent> > | |||
r1143 | CatalogueController::retrieveEventsFromCatalogue(std::shared_ptr<DBCatalogue> catalogue) const | |||
r1128 | { | |||
auto eventsShared = std::list<std::shared_ptr<DBEvent> >{}; | ||||
auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue); | ||||
for (auto event : events) { | ||||
eventsShared.push_back(std::make_shared<DBEvent>(event)); | ||||
} | ||||
return eventsShared; | ||||
} | ||||
r1159 | void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event) | |||
{ | ||||
r1224 | event->setRepository(impl->toWorkRepository(event->getRepository())); | |||
r1159 | ||||
impl->m_CatalogueDao.updateEvent(*event); | ||||
} | ||||
void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event) | ||||
{ | ||||
// Remove it from both repository and repository_work | ||||
event->setRepository(impl->toWorkRepository(event->getRepository())); | ||||
impl->m_CatalogueDao.removeEvent(*event); | ||||
event->setRepository(impl->toSyncRepository(event->getRepository())); | ||||
impl->m_CatalogueDao.removeEvent(*event); | ||||
} | ||||
void CatalogueController::addEvent(std::shared_ptr<DBEvent> event) | ||||
{ | ||||
r1164 | event->setRepository(impl->toWorkRepository(event->getRepository())); | |||
r1159 | ||||
r1223 | auto eventTemp = *event; | |||
impl->m_CatalogueDao.addEvent(eventTemp); | ||||
r1159 | ||||
// Call update is necessary at the creation of add Event if it has some tags or some event | ||||
// products | ||||
if (!event->getEventProducts().empty() || !event->getTags().empty()) { | ||||
r1223 | ||||
auto eventProductsTemp = eventTemp.getEventProducts(); | ||||
auto eventProductTempUpdated = std::list<DBEventProduct>{}; | ||||
for (auto eventProductTemp : eventProductsTemp) { | ||||
eventProductTemp.setEvent(eventTemp); | ||||
eventProductTempUpdated.push_back(eventProductTemp); | ||||
} | ||||
eventTemp.setEventProducts(eventProductTempUpdated); | ||||
impl->m_CatalogueDao.updateEvent(eventTemp); | ||||
r1159 | } | |||
} | ||||
void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event) | ||||
{ | ||||
r1224 | impl->saveEvent(event, true); | |||
r1159 | } | |||
r1128 | std::list<std::shared_ptr<DBCatalogue> > | |||
r1159 | CatalogueController::retrieveCatalogues(const QString &repository) const | |||
r1128 | { | |||
r1159 | QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository; | |||
r1128 | auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{}; | |||
r1159 | auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName)); | |||
r1128 | for (auto catalogue : catalogues) { | |||
cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue)); | ||||
} | ||||
return cataloguesShared; | ||||
} | ||||
r1159 | void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue) | |||
{ | ||||
r1224 | catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository())); | |||
r1159 | ||||
impl->m_CatalogueDao.updateCatalogue(*catalogue); | ||||
} | ||||
void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue) | ||||
{ | ||||
// Remove it from both repository and repository_work | ||||
catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository())); | ||||
impl->m_CatalogueDao.removeCatalogue(*catalogue); | ||||
catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository())); | ||||
impl->m_CatalogueDao.removeCatalogue(*catalogue); | ||||
} | ||||
void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue) | ||||
{ | ||||
r1224 | impl->saveCatalogue(catalogue, true); | |||
r1159 | } | |||
void CatalogueController::saveAll() | ||||
{ | ||||
for (auto repository : impl->m_RepositoryList) { | ||||
// Save Event | ||||
auto events = this->retrieveEvents(repository); | ||||
for (auto event : events) { | ||||
r1224 | impl->saveEvent(event, false); | |||
r1159 | } | |||
// Save Catalogue | ||||
auto catalogues = this->retrieveCatalogues(repository); | ||||
for (auto catalogue : catalogues) { | ||||
r1224 | impl->saveCatalogue(catalogue, false); | |||
r1159 | } | |||
} | ||||
r1224 | ||||
impl->savAllDB(); | ||||
r1159 | } | |||
r1059 | void CatalogueController::initialize() | |||
{ | ||||
qCDebug(LOG_CatalogueController()) << tr("CatalogueController init") | ||||
<< QThread::currentThread(); | ||||
impl->m_WorkingMutex.lock(); | ||||
impl->m_CatalogueDao.initialize(); | ||||
r1126 | auto defaultRepositoryLocation | |||
= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); | ||||
QDir defaultRepositoryLocationDir; | ||||
if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) { | ||||
defaultRepositoryLocationDir.cd(defaultRepositoryLocation); | ||||
auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT); | ||||
r1159 | qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ") | |||
<< defaultRepository; | ||||
r1125 | this->addDB(defaultRepository); | |||
} | ||||
r1126 | else { | |||
qCWarning(LOG_CatalogueController()) | ||||
<< tr("Cannot load the persistent default repository from ") | ||||
<< defaultRepositoryLocation; | ||||
} | ||||
qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END"); | ||||
r1059 | } | |||
void CatalogueController::finalize() | ||||
{ | ||||
impl->m_WorkingMutex.unlock(); | ||||
} | ||||
void CatalogueController::waitForFinish() | ||||
{ | ||||
QMutexLocker locker{&impl->m_WorkingMutex}; | ||||
} | ||||
r1159 | ||||
void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom, | ||||
const QString &dbTo) | ||||
{ | ||||
r1225 | // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{}; | |||
r1164 | auto catalogues = m_CatalogueDao.getCatalogues(dbFrom); | |||
r1225 | auto events = m_CatalogueDao.getEvents(dbFrom); | |||
r1159 | for (auto catalogue : catalogues) { | |||
r1225 | m_CatalogueDao.copyCatalogue(catalogue, dbTo, true); | |||
r1159 | } | |||
for (auto event : events) { | ||||
r1225 | m_CatalogueDao.copyEvent(event, dbTo, true); | |||
r1159 | } | |||
} | ||||
QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository) | ||||
{ | ||||
auto syncRepository = toSyncRepository(repository); | ||||
r1224 | return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX); | |||
r1159 | } | |||
QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository) | ||||
{ | ||||
auto syncRepository = repository; | ||||
if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) { | ||||
syncRepository.remove(REPOSITORY_WORK_SUFFIX); | ||||
} | ||||
else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) { | ||||
syncRepository.remove(REPOSITORY_TRASH_SUFFIX); | ||||
} | ||||
return syncRepository; | ||||
} | ||||
r1224 | ||||
void CatalogueController::CatalogueControllerPrivate::savAllDB() | ||||
{ | ||||
for (auto repository : m_RepositoryList) { | ||||
auto defaultRepositoryLocation | ||||
= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); | ||||
m_CatalogueDao.saveDB(defaultRepositoryLocation, repository); | ||||
} | ||||
} | ||||
void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event, | ||||
bool persist) | ||||
{ | ||||
r1225 | m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true); | |||
r1224 | if (persist) { | |||
savAllDB(); | ||||
} | ||||
} | ||||
void CatalogueController::CatalogueControllerPrivate::saveCatalogue( | ||||
std::shared_ptr<DBCatalogue> catalogue, bool persist) | ||||
{ | ||||
r1225 | m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true); | |||
r1224 | if (persist) { | |||
savAllDB(); | ||||
} | ||||
} | ||||