diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-02-05 17:14:29 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-02-05 17:14:29 +0100 |
commit | b9a79ed514e7ab6bab0d6dedfcb9a78387d2b7c1 (patch) | |
tree | f3b51a296dd09ca0c0cd78c880c893de315a5a59 | |
parent | 36a742c33f0a3144ed8d5dbaf56d7b4ef4e4e3d3 (diff) | |
download | sink-b9a79ed514e7ab6bab0d6dedfcb9a78387d2b7c1.tar.gz sink-b9a79ed514e7ab6bab0d6dedfcb9a78387d2b7c1.zip |
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...
-rw-r--r-- | common/facade.cpp | 1 | ||||
-rw-r--r-- | common/facade.h | 3 | ||||
-rw-r--r-- | common/queryrunner.cpp | 33 | ||||
-rw-r--r-- | 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<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> | |||
148 | { | 148 | { |
149 | //The runner lives for the lifetime of the query | 149 | //The runner lives for the lifetime of the query |
150 | auto runner = new QueryRunner<DomainType>(query, mResourceAccess, mResourceInstanceIdentifier, mDomainTypeAdaptorFactory, bufferTypeForDomainType()); | 150 | auto runner = new QueryRunner<DomainType>(query, mResourceAccess, mResourceInstanceIdentifier, mDomainTypeAdaptorFactory, bufferTypeForDomainType()); |
151 | runner->setResultTransformation(mResultTransformation); | ||
151 | return qMakePair(KAsync::null<void>(), runner->emitter()); | 152 | return qMakePair(KAsync::null<void>(), runner->emitter()); |
152 | } | 153 | } |
153 | 154 | ||
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: | |||
60 | KAsync::Job<void> create(const DomainType &domainObject) Q_DECL_OVERRIDE; | 60 | KAsync::Job<void> create(const DomainType &domainObject) Q_DECL_OVERRIDE; |
61 | KAsync::Job<void> modify(const DomainType &domainObject) Q_DECL_OVERRIDE; | 61 | KAsync::Job<void> modify(const DomainType &domainObject) Q_DECL_OVERRIDE; |
62 | KAsync::Job<void> remove(const DomainType &domainObject) Q_DECL_OVERRIDE; | 62 | KAsync::Job<void> remove(const DomainType &domainObject) Q_DECL_OVERRIDE; |
63 | QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; | 63 | virtual QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; |
64 | 64 | ||
65 | protected: | 65 | protected: |
66 | std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> mResultTransformation; | ||
66 | //TODO use one resource access instance per application & per resource | 67 | //TODO use one resource access instance per application & per resource |
67 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; | 68 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; |
68 | DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; | 69 | 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<typename DomainType> | |||
41 | class QueryWorker : public QObject | 41 | class QueryWorker : public QObject |
42 | { | 42 | { |
43 | public: | 43 | public: |
44 | QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); | 44 | QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation); |
45 | virtual ~QueryWorker(); | 45 | virtual ~QueryWorker(); |
46 | 46 | ||
47 | qint64 executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); | 47 | qint64 executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); |
48 | qint64 executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); | 48 | qint64 executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider); |
49 | 49 | ||
50 | private: | 50 | private: |
51 | static void replaySet(ResultSet &resultSet, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const QList<QByteArray> &properties); | 51 | void replaySet(ResultSet &resultSet, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const QList<QByteArray> &properties); |
52 | 52 | ||
53 | void readEntity(const Sink::Storage::NamedDatabase &db, const QByteArray &key, const std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)> &resultCallback); | 53 | void readEntity(const Sink::Storage::NamedDatabase &db, const QByteArray &key, const std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)> &resultCallback); |
54 | 54 | ||
@@ -60,6 +60,7 @@ private: | |||
60 | qint64 load(const Sink::Query &query, const std::function<ResultSet(Sink::Storage::Transaction &, QSet<QByteArray> &)> &baseSetRetriever, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, bool initialQuery); | 60 | qint64 load(const Sink::Query &query, const std::function<ResultSet(Sink::Storage::Transaction &, QSet<QByteArray> &)> &baseSetRetriever, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, bool initialQuery); |
61 | 61 | ||
62 | private: | 62 | private: |
63 | QueryRunnerBase::ResultTransformation mResultTransformation; | ||
63 | DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; | 64 | DomainTypeAdaptorFactoryInterface::Ptr mDomainTypeAdaptorFactory; |
64 | QByteArray mResourceInstanceIdentifier; | 65 | QByteArray mResourceInstanceIdentifier; |
65 | QByteArray mBufferType; | 66 | QByteArray mBufferType; |
@@ -78,8 +79,8 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
78 | mResultProvider->setFetcher([=](const typename DomainType::Ptr &parent) { | 79 | mResultProvider->setFetcher([=](const typename DomainType::Ptr &parent) { |
79 | Trace() << "Running fetcher"; | 80 | Trace() << "Running fetcher"; |
80 | auto resultProvider = mResultProvider; | 81 | auto resultProvider = mResultProvider; |
81 | async::run<qint64>([query, instanceIdentifier, factory, bufferType, parent, resultProvider]() -> qint64 { | 82 | async::run<qint64>([=]() -> qint64 { |
82 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType); | 83 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); |
83 | const qint64 newRevision = worker.executeInitialQuery(query, parent, *resultProvider); | 84 | const qint64 newRevision = worker.executeInitialQuery(query, parent, *resultProvider); |
84 | return newRevision; | 85 | return newRevision; |
85 | }) | 86 | }) |
@@ -96,8 +97,8 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
96 | //Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting | 97 | //Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting |
97 | setQuery([=] () -> KAsync::Job<void> { | 98 | setQuery([=] () -> KAsync::Job<void> { |
98 | auto resultProvider = mResultProvider; | 99 | auto resultProvider = mResultProvider; |
99 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType); | ||
100 | return async::run<qint64>([=]() -> qint64 { | 100 | return async::run<qint64>([=]() -> qint64 { |
101 | QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); | ||
101 | const qint64 newRevision = worker.executeIncrementalQuery(query, *resultProvider); | 102 | const qint64 newRevision = worker.executeIncrementalQuery(query, *resultProvider); |
102 | return newRevision; | 103 | return newRevision; |
103 | }) | 104 | }) |
@@ -121,6 +122,12 @@ QueryRunner<DomainType>::~QueryRunner() | |||
121 | } | 122 | } |
122 | 123 | ||
123 | template<class DomainType> | 124 | template<class DomainType> |
125 | void QueryRunner<DomainType>::setResultTransformation(const ResultTransformation &transformation) | ||
126 | { | ||
127 | mResultTransformation = transformation; | ||
128 | } | ||
129 | |||
130 | template<class DomainType> | ||
124 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainType>::emitter() | 131 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainType>::emitter() |
125 | { | 132 | { |
126 | return mResultProvider->emitter(); | 133 | return mResultProvider->emitter(); |
@@ -150,8 +157,9 @@ static inline ResultSet fullScan(const Sink::Storage::Transaction &transaction, | |||
150 | 157 | ||
151 | 158 | ||
152 | template<class DomainType> | 159 | template<class DomainType> |
153 | QueryWorker<DomainType>::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType) | 160 | QueryWorker<DomainType>::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType, const QueryRunnerBase::ResultTransformation &transformation) |
154 | : QObject(), | 161 | : QObject(), |
162 | mResultTransformation(transformation), | ||
155 | mDomainTypeAdaptorFactory(factory), | 163 | mDomainTypeAdaptorFactory(factory), |
156 | mResourceInstanceIdentifier(instanceIdentifier), | 164 | mResourceInstanceIdentifier(instanceIdentifier), |
157 | mBufferType(bufferType), | 165 | mBufferType(bufferType), |
@@ -170,20 +178,25 @@ template<class DomainType> | |||
170 | void QueryWorker<DomainType>::replaySet(ResultSet &resultSet, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const QList<QByteArray> &properties) | 178 | void QueryWorker<DomainType>::replaySet(ResultSet &resultSet, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const QList<QByteArray> &properties) |
171 | { | 179 | { |
172 | int counter = 0; | 180 | int counter = 0; |
173 | while (resultSet.next([&resultProvider, &counter, &properties](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &value, Sink::Operation operation) -> bool { | 181 | while (resultSet.next([this, &resultProvider, &counter, &properties](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &value, Sink::Operation operation) -> bool { |
182 | //FIXME allow maildir resource to set the mimeMessage property | ||
183 | auto valueCopy = Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(*value, properties).template staticCast<DomainType>(); | ||
184 | if (mResultTransformation) { | ||
185 | mResultTransformation(*valueCopy); | ||
186 | } | ||
174 | counter++; | 187 | counter++; |
175 | switch (operation) { | 188 | switch (operation) { |
176 | case Sink::Operation_Creation: | 189 | case Sink::Operation_Creation: |
177 | // Trace() << "Got creation"; | 190 | // Trace() << "Got creation"; |
178 | resultProvider.add(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(*value, properties).template staticCast<DomainType>()); | 191 | resultProvider.add(valueCopy); |
179 | break; | 192 | break; |
180 | case Sink::Operation_Modification: | 193 | case Sink::Operation_Modification: |
181 | // Trace() << "Got modification"; | 194 | // Trace() << "Got modification"; |
182 | resultProvider.modify(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(*value, properties).template staticCast<DomainType>()); | 195 | resultProvider.modify(valueCopy); |
183 | break; | 196 | break; |
184 | case Sink::Operation_Removal: | 197 | case Sink::Operation_Removal: |
185 | // Trace() << "Got removal"; | 198 | // Trace() << "Got removal"; |
186 | resultProvider.remove(Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(*value, properties).template staticCast<DomainType>()); | 199 | resultProvider.remove(valueCopy); |
187 | break; | 200 | break; |
188 | } | 201 | } |
189 | return true; | 202 | 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 @@ | |||
32 | class QueryRunnerBase : public QObject | 32 | class QueryRunnerBase : public QObject |
33 | { | 33 | { |
34 | Q_OBJECT | 34 | Q_OBJECT |
35 | public: | ||
36 | typedef std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> ResultTransformation; | ||
37 | |||
35 | protected: | 38 | protected: |
36 | typedef std::function<KAsync::Job<void>()> QueryFunction; | 39 | typedef std::function<KAsync::Job<void>()> QueryFunction; |
37 | 40 | ||
@@ -43,7 +46,6 @@ protected: | |||
43 | queryFunction = query; | 46 | queryFunction = query; |
44 | } | 47 | } |
45 | 48 | ||
46 | |||
47 | protected slots: | 49 | protected slots: |
48 | /** | 50 | /** |
49 | * Rerun query with new revision | 51 | * Rerun query with new revision |
@@ -82,10 +84,17 @@ public: | |||
82 | QueryRunner(const Sink::Query &query, const Sink::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); | 84 | QueryRunner(const Sink::Query &query, const Sink::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); |
83 | virtual ~QueryRunner(); | 85 | virtual ~QueryRunner(); |
84 | 86 | ||
87 | /** | ||
88 | * Allows you to run a transformation on every result. | ||
89 | * This transformation is executed in the query thread. | ||
90 | */ | ||
91 | void setResultTransformation(const ResultTransformation &transformation); | ||
92 | |||
85 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); | 93 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); |
86 | 94 | ||
87 | private: | 95 | private: |
88 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; | 96 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; |
89 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr> > mResultProvider; | 97 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr> > mResultProvider; |
98 | ResultTransformation mResultTransformation; | ||
90 | }; | 99 | }; |
91 | 100 | ||