From 2cbbdaca7c6e96e40b17b6af4672af2b6735bf8e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 12 Apr 2016 22:03:27 +0200 Subject: Generalized LocalStorageFacade --- common/resourcefacade.cpp | 242 +++++++++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 111 deletions(-) (limited to 'common/resourcefacade.cpp') diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 2969c44..935c613 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp @@ -24,6 +24,136 @@ #include "storage.h" #include +template +ConfigNotifier LocalStorageFacade::sConfigNotifier; + +template +LocalStorageFacade::LocalStorageFacade(const QByteArray &identifier) : Sink::StoreFacade(), mConfigStore(identifier) +{ +} + +template +LocalStorageFacade::~LocalStorageFacade() +{ +} + +template +typename DomainType::Ptr LocalStorageFacade::readFromConfig(const QByteArray &id, const QByteArray &type) +{ + auto object = DomainType::Ptr::create(id); + object->setProperty("type", type); + const auto configurationValues = mConfigStore.get(id); + for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { + object->setProperty(it.key(), it.value()); + } + return object; +} + +template +KAsync::Job LocalStorageFacade::create(const DomainType &domainObject) +{ + return KAsync::start([domainObject, this]() { + const QByteArray type = domainObject.getProperty("type").toByteArray(); + //FIXME use .identifier() instead + const QByteArray providedIdentifier = domainObject.getProperty("identifier").toByteArray(); + const QByteArray identifier = providedIdentifier.isEmpty() ? ResourceConfig::newIdentifier(type) : providedIdentifier; + mConfigStore.add(identifier, type); + auto changedProperties = domainObject.changedProperties(); + changedProperties.removeOne("identifier"); + changedProperties.removeOne("type"); + if (!changedProperties.isEmpty()) { + // We have some configuration values + QMap configurationValues; + for (const auto &property : changedProperties) { + configurationValues.insert(property, domainObject.getProperty(property)); + } + mConfigStore.modify(identifier, configurationValues); + } + sConfigNotifier.add(readFromConfig(identifier, type)); + }); +} + +template +KAsync::Job LocalStorageFacade::modify(const DomainType &domainObject) +{ + return KAsync::start([domainObject, this]() { + const QByteArray identifier = domainObject.identifier(); + if (identifier.isEmpty()) { + Warning() << "We need an \"identifier\" property to identify the entity to configure."; + return; + } + auto changedProperties = domainObject.changedProperties(); + changedProperties.removeOne("identifier"); + changedProperties.removeOne("type"); + if (!changedProperties.isEmpty()) { + // We have some configuration values + QMap configurationValues; + for (const auto &property : changedProperties) { + configurationValues.insert(property, domainObject.getProperty(property)); + } + mConfigStore.modify(identifier, configurationValues); + } + + const auto type = mConfigStore.getEntries().value(identifier); + sConfigNotifier.modify(readFromConfig(identifier, type)); + }); +} + +template +KAsync::Job LocalStorageFacade::remove(const DomainType &domainObject) +{ + return KAsync::start([domainObject, this]() { + const QByteArray identifier = domainObject.identifier(); + if (identifier.isEmpty()) { + Warning() << "We need an \"identifier\" property to identify the entity to configure"; + return; + } + mConfigStore.remove(identifier); + sConfigNotifier.remove(QSharedPointer::create(domainObject)); + }); +} + +template +QPair, typename Sink::ResultEmitter::Ptr> LocalStorageFacade::load(const Sink::Query &query) +{ + QObject *guard = new QObject; + auto resultProvider = new Sink::ResultProvider(); + auto emitter = resultProvider->emitter(); + resultProvider->setFetcher([](const QSharedPointer &) {}); + resultProvider->onDone([=]() { delete resultProvider; delete guard; }); + auto job = KAsync::start([=]() { + const auto entries = mConfigStore.getEntries(); + for (const auto &res : entries.keys()) { + const auto type = entries.value(res); + if (!query.ids.isEmpty() && !query.ids.contains(res)) { + continue; + } + resultProvider->add(readFromConfig(res, type)); + } + if (query.liveQuery) { + QObject::connect(&sConfigNotifier, &ConfigNotifier::modified, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { + resultProvider->modify(entry.staticCast()); + }); + QObject::connect(&sConfigNotifier, &ConfigNotifier::added, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { + resultProvider->add(entry.staticCast()); + }); + QObject::connect(&sConfigNotifier, &ConfigNotifier::removed, guard,[resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { + resultProvider->remove(entry.staticCast()); + }); + } + // TODO initialResultSetComplete should be implicit + resultProvider->initialResultSetComplete(typename DomainType::Ptr()); + resultProvider->complete(); + }); + return qMakePair(job, emitter); +} + + + + + + + ResourceFacade::ResourceFacade(const QByteArray &) : Sink::StoreFacade() { } @@ -145,22 +275,7 @@ QPair, typename Sink::ResultEmittersetProperty("type", type); - const auto configurationValues = ConfigStore("accounts").get(id); - for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { - account->setProperty(it.key(), it.value()); - } - return account; -} - - -AccountFacade::AccountFacade(const QByteArray &) : Sink::StoreFacade(), mConfigStore("accounts") +AccountFacade::AccountFacade(const QByteArray &) : LocalStorageFacade("accounts") { } @@ -168,98 +283,3 @@ AccountFacade::~AccountFacade() { } -KAsync::Job AccountFacade::create(const Sink::ApplicationDomain::SinkAccount &account) -{ - return KAsync::start([account, this]() { - const QByteArray type = account.getProperty("type").toByteArray(); - const QByteArray providedIdentifier = account.getProperty("identifier").toByteArray(); - // It is currently a requirement that the account starts with the type - const QByteArray identifier = providedIdentifier.isEmpty() ? ResourceConfig::newIdentifier(type) : providedIdentifier; - mConfigStore.add(identifier, type); - auto changedProperties = account.changedProperties(); - changedProperties.removeOne("identifier"); - changedProperties.removeOne("type"); - if (!changedProperties.isEmpty()) { - // We have some configuration values - QMap configurationValues; - for (const auto &property : changedProperties) { - configurationValues.insert(property, account.getProperty(property)); - } - mConfigStore.modify(identifier, configurationValues); - } - sConfig->add(readAccountFromConfig(identifier, type)); - }); -} - -KAsync::Job AccountFacade::modify(const Sink::ApplicationDomain::SinkAccount &account) -{ - return KAsync::start([account, this]() { - const QByteArray identifier = account.identifier(); - if (identifier.isEmpty()) { - Warning() << "We need an \"identifier\" property to identify the account to configure."; - return; - } - auto changedProperties = account.changedProperties(); - changedProperties.removeOne("identifier"); - changedProperties.removeOne("type"); - if (!changedProperties.isEmpty()) { - // We have some configuration values - QMap configurationValues; - for (const auto &property : changedProperties) { - configurationValues.insert(property, account.getProperty(property)); - } - mConfigStore.modify(identifier, configurationValues); - } - - const auto type = mConfigStore.getEntries().value(identifier); - sConfig->modify(readAccountFromConfig(identifier, type)); - }); -} - -KAsync::Job AccountFacade::remove(const Sink::ApplicationDomain::SinkAccount &account) -{ - return KAsync::start([account, this]() { - const QByteArray identifier = account.identifier(); - if (identifier.isEmpty()) { - Warning() << "We need an \"identifier\" property to identify the account to configure"; - return; - } - mConfigStore.remove(identifier); - sConfig->remove(Sink::ApplicationDomain::SinkAccount::Ptr::create(account)); - }); -} - -QPair, typename Sink::ResultEmitter::Ptr> AccountFacade::load(const Sink::Query &query) -{ - QObject *guard = new QObject; - auto resultProvider = new Sink::ResultProvider(); - auto emitter = resultProvider->emitter(); - resultProvider->setFetcher([](const QSharedPointer &) {}); - resultProvider->onDone([=]() { delete resultProvider; delete guard; }); - auto job = KAsync::start([=]() { - const auto configuredAccounts = mConfigStore.getEntries(); - for (const auto &res : configuredAccounts.keys()) { - const auto type = configuredAccounts.value(res); - if (!query.ids.isEmpty() && !query.ids.contains(res)) { - continue; - } - - resultProvider->add(readAccountFromConfig(res, type)); - } - if (query.liveQuery) { - QObject::connect(sConfig, &ConfigNotifier::modified, guard, [resultProvider](const Sink::ApplicationDomain::SinkAccount::Ptr &account) { - resultProvider->modify(account); - }); - QObject::connect(sConfig, &ConfigNotifier::added, guard, [resultProvider](const Sink::ApplicationDomain::SinkAccount::Ptr &account) { - resultProvider->add(account); - }); - QObject::connect(sConfig, &ConfigNotifier::removed, guard,[resultProvider](const Sink::ApplicationDomain::SinkAccount::Ptr &account) { - resultProvider->remove(account); - }); - } - // TODO initialResultSetComplete should be implicit - resultProvider->initialResultSetComplete(Sink::ApplicationDomain::SinkAccount::Ptr()); - resultProvider->complete(); - }); - return qMakePair(job, emitter); -} -- cgit v1.2.3