summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/clientapi.cpp64
-rw-r--r--common/clientapi.h9
-rw-r--r--tests/clientapitest.cpp20
3 files changed, 93 insertions, 0 deletions
diff --git a/common/clientapi.cpp b/common/clientapi.cpp
index e7ca99d..2c25220 100644
--- a/common/clientapi.cpp
+++ b/common/clientapi.cpp
@@ -212,10 +212,74 @@ KAsync::Job<void> Store::synchronize(const Akonadi2::Query &query)
212 .template then<void>([](){}); 212 .template then<void>([](){});
213} 213}
214 214
215template <class DomainType>
216KAsync::Job<DomainType> Store::fetchOne(const Akonadi2::Query &query)
217{
218 return KAsync::start<DomainType>([query](KAsync::Future<DomainType> &future) {
219 //FIXME We could do this more elegantly if composed jobs would have the correct type (In that case we'd simply return the value from then continuation, and could avoid the outer job entirely)
220 fetch<DomainType>(query, 1)
221 .template then<void, QList<typename DomainType::Ptr> >([&future](const QList<typename DomainType::Ptr> &list){
222 future.setValue(*list.first());
223 future.setFinished();
224 }, [&future](int errorCode, const QString &errorMessage) {
225 future.setError(errorCode, errorMessage);
226 future.setFinished();
227 }).exec();
228 });
229}
230
231template <class DomainType>
232KAsync::Job<QList<typename DomainType::Ptr> > Store::fetchAll(const Akonadi2::Query &query)
233{
234 return fetch<DomainType>(query);
235}
236
237template <class DomainType>
238KAsync::Job<QList<typename DomainType::Ptr> > Store::fetch(const Akonadi2::Query &query, int minimumAmount)
239{
240 auto model = loadModel<DomainType>(query);
241 auto list = QSharedPointer<QList<typename DomainType::Ptr> >::create();
242 auto context = QSharedPointer<QObject>::create();
243 return KAsync::start<QList<typename DomainType::Ptr> >([model, list, context, minimumAmount](KAsync::Future<QList<typename DomainType::Ptr> > &future) {
244 if (model->rowCount() >= 1) {
245 for (int i = 0; i < model->rowCount(); i++) {
246 list->append(model->index(i, 0, QModelIndex()).data(Akonadi2::Store::DomainObjectRole).template value<typename DomainType::Ptr>());
247 }
248 } else {
249 QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, context.data(), [model, &future, list](const QModelIndex &index, int start, int end) {
250 for (int i = start; i <= end; i++) {
251 list->append(model->index(i, 0, QModelIndex()).data(Akonadi2::Store::DomainObjectRole).template value<typename DomainType::Ptr>());
252 }
253 });
254 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, context.data(), [model, &future, list, minimumAmount](const QModelIndex &, const QModelIndex &, const QVector<int> &roles) {
255 if (roles.contains(ModelResult<DomainType, typename DomainType::Ptr>::ChildrenFetchedRole)) {
256 if (list->size() < minimumAmount) {
257 future.setError(1, "Not enough values.");
258 } else {
259 future.setValue(*list);
260 }
261 future.setFinished();
262 }
263 });
264 }
265 if (model->data(QModelIndex(), ModelResult<DomainType, typename DomainType::Ptr>::ChildrenFetchedRole).toBool()) {
266 if (list->size() < minimumAmount) {
267 future.setError(1, "Not enough values.");
268 } else {
269 future.setValue(*list);
270 }
271 future.setFinished();
272 }
273 });
274}
275
215#define REGISTER_TYPE(T) template KAsync::Job<void> Store::remove<T>(const T &domainObject); \ 276#define REGISTER_TYPE(T) template KAsync::Job<void> Store::remove<T>(const T &domainObject); \
216 template KAsync::Job<void> Store::create<T>(const T &domainObject); \ 277 template KAsync::Job<void> Store::create<T>(const T &domainObject); \
217 template KAsync::Job<void> Store::modify<T>(const T &domainObject); \ 278 template KAsync::Job<void> Store::modify<T>(const T &domainObject); \
218 template QSharedPointer<QAbstractItemModel> Store::loadModel<T>(Query query); \ 279 template QSharedPointer<QAbstractItemModel> Store::loadModel<T>(Query query); \
280 template KAsync::Job<T> Store::fetchOne<T>(const Query &); \
281 template KAsync::Job<QList<T::Ptr> > Store::fetchAll<T>(const Query &); \
282 template KAsync::Job<QList<T::Ptr> > Store::fetch<T>(const Query &, int); \
219 283
220REGISTER_TYPE(ApplicationDomain::Event); 284REGISTER_TYPE(ApplicationDomain::Event);
221REGISTER_TYPE(ApplicationDomain::Mail); 285REGISTER_TYPE(ApplicationDomain::Mail);
diff --git a/common/clientapi.h b/common/clientapi.h
index 4e55432..f1c3bc6 100644
--- a/common/clientapi.h
+++ b/common/clientapi.h
@@ -95,6 +95,15 @@ public:
95 * Removes a resource from disk. 95 * Removes a resource from disk.
96 */ 96 */
97 static void removeFromDisk(const QByteArray &resourceIdentifier); 97 static void removeFromDisk(const QByteArray &resourceIdentifier);
98
99 template <class DomainType>
100 static KAsync::Job<DomainType> fetchOne(const Akonadi2::Query &query);
101
102 template <class DomainType>
103 static KAsync::Job<QList<typename DomainType::Ptr> > fetchAll(const Akonadi2::Query &query);
104
105 template <class DomainType>
106 static KAsync::Job<QList<typename DomainType::Ptr> > fetch(const Akonadi2::Query &query, int minimumAmount = 0);
98}; 107};
99 108
100 109
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp
index ff79c82..5942849 100644
--- a/tests/clientapitest.cpp
+++ b/tests/clientapitest.cpp
@@ -279,6 +279,26 @@ private Q_SLOTS:
279 QCOMPARE(childrenFetchedCount, 1); 279 QCOMPARE(childrenFetchedCount, 1);
280 } 280 }
281 281
282 void testImperativeLoad()
283 {
284 auto facade = DummyResourceFacade<Akonadi2::ApplicationDomain::Event>::registerFacade();
285 facade->results << QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("resource", "id", 0, QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create());
286 ResourceConfig::addResource("dummyresource.instance1", "dummyresource");
287
288 Akonadi2::Query query;
289 query.resources << "dummyresource.instance1";
290 query.liveQuery = false;
291
292 bool gotValue = false;
293 auto result = Akonadi2::Store::fetchOne<Akonadi2::ApplicationDomain::Event>(query)
294 .then<void, Akonadi2::ApplicationDomain::Event>([&gotValue](const Akonadi2::ApplicationDomain::Event &event) {
295 gotValue = true;
296 }).exec();
297 result.waitForFinished();
298 QVERIFY(!result.errorCode());
299 QVERIFY(gotValue);
300 }
301
282 302
283}; 303};
284 304