summaryrefslogtreecommitdiffstats
path: root/dummyresource/facade.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-13 20:15:14 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-15 09:30:32 +0200
commitc55054e899660f2d667af2c2e573a1267d47358e (patch)
tree0f547effcad0c20521f0bc047a9eb1d4130b052b /dummyresource/facade.cpp
parent4652a39fc6869fc5af46367c35027b2b53478268 (diff)
downloadsink-c55054e899660f2d667af2c2e573a1267d47358e.tar.gz
sink-c55054e899660f2d667af2c2e573a1267d47358e.zip
Use a queryrunner to execute queries.
The queryrunner is responsible for running queries and keeping them up to date. This is required for self-updating queries. To get this to work properly the ResultProvider/emitter had to be fixed. The emitter now only lives as long as the client holds a reference to it, allowing the provider to detect when it is no longer necessary to keep the query alive (because noone is listening). In the process various lifetime issues have been fixed, that we're caused by lambdas capturing smartpointers, that then extended the lifetime of the associated objects unpredictably.
Diffstat (limited to 'dummyresource/facade.cpp')
-rw-r--r--dummyresource/facade.cpp44
1 files changed, 41 insertions, 3 deletions
diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp
index 1477fcf..f603c56 100644
--- a/dummyresource/facade.cpp
+++ b/dummyresource/facade.cpp
@@ -147,15 +147,51 @@ void DummyResourceFacade::readValue(QSharedPointer<Akonadi2::Storage> storage, c
147 }); 147 });
148} 148}
149 149
150Async::Job<void> DummyResourceFacade::load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback) 150Async::Job<void> DummyResourceFacade::load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr> > &resultProvider)
151{ 151{
152 return synchronizeResource(query.syncOnDemand, query.processAll).then<void>([=](Async::Future<void> &future) { 152 auto runner = QSharedPointer<QueryRunner>::create(query);
153 //The runner only lives as long as the resultProvider
154 resultProvider->setQueryRunner(runner);
155 runner->setQuery([this, resultProvider, query](qint64 oldRevision, qint64 newRevision) -> Async::Job<qint64> {
156 return Async::start<qint64>([this, resultProvider, query](Async::Future<qint64> &future) {
157 //TODO only emit changes and don't replace everything
158 resultProvider->clear();
159 //rerun query
160 std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> addCallback = std::bind(&Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr>::add, resultProvider, std::placeholders::_1);
161 load(query, addCallback).then<void, qint64>([resultProvider, &future](qint64 queriedRevision) {
162 //TODO set revision in result provider?
163 //TODO update all existing results with new revision
164 resultProvider->complete();
165 future.setValue(queriedRevision);
166 future.setFinished();
167 }).exec();
168 });
169 });
170
171 auto resourceAccess = mResourceAccess;
172 //TODO we need to somehow disconnect this
173 QObject::connect(resourceAccess.data(), &Akonadi2::ResourceAccess::revisionChanged, [runner](qint64 newRevision) {
174 runner->revisionChanged(newRevision);
175 });
176
177 return Async::start<void>([runner](Async::Future<void> &future) {
178 runner->run().then<void>([&future]() {
179 //TODO if not live query, destroy runner.
180 future.setFinished();
181 }).exec();
182 });
183}
184
185Async::Job<qint64> DummyResourceFacade::load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback)
186{
187 return synchronizeResource(query.syncOnDemand, query.processAll).then<qint64>([=](Async::Future<qint64> &future) {
153 //Now that the sync is complete we can execute the query 188 //Now that the sync is complete we can execute the query
154 const auto preparedQuery = prepareQuery(query); 189 const auto preparedQuery = prepareQuery(query);
155 190
156 auto storage = QSharedPointer<Akonadi2::Storage>::create(Akonadi2::Store::storageLocation(), "org.kde.dummy"); 191 auto storage = QSharedPointer<Akonadi2::Storage>::create(Akonadi2::Store::storageLocation(), "org.kde.dummy");
157 192
158 //TODO use transaction over full query and record store revision. We'll need it to update the query. 193 storage->startTransaction(Akonadi2::Storage::ReadOnly);
194 const qint64 revision = storage->maxRevision();
159 195
160 //Index lookups 196 //Index lookups
161 QVector<QByteArray> keys; 197 QVector<QByteArray> keys;
@@ -177,6 +213,8 @@ Async::Job<void> DummyResourceFacade::load(const Akonadi2::Query &query, const s
177 readValue(storage, key, resultCallback, preparedQuery); 213 readValue(storage, key, resultCallback, preparedQuery);
178 } 214 }
179 } 215 }
216 storage->abortTransaction();
217 future.setValue(revision);
180 future.setFinished(); 218 future.setFinished();
181 }); 219 });
182} 220}