summaryrefslogtreecommitdiffstats
path: root/common/queryrunner.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-02-05 17:14:29 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-02-05 17:14:29 +0100
commitb9a79ed514e7ab6bab0d6dedfcb9a78387d2b7c1 (patch)
treef3b51a296dd09ca0c0cd78c880c893de315a5a59 /common/queryrunner.cpp
parent36a742c33f0a3144ed8d5dbaf56d7b4ef4e4e3d3 (diff)
downloadsink-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...
Diffstat (limited to 'common/queryrunner.cpp')
-rw-r--r--common/queryrunner.cpp33
1 files changed, 23 insertions, 10 deletions
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>
41class QueryWorker : public QObject 41class QueryWorker : public QObject
42{ 42{
43public: 43public:
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
50private: 50private:
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
62private: 62private:
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
123template<class DomainType> 124template<class DomainType>
125void QueryRunner<DomainType>::setResultTransformation(const ResultTransformation &transformation)
126{
127 mResultTransformation = transformation;
128}
129
130template<class DomainType>
124typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainType>::emitter() 131typename 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
152template<class DomainType> 159template<class DomainType>
153QueryWorker<DomainType>::QueryWorker(const Sink::Query &query, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &factory, const QByteArray &bufferType) 160QueryWorker<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>
170void QueryWorker<DomainType>::replaySet(ResultSet &resultSet, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const QList<QByteArray> &properties) 178void 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;