From fd9703a6f990d965d1c7fba21fee36b2beef644e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 14 Jan 2016 18:22:36 +0100 Subject: An imperative query API --- common/clientapi.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'common/clientapi.cpp') 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 Store::synchronize(const Akonadi2::Query &query) .template then([](){}); } +template +KAsync::Job Store::fetchOne(const Akonadi2::Query &query) +{ + return KAsync::start([query](KAsync::Future &future) { + //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) + fetch(query, 1) + .template then >([&future](const QList &list){ + future.setValue(*list.first()); + future.setFinished(); + }, [&future](int errorCode, const QString &errorMessage) { + future.setError(errorCode, errorMessage); + future.setFinished(); + }).exec(); + }); +} + +template +KAsync::Job > Store::fetchAll(const Akonadi2::Query &query) +{ + return fetch(query); +} + +template +KAsync::Job > Store::fetch(const Akonadi2::Query &query, int minimumAmount) +{ + auto model = loadModel(query); + auto list = QSharedPointer >::create(); + auto context = QSharedPointer::create(); + return KAsync::start >([model, list, context, minimumAmount](KAsync::Future > &future) { + if (model->rowCount() >= 1) { + for (int i = 0; i < model->rowCount(); i++) { + list->append(model->index(i, 0, QModelIndex()).data(Akonadi2::Store::DomainObjectRole).template value()); + } + } else { + QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, context.data(), [model, &future, list](const QModelIndex &index, int start, int end) { + for (int i = start; i <= end; i++) { + list->append(model->index(i, 0, QModelIndex()).data(Akonadi2::Store::DomainObjectRole).template value()); + } + }); + QObject::connect(model.data(), &QAbstractItemModel::dataChanged, context.data(), [model, &future, list, minimumAmount](const QModelIndex &, const QModelIndex &, const QVector &roles) { + if (roles.contains(ModelResult::ChildrenFetchedRole)) { + if (list->size() < minimumAmount) { + future.setError(1, "Not enough values."); + } else { + future.setValue(*list); + } + future.setFinished(); + } + }); + } + if (model->data(QModelIndex(), ModelResult::ChildrenFetchedRole).toBool()) { + if (list->size() < minimumAmount) { + future.setError(1, "Not enough values."); + } else { + future.setValue(*list); + } + future.setFinished(); + } + }); +} + #define REGISTER_TYPE(T) template KAsync::Job Store::remove(const T &domainObject); \ template KAsync::Job Store::create(const T &domainObject); \ template KAsync::Job Store::modify(const T &domainObject); \ template QSharedPointer Store::loadModel(Query query); \ + template KAsync::Job Store::fetchOne(const Query &); \ + template KAsync::Job > Store::fetchAll(const Query &); \ + template KAsync::Job > Store::fetch(const Query &, int); \ REGISTER_TYPE(ApplicationDomain::Event); REGISTER_TYPE(ApplicationDomain::Mail); -- cgit v1.2.3