From b9a79ed514e7ab6bab0d6dedfcb9a78387d2b7c1 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 5 Feb 2016 17:14:29 +0100 Subject: Support result property transformations This can be used to modify each result before reporting it to the client. Alternatively this could also be done in the DomainTypeAdaptor, which would perhaps be the cleaner solution... --- common/facade.cpp | 1 + common/facade.h | 3 ++- common/queryrunner.cpp | 33 +++++++++++++++++++++++---------- common/queryrunner.h | 11 ++++++++++- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/common/facade.cpp b/common/facade.cpp index 540c364..1b91ce4 100644 --- a/common/facade.cpp +++ b/common/facade.cpp @@ -148,6 +148,7 @@ QPair, typename ResultEmitter::Ptr> { //The runner lives for the lifetime of the query auto runner = new QueryRunner(query, mResourceAccess, mResourceInstanceIdentifier, mDomainTypeAdaptorFactory, bufferTypeForDomainType()); + runner->setResultTransformation(mResultTransformation); return qMakePair(KAsync::null(), runner->emitter()); } diff --git a/common/facade.h b/common/facade.h index 71451e2..914b6fc 100644 --- a/common/facade.h +++ b/common/facade.h @@ -60,9 +60,10 @@ public: KAsync::Job create(const DomainType &domainObject) Q_DECL_OVERRIDE; KAsync::Job modify(const DomainType &domainObject) Q_DECL_OVERRIDE; KAsync::Job remove(const DomainType &domainObject) Q_DECL_OVERRIDE; - QPair, typename ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; + virtual QPair, typename ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; protected: + std::function mResultTransformation; //TODO use one resource access instance per application & per resource QSharedPointer mResourceAccess; DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index a62c64c..4d05721 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp @@ -41,14 +41,14 @@ template class QueryWorker : public QObject { public: - QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); + QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation); virtual ~QueryWorker(); qint64 executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface &resultProvider); qint64 executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface &resultProvider); private: - static void replaySet(ResultSet &resultSet, Sink::ResultProviderInterface &resultProvider, const QList &properties); + void replaySet(ResultSet &resultSet, Sink::ResultProviderInterface &resultProvider, const QList &properties); void readEntity(const Sink::Storage::NamedDatabase &db, const QByteArray &key, const std::function &resultCallback); @@ -60,6 +60,7 @@ private: qint64 load(const Sink::Query &query, const std::function &)> &baseSetRetriever, Sink::ResultProviderInterface &resultProvider, bool initialQuery); private: + QueryRunnerBase::ResultTransformation mResultTransformation; DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; QByteArray mResourceInstanceIdentifier; QByteArray mBufferType; @@ -78,8 +79,8 @@ QueryRunner::QueryRunner(const Sink::Query &query, const Sink::Resou mResultProvider->setFetcher([=](const typename DomainType::Ptr &parent) { Trace() << "Running fetcher"; auto resultProvider = mResultProvider; - async::run([query, instanceIdentifier, factory, bufferType, parent, resultProvider]() -> qint64 { - QueryWorker worker(query, instanceIdentifier, factory, bufferType); + async::run([=]() -> qint64 { + QueryWorker worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); const qint64 newRevision = worker.executeInitialQuery(query, parent, *resultProvider); return newRevision; }) @@ -96,8 +97,8 @@ QueryRunner::QueryRunner(const Sink::Query &query, const Sink::Resou //Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting setQuery([=] () -> KAsync::Job { auto resultProvider = mResultProvider; - QueryWorker worker(query, instanceIdentifier, factory, bufferType); return async::run([=]() -> qint64 { + QueryWorker worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); const qint64 newRevision = worker.executeIncrementalQuery(query, *resultProvider); return newRevision; }) @@ -120,6 +121,12 @@ QueryRunner::~QueryRunner() Trace() << "Stopped query"; } +template +void QueryRunner::setResultTransformation(const ResultTransformation &transformation) +{ + mResultTransformation = transformation; +} + template typename Sink::ResultEmitter::Ptr QueryRunner::emitter() { @@ -150,8 +157,9 @@ static inline ResultSet fullScan(const Sink::Storage::Transaction &transaction, template -QueryWorker::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType) +QueryWorker::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation) : QObject(), + mResultTransformation(transformation), mDomainTypeAdaptorFactory(factory), mResourceInstanceIdentifier(instanceIdentifier), mBufferType(bufferType), @@ -170,20 +178,25 @@ template void QueryWorker::replaySet(ResultSet &resultSet, Sink::ResultProviderInterface &resultProvider, const QList &properties) { int counter = 0; - while (resultSet.next([&resultProvider, &counter, &properties](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &value, Sink::Operation operation) -> bool { + while (resultSet.next([this, &resultProvider, &counter, &properties](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &value, Sink::Operation operation) -> bool { + //FIXME allow maildir resource to set the mimeMessage property + auto valueCopy = Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(*value, properties).template staticCast(); + if (mResultTransformation) { + mResultTransformation(*valueCopy); + } counter++; switch (operation) { case Sink::Operation_Creation: // Trace() << "Got creation"; - resultProvider.add(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(*value, properties).template staticCast()); + resultProvider.add(valueCopy); break; case Sink::Operation_Modification: // Trace() << "Got modification"; - resultProvider.modify(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(*value, properties).template staticCast()); + resultProvider.modify(valueCopy); break; case Sink::Operation_Removal: // Trace() << "Got removal"; - resultProvider.remove(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(*value, properties).template staticCast()); + resultProvider.remove(valueCopy); break; } return true; diff --git a/common/queryrunner.h b/common/queryrunner.h index 0ee6a81..04e4587 100644 --- a/common/queryrunner.h +++ b/common/queryrunner.h @@ -32,6 +32,9 @@ class QueryRunnerBase : public QObject { Q_OBJECT +public: + typedef std::function ResultTransformation; + protected: typedef std::function()> QueryFunction; @@ -43,7 +46,6 @@ protected: queryFunction = query; } - protected slots: /** * Rerun query with new revision @@ -82,10 +84,17 @@ public: QueryRunner(const Sink::Query &query, const Sink::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); virtual ~QueryRunner(); + /** + * Allows you to run a transformation on every result. + * This transformation is executed in the query thread. + */ + void setResultTransformation(const ResultTransformation &transformation); + typename Sink::ResultEmitter::Ptr emitter(); private: QSharedPointer mResourceAccess; QSharedPointer > mResultProvider; + ResultTransformation mResultTransformation; }; -- cgit v1.2.3