summaryrefslogtreecommitdiffstats
path: root/common
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
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')
-rw-r--r--common/facade.cpp1
-rw-r--r--common/facade.h3
-rw-r--r--common/queryrunner.cpp33
-rw-r--r--common/queryrunner.h11
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
65protected: 65protected:
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>
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;
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 @@
32class QueryRunnerBase : public QObject 32class QueryRunnerBase : public QObject
33{ 33{
34 Q_OBJECT 34 Q_OBJECT
35public:
36 typedef std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> ResultTransformation;
37
35protected: 38protected:
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
47protected slots: 49protected 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
87private: 95private:
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