diff options
-rw-r--r-- | common/modelresult.cpp | 59 | ||||
-rw-r--r-- | common/modelresult.h | 6 | ||||
-rw-r--r-- | common/notifier.cpp | 8 | ||||
-rw-r--r-- | common/queryrunner.cpp | 22 | ||||
-rw-r--r-- | common/queryrunner.h | 2 | ||||
-rw-r--r-- | common/resourcefacade.cpp | 10 | ||||
-rw-r--r-- | common/resultprovider.h | 91 | ||||
-rw-r--r-- | common/store.cpp | 12 | ||||
-rw-r--r-- | common/test.cpp | 17 | ||||
-rw-r--r-- | tests/clientapitest.cpp | 22 | ||||
-rw-r--r-- | tests/databasepopulationandfacadequerybenchmark.cpp | 4 | ||||
-rw-r--r-- | tests/mailquerybenchmark.cpp | 8 | ||||
-rw-r--r-- | tests/querytest.cpp | 7 |
13 files changed, 119 insertions, 149 deletions
diff --git a/common/modelresult.cpp b/common/modelresult.cpp index 4295a44..e11ec9c 100644 --- a/common/modelresult.cpp +++ b/common/modelresult.cpp | |||
@@ -253,14 +253,14 @@ bool ModelResult<T, Ptr>::hasChildren(const QModelIndex &parent) const | |||
253 | if (mQuery.parentProperty().isEmpty() && parent.isValid()) { | 253 | if (mQuery.parentProperty().isEmpty() && parent.isValid()) { |
254 | return false; | 254 | return false; |
255 | } | 255 | } |
256 | //Figure out whether we have children | 256 | // //Figure out whether we have children |
257 | const auto id = parent.internalId(); | 257 | // const auto id = parent.internalId(); |
258 | if (!mEntityChildrenFetched.contains(id)) { | 258 | // if (!mEntityChildrenFetched.contains(id)) { |
259 | //Since we don't retrieve that information as part of the entity, | 259 | // //Since we don't retrieve that information as part of the entity, |
260 | //we have to query for the children to see if we have some | 260 | // //we have to query for the children to see if we have some |
261 | auto p = const_cast<ModelResult<T, Ptr>*>(this); | 261 | // auto p = const_cast<ModelResult<T, Ptr>*>(this); |
262 | p->fetchMore(parent); | 262 | // p->fetchMore(parent); |
263 | } | 263 | // } |
264 | return QAbstractItemModel::hasChildren(parent); | 264 | return QAbstractItemModel::hasChildren(parent); |
265 | } | 265 | } |
266 | 266 | ||
@@ -278,7 +278,9 @@ template <class T, class Ptr> | |||
278 | void ModelResult<T, Ptr>::fetchMore(const QModelIndex &parent) | 278 | void ModelResult<T, Ptr>::fetchMore(const QModelIndex &parent) |
279 | { | 279 | { |
280 | SinkTraceCtx(mLogCtx) << "Fetching more: " << parent; | 280 | SinkTraceCtx(mLogCtx) << "Fetching more: " << parent; |
281 | fetchEntities(parent); | 281 | if (!parent.isValid()) { |
282 | fetchEntities(); | ||
283 | } | ||
282 | } | 284 | } |
283 | 285 | ||
284 | template <class T, class Ptr> | 286 | template <class T, class Ptr> |
@@ -287,10 +289,10 @@ void ModelResult<T, Ptr>::add(const Ptr &value) | |||
287 | const auto childId = qHash(*value); | 289 | const auto childId = qHash(*value); |
288 | const auto id = parentId(value); | 290 | const auto id = parentId(value); |
289 | // Ignore updates we get before the initial fetch is done | 291 | // Ignore updates we get before the initial fetch is done |
290 | if (!mEntityChildrenFetched.contains(id)) { | 292 | // if (!mEntityChildrenFetched.contains(id)) { |
291 | SinkTraceCtx(mLogCtx) << "Too early" << id; | 293 | // SinkTraceCtx(mLogCtx) << "Too early" << id; |
292 | return; | 294 | // return; |
293 | } | 295 | // } |
294 | if (mEntities.contains(childId)) { | 296 | if (mEntities.contains(childId)) { |
295 | SinkWarningCtx(mLogCtx) << "Entity already in model: " << value->identifier(); | 297 | SinkWarningCtx(mLogCtx) << "Entity already in model: " << value->identifier(); |
296 | return; | 298 | return; |
@@ -335,27 +337,27 @@ void ModelResult<T, Ptr>::remove(const Ptr &value) | |||
335 | } | 337 | } |
336 | 338 | ||
337 | template <class T, class Ptr> | 339 | template <class T, class Ptr> |
338 | void ModelResult<T, Ptr>::fetchEntities(const QModelIndex &parent) | 340 | void ModelResult<T, Ptr>::fetchEntities() |
339 | { | 341 | { |
340 | Q_ASSERT(QThread::currentThread() == this->thread()); | 342 | Q_ASSERT(QThread::currentThread() == this->thread()); |
341 | const auto id = getIdentifier(parent); | 343 | const auto id = getIdentifier({}); |
342 | //There is already a fetch in progress, don't fetch again. | 344 | //There is already a fetch in progress, don't fetch again. |
343 | if (mEntityChildrenFetched.contains(id) && !mEntityChildrenFetchComplete.contains(id)) { | 345 | if (mEntityChildrenFetched.contains(id) && !mEntityChildrenFetchComplete.contains(id)) { |
344 | SinkTraceCtx(mLogCtx) << "A fetch is already in progress: " << parent; | 346 | SinkTraceCtx(mLogCtx) << "A fetch is already in progress."; |
345 | return; | 347 | return; |
346 | } | 348 | } |
347 | mEntityChildrenFetchComplete.remove(id); | 349 | mEntityChildrenFetchComplete.remove(id); |
348 | mEntityChildrenFetched.insert(id); | 350 | mEntityChildrenFetched.insert(id); |
349 | SinkTraceCtx(mLogCtx) << "Loading child entities of parent " << id; | 351 | SinkTraceCtx(mLogCtx) << "Loading child entities of parent " << id; |
350 | if (loadEntities) { | 352 | if (loadEntities) { |
351 | loadEntities(parent.data(DomainObjectRole).template value<Ptr>()); | 353 | loadEntities(); |
352 | } else { | 354 | } else { |
353 | SinkWarningCtx(mLogCtx) << "No way to fetch entities"; | 355 | SinkWarningCtx(mLogCtx) << "No way to fetch entities"; |
354 | } | 356 | } |
355 | } | 357 | } |
356 | 358 | ||
357 | template <class T, class Ptr> | 359 | template <class T, class Ptr> |
358 | void ModelResult<T, Ptr>::setFetcher(const std::function<void(const Ptr &parent)> &fetcher) | 360 | void ModelResult<T, Ptr>::setFetcher(const std::function<void()> &fetcher) |
359 | { | 361 | { |
360 | SinkTraceCtx(mLogCtx) << "Setting fetcher"; | 362 | SinkTraceCtx(mLogCtx) << "Setting fetcher"; |
361 | loadEntities = fetcher; | 363 | loadEntities = fetcher; |
@@ -364,7 +366,7 @@ void ModelResult<T, Ptr>::setFetcher(const std::function<void(const Ptr &parent) | |||
364 | template <class T, class Ptr> | 366 | template <class T, class Ptr> |
365 | void ModelResult<T, Ptr>::setEmitter(const typename Sink::ResultEmitter<Ptr>::Ptr &emitter) | 367 | void ModelResult<T, Ptr>::setEmitter(const typename Sink::ResultEmitter<Ptr>::Ptr &emitter) |
366 | { | 368 | { |
367 | setFetcher([this](const Ptr &parent) { mEmitter->fetch(parent); }); | 369 | setFetcher([this]() { mEmitter->fetch(); }); |
368 | 370 | ||
369 | QPointer<QObject> guard(this); | 371 | QPointer<QObject> guard(this); |
370 | emitter->onAdded([this, guard](const Ptr &value) { | 372 | emitter->onAdded([this, guard](const Ptr &value) { |
@@ -389,18 +391,19 @@ void ModelResult<T, Ptr>::setEmitter(const typename Sink::ResultEmitter<Ptr>::Pt | |||
389 | remove(value); | 391 | remove(value); |
390 | }); | 392 | }); |
391 | }); | 393 | }); |
392 | emitter->onInitialResultSetComplete([this, guard](const Ptr &parent, bool fetchedAll) { | 394 | emitter->onInitialResultSetComplete([this, guard](bool fetchedAll) { |
393 | SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll; | 395 | SinkTraceCtx(mLogCtx) << "Initial result set complete. Fetched all: " << fetchedAll; |
394 | Q_ASSERT(guard); | 396 | Q_ASSERT(guard); |
395 | Q_ASSERT(QThread::currentThread() == this->thread()); | 397 | Q_ASSERT(QThread::currentThread() == this->thread()); |
396 | 398 | ||
397 | const qint64 parentId = parent ? qHash(*parent) : 0; | 399 | // const qint64 parentId = parent ? qHash(*parent) : 0; |
398 | const auto parentIndex = createIndexFromId(parentId); | 400 | // const auto parentIndex = createIndexFromId(parentId); |
399 | mEntityChildrenFetchComplete.insert(parentId); | 401 | mEntityChildrenFetchComplete.insert(0); |
400 | if (fetchedAll) { | 402 | if (fetchedAll) { |
401 | mEntityAllChildrenFetched.insert(parentId); | 403 | mEntityAllChildrenFetched.insert(0); |
402 | } | 404 | } |
403 | emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole); | 405 | // emit dataChanged(parentIndex, parentIndex, QVector<int>() << ChildrenFetchedRole); |
406 | emit dataChanged({}, {}, QVector<int>() << ChildrenFetchedRole); | ||
404 | }); | 407 | }); |
405 | mEmitter = emitter; | 408 | mEmitter = emitter; |
406 | } | 409 | } |
@@ -423,9 +426,9 @@ void ModelResult<T, Ptr>::modify(const Ptr &value) | |||
423 | } | 426 | } |
424 | auto id = parentId(value); | 427 | auto id = parentId(value); |
425 | // Ignore updates we get before the initial fetch is done | 428 | // Ignore updates we get before the initial fetch is done |
426 | if (!mEntityChildrenFetched.contains(id)) { | 429 | // if (!mEntityChildrenFetched.contains(id)) { |
427 | return; | 430 | // return; |
428 | } | 431 | // } |
429 | auto parent = createIndexFromId(id); | 432 | auto parent = createIndexFromId(id); |
430 | SinkTraceCtx(mLogCtx) << "Modified entity:" << value->identifier() << ", id: " << childId; | 433 | SinkTraceCtx(mLogCtx) << "Modified entity:" << value->identifier() << ", id: " << childId; |
431 | auto i = mTree[id].indexOf(childId); | 434 | auto i = mTree[id].indexOf(childId); |
diff --git a/common/modelresult.h b/common/modelresult.h index cc263cf..a4def81 100644 --- a/common/modelresult.h +++ b/common/modelresult.h | |||
@@ -65,7 +65,7 @@ public: | |||
65 | bool canFetchMore(const QModelIndex &parent) const; | 65 | bool canFetchMore(const QModelIndex &parent) const; |
66 | void fetchMore(const QModelIndex &parent); | 66 | void fetchMore(const QModelIndex &parent); |
67 | 67 | ||
68 | void setFetcher(const std::function<void(const Ptr &parent)> &fetcher); | 68 | void setFetcher(const std::function<void()> &fetcher); |
69 | 69 | ||
70 | private: | 70 | private: |
71 | void add(const Ptr &value); | 71 | void add(const Ptr &value); |
@@ -75,7 +75,7 @@ private: | |||
75 | 75 | ||
76 | qint64 parentId(const Ptr &value); | 76 | qint64 parentId(const Ptr &value); |
77 | QModelIndex createIndexFromId(const qint64 &id) const; | 77 | QModelIndex createIndexFromId(const qint64 &id) const; |
78 | void fetchEntities(const QModelIndex &parent); | 78 | void fetchEntities(); |
79 | 79 | ||
80 | Sink::Log::Context mLogCtx; | 80 | Sink::Log::Context mLogCtx; |
81 | // TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap<T, T> and QList<T> | 81 | // TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap<T, T> and QList<T> |
@@ -88,7 +88,7 @@ private: | |||
88 | QMap<qint64 /* entity id */, int /* Status */> mEntityStatus; | 88 | QMap<qint64 /* entity id */, int /* Status */> mEntityStatus; |
89 | QList<QByteArray> mPropertyColumns; | 89 | QList<QByteArray> mPropertyColumns; |
90 | Sink::Query mQuery; | 90 | Sink::Query mQuery; |
91 | std::function<void(const Ptr &)> loadEntities; | 91 | std::function<void()> loadEntities; |
92 | typename Sink::ResultEmitter<Ptr>::Ptr mEmitter; | 92 | typename Sink::ResultEmitter<Ptr>::Ptr mEmitter; |
93 | async::ThreadBoundary threadBoundary; | 93 | async::ThreadBoundary threadBoundary; |
94 | QScopedPointer<Sink::Notifier> mNotifier; | 94 | QScopedPointer<Sink::Notifier> mNotifier; |
diff --git a/common/notifier.cpp b/common/notifier.cpp index 9aa6c90..131fd7a 100644 --- a/common/notifier.cpp +++ b/common/notifier.cpp | |||
@@ -82,16 +82,10 @@ Notifier::Notifier(const Sink::Query &resourceQuery) : d(new Sink::Notifier::Pri | |||
82 | resourceAccess->open(); | 82 | resourceAccess->open(); |
83 | d->listenForNotifications(resourceAccess); | 83 | d->listenForNotifications(resourceAccess); |
84 | }); | 84 | }); |
85 | emitter->onModified([](const ApplicationDomain::SinkResource::Ptr &) { | ||
86 | }); | ||
87 | emitter->onRemoved([](const ApplicationDomain::SinkResource::Ptr &) { | ||
88 | }); | ||
89 | emitter->onInitialResultSetComplete([](const ApplicationDomain::SinkResource::Ptr &, bool) { | ||
90 | }); | ||
91 | emitter->onComplete([resourceCtx]() { | 85 | emitter->onComplete([resourceCtx]() { |
92 | SinkTraceCtx(resourceCtx) << "Resource query complete"; | 86 | SinkTraceCtx(resourceCtx) << "Resource query complete"; |
93 | }); | 87 | }); |
94 | emitter->fetch({}); | 88 | emitter->fetch(); |
95 | if (resourceQuery.liveQuery()) { | 89 | if (resourceQuery.liveQuery()) { |
96 | d->mResourceEmitter = emitter; | 90 | d->mResourceEmitter = emitter; |
97 | } | 91 | } |
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index f3a9af8..288ce27 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp | |||
@@ -51,7 +51,7 @@ public: | |||
51 | virtual ~QueryWorker(); | 51 | virtual ~QueryWorker(); |
52 | 52 | ||
53 | ReplayResult executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, DataStoreQuery::State::Ptr state); | 53 | ReplayResult executeIncrementalQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, DataStoreQuery::State::Ptr state); |
54 | ReplayResult executeInitialQuery(const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int batchsize, DataStoreQuery::State::Ptr state); | 54 | ReplayResult executeInitialQuery(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int batchsize, DataStoreQuery::State::Ptr state); |
55 | 55 | ||
56 | private: | 56 | private: |
57 | void resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const ResultSet::Result &result); | 57 | void resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const ResultSet::Result &result); |
@@ -70,34 +70,33 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
70 | SinkWarningCtx(mLogCtx) << "A limited query without sorting is typically a bad idea, because there is no telling what you're going to get."; | 70 | SinkWarningCtx(mLogCtx) << "A limited query without sorting is typically a bad idea, because there is no telling what you're going to get."; |
71 | } | 71 | } |
72 | auto guardPtr = QPointer<QObject>(&guard); | 72 | auto guardPtr = QPointer<QObject>(&guard); |
73 | auto fetcher = [=](const typename DomainType::Ptr &parent) { | 73 | auto fetcher = [=]() { |
74 | const QByteArray parentId = parent ? parent->identifier() : QByteArray(); | ||
75 | SinkTraceCtx(mLogCtx) << "Running fetcher. Batchsize: " << mBatchSize; | 74 | SinkTraceCtx(mLogCtx) << "Running fetcher. Batchsize: " << mBatchSize; |
76 | auto resultProvider = mResultProvider; | 75 | auto resultProvider = mResultProvider; |
77 | auto resultTransformation = mResultTransformation; | 76 | auto resultTransformation = mResultTransformation; |
78 | auto batchSize = mBatchSize; | 77 | auto batchSize = mBatchSize; |
79 | auto resourceContext = mResourceContext; | 78 | auto resourceContext = mResourceContext; |
80 | auto logCtx = mLogCtx; | 79 | auto logCtx = mLogCtx; |
81 | auto state = mQueryState.value(parentId); | 80 | auto state = mQueryState; |
82 | const bool runAsync = !query.synchronousQuery(); | 81 | const bool runAsync = !query.synchronousQuery(); |
83 | //The lambda will be executed in a separate thread, so copy all arguments | 82 | //The lambda will be executed in a separate thread, so copy all arguments |
84 | async::run<ReplayResult>([=]() { | 83 | async::run<ReplayResult>([=]() { |
85 | QueryWorker<DomainType> worker(query, resourceContext, bufferType, resultTransformation, logCtx); | 84 | QueryWorker<DomainType> worker(query, resourceContext, bufferType, resultTransformation, logCtx); |
86 | return worker.executeInitialQuery(query, parent, *resultProvider, batchSize, state); | 85 | return worker.executeInitialQuery(query, *resultProvider, batchSize, state); |
87 | }, runAsync) | 86 | }, runAsync) |
88 | .then([this, parentId, query, parent, resultProvider, guardPtr](const ReplayResult &result) { | 87 | .then([this, query, resultProvider, guardPtr](const ReplayResult &result) { |
89 | if (!guardPtr) { | 88 | if (!guardPtr) { |
90 | //Not an error, the query can vanish at any time. | 89 | //Not an error, the query can vanish at any time. |
91 | return; | 90 | return; |
92 | } | 91 | } |
93 | mInitialQueryComplete = true; | 92 | mInitialQueryComplete = true; |
94 | mQueryState[parentId] = result.queryState; | 93 | mQueryState = result.queryState; |
95 | // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise. | 94 | // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise. |
96 | if (query.liveQuery()) { | 95 | if (query.liveQuery()) { |
97 | mResourceAccess->sendRevisionReplayedCommand(result.newRevision); | 96 | mResourceAccess->sendRevisionReplayedCommand(result.newRevision); |
98 | } | 97 | } |
99 | resultProvider->setRevision(result.newRevision); | 98 | resultProvider->setRevision(result.newRevision); |
100 | resultProvider->initialResultSetComplete(parent, result.replayedAll); | 99 | resultProvider->initialResultSetComplete(result.replayedAll); |
101 | }) | 100 | }) |
102 | .exec(); | 101 | .exec(); |
103 | }; | 102 | }; |
@@ -110,14 +109,13 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou | |||
110 | Q_ASSERT(!query.synchronousQuery()); | 109 | Q_ASSERT(!query.synchronousQuery()); |
111 | // Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting | 110 | // Incremental updates are always loaded directly, leaving it up to the result to discard the changes if they are not interesting |
112 | setQuery([=]() -> KAsync::Job<void> { | 111 | setQuery([=]() -> KAsync::Job<void> { |
113 | const QByteArray parentId; | ||
114 | auto resultProvider = mResultProvider; | 112 | auto resultProvider = mResultProvider; |
115 | auto resourceContext = mResourceContext; | 113 | auto resourceContext = mResourceContext; |
116 | auto logCtx = mLogCtx; | 114 | auto logCtx = mLogCtx; |
117 | auto state = mQueryState.value(parentId); | 115 | auto state = mQueryState; |
118 | if (!mInitialQueryComplete) { | 116 | if (!mInitialQueryComplete) { |
119 | SinkWarningCtx(mLogCtx) << "Can't start the incremental query before the initial query is complete"; | 117 | SinkWarningCtx(mLogCtx) << "Can't start the incremental query before the initial query is complete"; |
120 | fetcher({}); | 118 | fetcher(); |
121 | return KAsync::null(); | 119 | return KAsync::null(); |
122 | } | 120 | } |
123 | if (mQueryInProgress) { | 121 | if (mQueryInProgress) { |
@@ -240,7 +238,7 @@ ReplayResult QueryWorker<DomainType>::executeIncrementalQuery(const Sink::Query | |||
240 | 238 | ||
241 | template <class DomainType> | 239 | template <class DomainType> |
242 | ReplayResult QueryWorker<DomainType>::executeInitialQuery( | 240 | ReplayResult QueryWorker<DomainType>::executeInitialQuery( |
243 | const Sink::Query &query, const typename DomainType::Ptr &parent, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int batchsize, DataStoreQuery::State::Ptr state) | 241 | const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, int batchsize, DataStoreQuery::State::Ptr state) |
244 | { | 242 | { |
245 | QTime time; | 243 | QTime time; |
246 | time.start(); | 244 | time.start(); |
diff --git a/common/queryrunner.h b/common/queryrunner.h index 11a302f..a567b3c 100644 --- a/common/queryrunner.h +++ b/common/queryrunner.h | |||
@@ -96,7 +96,7 @@ private: | |||
96 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; | 96 | QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; |
97 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr>> mResultProvider; | 97 | QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr>> mResultProvider; |
98 | ResultTransformation mResultTransformation; | 98 | ResultTransformation mResultTransformation; |
99 | QHash<QByteArray, DataStoreQuery::State::Ptr> mQueryState; | 99 | DataStoreQuery::State::Ptr mQueryState; |
100 | int mBatchSize; | 100 | int mBatchSize; |
101 | QObject guard; | 101 | QObject guard; |
102 | Sink::Log::Context mLogCtx; | 102 | Sink::Log::Context mLogCtx; |
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 0687bbc..3dba3e5 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp | |||
@@ -110,7 +110,7 @@ LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | QObject *guard = new QObject; | 112 | QObject *guard = new QObject; |
113 | mResultProvider->setFetcher([this, query, guard, &configNotifier, matchesTypeAndIds](const QSharedPointer<DomainType> &) { | 113 | mResultProvider->setFetcher([this, query, guard, &configNotifier, matchesTypeAndIds]() { |
114 | const auto entries = mConfigStore.getEntries(); | 114 | const auto entries = mConfigStore.getEntries(); |
115 | for (const auto &res : entries.keys()) { | 115 | for (const auto &res : entries.keys()) { |
116 | const auto type = entries.value(res); | 116 | const auto type = entries.value(res); |
@@ -127,7 +127,7 @@ LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, | |||
127 | mResultProvider->add(entity); | 127 | mResultProvider->add(entity); |
128 | } | 128 | } |
129 | // TODO initialResultSetComplete should be implicit | 129 | // TODO initialResultSetComplete should be implicit |
130 | mResultProvider->initialResultSetComplete(typename DomainType::Ptr(), true); | 130 | mResultProvider->initialResultSetComplete(true); |
131 | mResultProvider->complete(); | 131 | mResultProvider->complete(); |
132 | }); | 132 | }); |
133 | if (query.liveQuery()) { | 133 | if (query.liveQuery()) { |
@@ -390,11 +390,7 @@ QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename ApplicationDomain | |||
390 | auto resourceAccess = Sink::ResourceAccessFactory::instance().getAccess(resource->identifier(), ResourceConfig::getResourceType(resource->identifier())); | 390 | auto resourceAccess = Sink::ResourceAccessFactory::instance().getAccess(resource->identifier(), ResourceConfig::getResourceType(resource->identifier())); |
391 | monitorResource(accountIdentifier, *resource, resourceAccess); | 391 | monitorResource(accountIdentifier, *resource, resourceAccess); |
392 | }); | 392 | }); |
393 | emitter->onModified([](const ApplicationDomain::SinkResource::Ptr &) {}); | 393 | emitter->fetch(); |
394 | emitter->onRemoved([](const ApplicationDomain::SinkResource::Ptr &) {}); | ||
395 | emitter->onInitialResultSetComplete([](const ApplicationDomain::SinkResource::Ptr &, bool) {}); | ||
396 | emitter->onComplete([]() {}); | ||
397 | emitter->fetch({}); | ||
398 | runner->mResourceEmitter[accountIdentifier] = emitter; | 394 | runner->mResourceEmitter[accountIdentifier] = emitter; |
399 | } | 395 | } |
400 | 396 | ||
diff --git a/common/resultprovider.h b/common/resultprovider.h index d6feaf9..890e109 100644 --- a/common/resultprovider.h +++ b/common/resultprovider.h | |||
@@ -48,10 +48,10 @@ public: | |||
48 | virtual void add(const T &value) = 0; | 48 | virtual void add(const T &value) = 0; |
49 | virtual void modify(const T &value) = 0; | 49 | virtual void modify(const T &value) = 0; |
50 | virtual void remove(const T &value) = 0; | 50 | virtual void remove(const T &value) = 0; |
51 | virtual void initialResultSetComplete(const T &parent, bool) = 0; | 51 | virtual void initialResultSetComplete(bool) = 0; |
52 | virtual void complete() = 0; | 52 | virtual void complete() = 0; |
53 | virtual void clear() = 0; | 53 | virtual void clear() = 0; |
54 | virtual void setFetcher(const std::function<void(const T &parent)> &fetcher) = 0; | 54 | virtual void setFetcher(const std::function<void()> &fetcher) = 0; |
55 | 55 | ||
56 | void setRevision(qint64 revision) | 56 | void setRevision(qint64 revision) |
57 | { | 57 | { |
@@ -102,10 +102,10 @@ public: | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | void initialResultSetComplete(const T &parent, bool replayedAll) | 105 | void initialResultSetComplete(bool replayedAll) |
106 | { | 106 | { |
107 | if (auto strongRef = mResultEmitter.toStrongRef()) { | 107 | if (auto strongRef = mResultEmitter.toStrongRef()) { |
108 | strongRef->initialResultSetComplete(parent, replayedAll); | 108 | strongRef->initialResultSetComplete(replayedAll); |
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
@@ -134,9 +134,9 @@ public: | |||
134 | delete emitter; | 134 | delete emitter; |
135 | }); | 135 | }); |
136 | mResultEmitter = sharedPtr; | 136 | mResultEmitter = sharedPtr; |
137 | sharedPtr->setFetcher([this](const T &parent) { | 137 | sharedPtr->setFetcher([this]() { |
138 | Q_ASSERT(mFetcher); | 138 | Q_ASSERT(mFetcher); |
139 | mFetcher(parent); | 139 | mFetcher(); |
140 | }); | 140 | }); |
141 | return sharedPtr; | 141 | return sharedPtr; |
142 | } | 142 | } |
@@ -155,7 +155,7 @@ public: | |||
155 | return mResultEmitter.toStrongRef().isNull(); | 155 | return mResultEmitter.toStrongRef().isNull(); |
156 | } | 156 | } |
157 | 157 | ||
158 | void setFetcher(const std::function<void(const T &parent)> &fetcher) | 158 | void setFetcher(const std::function<void()> &fetcher) |
159 | { | 159 | { |
160 | mFetcher = fetcher; | 160 | mFetcher = fetcher; |
161 | } | 161 | } |
@@ -173,7 +173,7 @@ private: | |||
173 | 173 | ||
174 | QWeakPointer<ResultEmitter<T>> mResultEmitter; | 174 | QWeakPointer<ResultEmitter<T>> mResultEmitter; |
175 | std::function<void()> mOnDoneCallback; | 175 | std::function<void()> mOnDoneCallback; |
176 | std::function<void(const T &parent)> mFetcher; | 176 | std::function<void()> mFetcher; |
177 | }; | 177 | }; |
178 | 178 | ||
179 | /* | 179 | /* |
@@ -222,7 +222,7 @@ public: | |||
222 | removeHandler = handler; | 222 | removeHandler = handler; |
223 | } | 223 | } |
224 | 224 | ||
225 | void onInitialResultSetComplete(const std::function<void(const DomainType &, bool)> &handler) | 225 | void onInitialResultSetComplete(const std::function<void(bool)> &handler) |
226 | { | 226 | { |
227 | initialResultSetCompleteHandler = handler; | 227 | initialResultSetCompleteHandler = handler; |
228 | } | 228 | } |
@@ -246,7 +246,9 @@ public: | |||
246 | { | 246 | { |
247 | QMutexLocker locker{&mMutex}; | 247 | QMutexLocker locker{&mMutex}; |
248 | if (guardOk()) { | 248 | if (guardOk()) { |
249 | addHandler(value); | 249 | if (addHandler) { |
250 | addHandler(value); | ||
251 | } | ||
250 | } | 252 | } |
251 | } | 253 | } |
252 | 254 | ||
@@ -254,7 +256,9 @@ public: | |||
254 | { | 256 | { |
255 | QMutexLocker locker{&mMutex}; | 257 | QMutexLocker locker{&mMutex}; |
256 | if (guardOk()) { | 258 | if (guardOk()) { |
257 | modifyHandler(value); | 259 | if (modifyHandler) { |
260 | modifyHandler(value); | ||
261 | } | ||
258 | } | 262 | } |
259 | } | 263 | } |
260 | 264 | ||
@@ -262,16 +266,20 @@ public: | |||
262 | { | 266 | { |
263 | QMutexLocker locker{&mMutex}; | 267 | QMutexLocker locker{&mMutex}; |
264 | if (guardOk()) { | 268 | if (guardOk()) { |
265 | removeHandler(value); | 269 | if (removeHandler) { |
270 | removeHandler(value); | ||
271 | } | ||
266 | } | 272 | } |
267 | } | 273 | } |
268 | 274 | ||
269 | void initialResultSetComplete(const DomainType &parent, bool replayedAll) | 275 | void initialResultSetComplete(bool replayedAll) |
270 | { | 276 | { |
271 | //This callback is only ever called from the main thread, so we don't do any locking | 277 | //This callback is only ever called from the main thread, so we don't do any locking |
272 | if (initialResultSetCompleteHandler && guardOk()) { | 278 | if (initialResultSetCompleteHandler && guardOk()) { |
273 | //This can directly lead to our destruction and thus waitForMethodExecutionEnd | 279 | if (initialResultSetCompleteHandler) { |
274 | initialResultSetCompleteHandler(parent, replayedAll); | 280 | //This can directly lead to our destruction and thus waitForMethodExecutionEnd |
281 | initialResultSetCompleteHandler(replayedAll); | ||
282 | } | ||
275 | } | 283 | } |
276 | } | 284 | } |
277 | 285 | ||
@@ -279,7 +287,9 @@ public: | |||
279 | { | 287 | { |
280 | QMutexLocker locker{&mMutex}; | 288 | QMutexLocker locker{&mMutex}; |
281 | if (completeHandler && guardOk()) { | 289 | if (completeHandler && guardOk()) { |
282 | completeHandler(); | 290 | if (completeHandler) { |
291 | completeHandler(); | ||
292 | } | ||
283 | } | 293 | } |
284 | } | 294 | } |
285 | 295 | ||
@@ -287,19 +297,21 @@ public: | |||
287 | { | 297 | { |
288 | QMutexLocker locker{&mMutex}; | 298 | QMutexLocker locker{&mMutex}; |
289 | if (clearHandler && guardOk()) { | 299 | if (clearHandler && guardOk()) { |
290 | clearHandler(); | 300 | if (clearHandler) { |
301 | clearHandler(); | ||
302 | } | ||
291 | } | 303 | } |
292 | } | 304 | } |
293 | 305 | ||
294 | void setFetcher(const std::function<void(const DomainType &parent)> &fetcher) | 306 | void setFetcher(const std::function<void()> &fetcher) |
295 | { | 307 | { |
296 | mFetcher = fetcher; | 308 | mFetcher = fetcher; |
297 | } | 309 | } |
298 | 310 | ||
299 | virtual void fetch(const DomainType &parent) | 311 | virtual void fetch() |
300 | { | 312 | { |
301 | if (mFetcher) { | 313 | if (mFetcher) { |
302 | mFetcher(parent); | 314 | mFetcher(); |
303 | } | 315 | } |
304 | } | 316 | } |
305 | 317 | ||
@@ -309,11 +321,11 @@ private: | |||
309 | std::function<void(const DomainType &)> addHandler; | 321 | std::function<void(const DomainType &)> addHandler; |
310 | std::function<void(const DomainType &)> modifyHandler; | 322 | std::function<void(const DomainType &)> modifyHandler; |
311 | std::function<void(const DomainType &)> removeHandler; | 323 | std::function<void(const DomainType &)> removeHandler; |
312 | std::function<void(const DomainType &, bool)> initialResultSetCompleteHandler; | 324 | std::function<void(bool)> initialResultSetCompleteHandler; |
313 | std::function<void(void)> completeHandler; | 325 | std::function<void(void)> completeHandler; |
314 | std::function<void(void)> clearHandler; | 326 | std::function<void(void)> clearHandler; |
315 | 327 | ||
316 | std::function<void(const DomainType &parent)> mFetcher; | 328 | std::function<void()> mFetcher; |
317 | /* | 329 | /* |
318 | * This mutex is here to protect the emitter from getting destroyed while the producer-thread (ResultProvider) is calling into it, | 330 | * This mutex is here to protect the emitter from getting destroyed while the producer-thread (ResultProvider) is calling into it, |
319 | * and vice-verca, to protect the producer thread from calling into a destroyed emitter. | 331 | * and vice-verca, to protect the producer thread from calling into a destroyed emitter. |
@@ -350,53 +362,50 @@ public: | |||
350 | emitter->onModified([this](const DomainType &value) { this->modify(value); }); | 362 | emitter->onModified([this](const DomainType &value) { this->modify(value); }); |
351 | emitter->onRemoved([this](const DomainType &value) { this->remove(value); }); | 363 | emitter->onRemoved([this](const DomainType &value) { this->remove(value); }); |
352 | auto ptr = emitter.data(); | 364 | auto ptr = emitter.data(); |
353 | emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent, bool replayedAll) { | 365 | emitter->onInitialResultSetComplete([this, ptr](bool replayedAll) { |
354 | auto hashValue = qHash(parent); | ||
355 | if (replayedAll) { | 366 | if (replayedAll) { |
356 | mAllResultsReplayed.remove(hashValue, ptr); | 367 | mAllResultsReplayed.remove(ptr); |
357 | } | 368 | } |
358 | mInitialResultSetInProgress.remove(hashValue, ptr); | 369 | mInitialResultSetInProgress.remove(ptr); |
359 | callInitialResultCompleteIfDone(parent); | 370 | callInitialResultCompleteIfDone(); |
360 | }); | 371 | }); |
361 | emitter->onComplete([this]() { this->complete(); }); | 372 | emitter->onComplete([this]() { this->complete(); }); |
362 | emitter->onClear([this]() { this->clear(); }); | 373 | emitter->onClear([this]() { this->clear(); }); |
363 | mEmitter << emitter; | 374 | mEmitter << emitter; |
364 | } | 375 | } |
365 | 376 | ||
366 | void callInitialResultCompleteIfDone(const DomainType &parent) | 377 | void callInitialResultCompleteIfDone() |
367 | { | 378 | { |
368 | auto hashValue = qHash(parent); | ||
369 | // Normally a parent is only in a single resource, except the toplevel (invalid) parent | 379 | // Normally a parent is only in a single resource, except the toplevel (invalid) parent |
370 | if (!mInitialResultSetInProgress.contains(hashValue) && mAllResultsFetched && !mResultEmitted) { | 380 | if (mInitialResultSetInProgress.isEmpty() && mAllResultsFetched && !mResultEmitted) { |
371 | bool allResourcesReplayedAll = mAllResultsReplayed.isEmpty(); | ||
372 | mResultEmitted = true; | 381 | mResultEmitted = true; |
373 | this->initialResultSetComplete(parent, allResourcesReplayedAll); | 382 | this->initialResultSetComplete(mAllResultsReplayed.isEmpty()); |
374 | } | 383 | } |
375 | } | 384 | } |
376 | 385 | ||
377 | void fetch(const DomainType &parent) Q_DECL_OVERRIDE | 386 | void fetch() Q_DECL_OVERRIDE |
378 | { | 387 | { |
379 | if (mEmitter.isEmpty()) { | 388 | if (mEmitter.isEmpty()) { |
380 | this->initialResultSetComplete(parent, true); | 389 | this->initialResultSetComplete(true); |
381 | } else { | 390 | } else { |
382 | mResultEmitted = false; | 391 | mResultEmitted = false; |
383 | mAllResultsFetched = false; | 392 | mAllResultsFetched = false; |
393 | mInitialResultSetInProgress.clear(); | ||
384 | mAllResultsReplayed.clear(); | 394 | mAllResultsReplayed.clear(); |
385 | const auto hashValue = qHash(parent); | ||
386 | for (const auto &emitter : mEmitter) { | 395 | for (const auto &emitter : mEmitter) { |
387 | mInitialResultSetInProgress.insert(hashValue, emitter.data()); | 396 | mInitialResultSetInProgress.insert(emitter.data()); |
388 | mAllResultsReplayed.insert(hashValue, emitter.data()); | 397 | mAllResultsReplayed.insert(emitter.data()); |
389 | emitter->fetch(parent); | 398 | emitter->fetch(); |
390 | } | 399 | } |
391 | mAllResultsFetched = true; | 400 | mAllResultsFetched = true; |
392 | callInitialResultCompleteIfDone(parent); | 401 | callInitialResultCompleteIfDone(); |
393 | } | 402 | } |
394 | } | 403 | } |
395 | 404 | ||
396 | private: | 405 | private: |
397 | QList<typename ResultEmitter<DomainType>::Ptr> mEmitter; | 406 | QList<typename ResultEmitter<DomainType>::Ptr> mEmitter; |
398 | QMultiMap<qint64, ResultEmitter<DomainType> *> mInitialResultSetInProgress; | 407 | QSet<ResultEmitter<DomainType>*> mInitialResultSetInProgress; |
399 | QMultiMap<qint64, ResultEmitter<DomainType> *> mAllResultsReplayed; | 408 | QSet<ResultEmitter<DomainType>*> mAllResultsReplayed; |
400 | bool mAllResultsFetched; | 409 | bool mAllResultsFetched; |
401 | bool mResultEmitted; | 410 | bool mResultEmitted; |
402 | }; | 411 | }; |
diff --git a/common/store.cpp b/common/store.cpp index 1701a43..b16fa4e 100644 --- a/common/store.cpp +++ b/common/store.cpp | |||
@@ -136,12 +136,6 @@ QPair<typename AggregatingResultEmitter<typename DomainType::Ptr>::Ptr, typenam | |||
136 | Q_ASSERT(!resourceType.isEmpty()); | 136 | Q_ASSERT(!resourceType.isEmpty()); |
137 | queryResource<DomainType>(resourceType, resource->identifier(), query, aggregatingEmitter, ctx).exec(); | 137 | queryResource<DomainType>(resourceType, resource->identifier(), query, aggregatingEmitter, ctx).exec(); |
138 | }); | 138 | }); |
139 | emitter->onModified([](const ApplicationDomain::SinkResource::Ptr &) { | ||
140 | }); | ||
141 | emitter->onRemoved([](const ApplicationDomain::SinkResource::Ptr &) { | ||
142 | }); | ||
143 | emitter->onInitialResultSetComplete([](const ApplicationDomain::SinkResource::Ptr &, bool) { | ||
144 | }); | ||
145 | emitter->onComplete([query, aggregatingEmitter, resourceCtx]() { | 139 | emitter->onComplete([query, aggregatingEmitter, resourceCtx]() { |
146 | SinkTraceCtx(resourceCtx) << "Resource query complete"; | 140 | SinkTraceCtx(resourceCtx) << "Resource query complete"; |
147 | }); | 141 | }); |
@@ -178,7 +172,7 @@ QSharedPointer<QAbstractItemModel> Store::loadModel(const Query &query) | |||
178 | //Keep the emitter alive | 172 | //Keep the emitter alive |
179 | if (auto resourceEmitter = result.second) { | 173 | if (auto resourceEmitter = result.second) { |
180 | model->setProperty("resourceEmitter", QVariant::fromValue(resourceEmitter)); //TODO only neceesary for live queries | 174 | model->setProperty("resourceEmitter", QVariant::fromValue(resourceEmitter)); //TODO only neceesary for live queries |
181 | resourceEmitter->fetch(ApplicationDomain::SinkResource::Ptr()); | 175 | resourceEmitter->fetch(); |
182 | } | 176 | } |
183 | 177 | ||
184 | 178 | ||
@@ -443,10 +437,10 @@ QList<DomainType> Store::read(const Sink::Query &query_) | |||
443 | }); | 437 | }); |
444 | 438 | ||
445 | if (auto resourceEmitter = result.second) { | 439 | if (auto resourceEmitter = result.second) { |
446 | resourceEmitter->fetch(ApplicationDomain::SinkResource::Ptr()); | 440 | resourceEmitter->fetch(); |
447 | } | 441 | } |
448 | 442 | ||
449 | aggregatingEmitter->fetch(typename DomainType::Ptr()); | 443 | aggregatingEmitter->fetch(); |
450 | return list; | 444 | return list; |
451 | } | 445 | } |
452 | 446 | ||
diff --git a/common/test.cpp b/common/test.cpp index 237d3bb..52d79ca 100644 --- a/common/test.cpp +++ b/common/test.cpp | |||
@@ -150,22 +150,13 @@ public: | |||
150 | // We have to do it this way, otherwise we're not setting the fetcher right | 150 | // We have to do it this way, otherwise we're not setting the fetcher right |
151 | auto emitter = resultProvider->emitter(); | 151 | auto emitter = resultProvider->emitter(); |
152 | 152 | ||
153 | resultProvider->setFetcher([query, resultProvider, this](const typename T::Ptr &parent) { | 153 | resultProvider->setFetcher([query, resultProvider, this]() { |
154 | if (parent) { | 154 | SinkTrace() << "Running the fetcher."; |
155 | SinkTrace() << "Running the fetcher " << parent->identifier(); | ||
156 | } else { | ||
157 | SinkTrace() << "Running the fetcher."; | ||
158 | } | ||
159 | SinkTrace() << "-------------------------."; | 155 | SinkTrace() << "-------------------------."; |
160 | for (const auto &res : mTestAccount->entities<T>()) { | 156 | for (const auto &res : mTestAccount->entities<T>()) { |
161 | qDebug() << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); | 157 | resultProvider->add(res.template staticCast<T>()); |
162 | auto parentProperty = res->getProperty("parent").toByteArray(); | ||
163 | if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty().isEmpty()) { | ||
164 | qDebug() << "Found a match" << res->identifier(); | ||
165 | resultProvider->add(res.template staticCast<T>()); | ||
166 | } | ||
167 | } | 158 | } |
168 | resultProvider->initialResultSetComplete(parent, true); | 159 | resultProvider->initialResultSetComplete(true); |
169 | }); | 160 | }); |
170 | auto job = KAsync::start([query, resultProvider]() {}); | 161 | auto job = KAsync::start([query, resultProvider]() {}); |
171 | return qMakePair(job, emitter); | 162 | return qMakePair(job, emitter); |
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp index 7e348c2..94818e1 100644 --- a/tests/clientapitest.cpp +++ b/tests/clientapitest.cpp | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | template <typename T> | 14 | template <typename T> |
15 | struct Result { | 15 | struct Result { |
16 | QSharedPointer<T> parent; | ||
17 | bool fetchedAll; | 16 | bool fetchedAll; |
18 | }; | 17 | }; |
19 | 18 | ||
@@ -73,37 +72,28 @@ public: | |||
73 | // We have to do it this way, otherwise we're not setting the fetcher right | 72 | // We have to do it this way, otherwise we're not setting the fetcher right |
74 | auto emitter = resultProvider->emitter(); | 73 | auto emitter = resultProvider->emitter(); |
75 | 74 | ||
76 | resultProvider->setFetcher([query, resultProvider, this, ctx](const typename T::Ptr &parent) { | 75 | resultProvider->setFetcher([query, resultProvider, this, ctx]() { |
77 | async::run<Result<T>>([=] { | 76 | async::run<Result<T>>([=] { |
78 | if (parent) { | 77 | SinkTraceCtx(ctx) << "Running the fetcher."; |
79 | SinkTraceCtx(ctx) << "Running the fetcher " << parent->identifier(); | ||
80 | } else { | ||
81 | SinkTraceCtx(ctx) << "Running the fetcher."; | ||
82 | } | ||
83 | SinkTraceCtx(ctx) << "-------------------------."; | 78 | SinkTraceCtx(ctx) << "-------------------------."; |
84 | int count = 0; | 79 | int count = 0; |
85 | for (int i = offset; i < results.size(); i++) { | 80 | for (int i = offset; i < results.size(); i++) { |
86 | const auto res = results.at(i); | 81 | const auto res = results.at(i); |
87 | count++; | 82 | count++; |
88 | // SinkTraceCtx(ctx) << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); | 83 | resultProvider->add(res); |
89 | auto parentProperty = res->getProperty("parent").toByteArray(); | ||
90 | if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty().isEmpty()) { | ||
91 | // SinkTraceCtx(ctx) << "Found a hit" << res->identifier(); | ||
92 | resultProvider->add(res); | ||
93 | } | ||
94 | if (query.limit()) { | 84 | if (query.limit()) { |
95 | if (count >= query.limit()) { | 85 | if (count >= query.limit()) { |
96 | SinkTraceCtx(ctx) << "Aborting early after " << count << "results."; | 86 | SinkTraceCtx(ctx) << "Aborting early after " << count << "results."; |
97 | offset = i + 1; | 87 | offset = i + 1; |
98 | bool fetchedAll = (i + 1 >= results.size()); | 88 | bool fetchedAll = (i + 1 >= results.size()); |
99 | return Result<T>{parent, fetchedAll}; | 89 | return Result<T>{fetchedAll}; |
100 | } | 90 | } |
101 | } | 91 | } |
102 | } | 92 | } |
103 | return Result<T>{parent, true}; | 93 | return Result<T>{true}; |
104 | }, runAsync) | 94 | }, runAsync) |
105 | .then([=] (const Result<T> &r) { | 95 | .then([=] (const Result<T> &r) { |
106 | resultProvider->initialResultSetComplete(r.parent, r.fetchedAll); | 96 | resultProvider->initialResultSetComplete(r.fetchedAll); |
107 | }) | 97 | }) |
108 | .exec(); | 98 | .exec(); |
109 | }); | 99 | }); |
diff --git a/tests/databasepopulationandfacadequerybenchmark.cpp b/tests/databasepopulationandfacadequerybenchmark.cpp index 4f81d1d..7f478cf 100644 --- a/tests/databasepopulationandfacadequerybenchmark.cpp +++ b/tests/databasepopulationandfacadequerybenchmark.cpp | |||
@@ -113,8 +113,8 @@ class DatabasePopulationAndFacadeQueryBenchmark : public QObject | |||
113 | QList<Sink::ApplicationDomain::Event::Ptr> list; | 113 | QList<Sink::ApplicationDomain::Event::Ptr> list; |
114 | emitter->onAdded([&list](const Sink::ApplicationDomain::Event::Ptr &event) { list << event; }); | 114 | emitter->onAdded([&list](const Sink::ApplicationDomain::Event::Ptr &event) { list << event; }); |
115 | bool done = false; | 115 | bool done = false; |
116 | emitter->onInitialResultSetComplete([&done](const Sink::ApplicationDomain::Event::Ptr &event, bool) { done = true; }); | 116 | emitter->onInitialResultSetComplete([&done](bool) { done = true; }); |
117 | emitter->fetch(Sink::ApplicationDomain::Event::Ptr()); | 117 | emitter->fetch(); |
118 | QUICK_TRY_VERIFY(done); | 118 | QUICK_TRY_VERIFY(done); |
119 | QCOMPARE(list.size(), count); | 119 | QCOMPARE(list.size(), count); |
120 | 120 | ||
diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp index 1d295b5..3eccfc3 100644 --- a/tests/mailquerybenchmark.cpp +++ b/tests/mailquerybenchmark.cpp | |||
@@ -96,8 +96,8 @@ class MailQueryBenchmark : public QObject | |||
96 | int i = 0; | 96 | int i = 0; |
97 | emitter->onAdded([&](const Mail::Ptr &) { i++; }); | 97 | emitter->onAdded([&](const Mail::Ptr &) { i++; }); |
98 | bool done = false; | 98 | bool done = false; |
99 | emitter->onInitialResultSetComplete([&done](const Mail::Ptr &mail, bool) { done = true; }); | 99 | emitter->onInitialResultSetComplete([&done](bool) { done = true; }); |
100 | emitter->fetch(Mail::Ptr()); | 100 | emitter->fetch(); |
101 | QUICK_TRY_VERIFY(done); | 101 | QUICK_TRY_VERIFY(done); |
102 | return i; | 102 | return i; |
103 | } | 103 | } |
@@ -273,8 +273,8 @@ private slots: | |||
273 | emitter->onRemoved([&](const Mail::Ptr &mail) { removed << mail; /*qWarning() << "Removed";*/ }); | 273 | emitter->onRemoved([&](const Mail::Ptr &mail) { removed << mail; /*qWarning() << "Removed";*/ }); |
274 | emitter->onModified([&](const Mail::Ptr &mail) { modified << mail; /*qWarning() << "Modified";*/ }); | 274 | emitter->onModified([&](const Mail::Ptr &mail) { modified << mail; /*qWarning() << "Modified";*/ }); |
275 | bool done = false; | 275 | bool done = false; |
276 | emitter->onInitialResultSetComplete([&done](const Mail::Ptr &mail, bool) { done = true; }); | 276 | emitter->onInitialResultSetComplete([&done](bool) { done = true; }); |
277 | emitter->fetch(Mail::Ptr()); | 277 | emitter->fetch(); |
278 | QUICK_TRY_VERIFY(done); | 278 | QUICK_TRY_VERIFY(done); |
279 | QCOMPARE(added.size(), expectedSize); | 279 | QCOMPARE(added.size(), expectedSize); |
280 | 280 | ||
diff --git a/tests/querytest.cpp b/tests/querytest.cpp index 6279fa9..5af8a99 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp | |||
@@ -245,8 +245,6 @@ private slots: | |||
245 | auto model = Sink::Store::loadModel<Folder>(query); | 245 | auto model = Sink::Store::loadModel<Folder>(query); |
246 | QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); | 246 | QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); |
247 | QCOMPARE(model->rowCount(), 1); | 247 | QCOMPARE(model->rowCount(), 1); |
248 | model->fetchMore(model->index(0, 0)); | ||
249 | QTRY_VERIFY(model->data(model->index(0, 0), Sink::Store::ChildrenFetchedRole).toBool()); | ||
250 | QCOMPARE(model->rowCount(model->index(0, 0)), 1); | 248 | QCOMPARE(model->rowCount(model->index(0, 0)), 1); |
251 | } | 249 | } |
252 | 250 | ||
@@ -266,7 +264,6 @@ private slots: | |||
266 | auto model = Sink::Store::loadModel<Folder>(query); | 264 | auto model = Sink::Store::loadModel<Folder>(query); |
267 | QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); | 265 | QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); |
268 | QCOMPARE(model->rowCount(), 1); | 266 | QCOMPARE(model->rowCount(), 1); |
269 | model->fetchMore(model->index(0, 0)); | ||
270 | 267 | ||
271 | auto subfolder = ApplicationDomainType::createEntity<Folder>("sink.dummy.instance1"); | 268 | auto subfolder = ApplicationDomainType::createEntity<Folder>("sink.dummy.instance1"); |
272 | subfolder.setParent(folder.identifier()); | 269 | subfolder.setParent(folder.identifier()); |
@@ -274,9 +271,7 @@ private slots: | |||
274 | VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1")); | 271 | VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1")); |
275 | 272 | ||
276 | //Ensure the folder appears | 273 | //Ensure the folder appears |
277 | model->fetchMore(model->index(0, 0)); | 274 | QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); |
278 | QTRY_VERIFY(model->data(model->index(0, 0), Sink::Store::ChildrenFetchedRole).toBool()); | ||
279 | QCOMPARE(model->rowCount(model->index(0, 0)), 1); | ||
280 | 275 | ||
281 | //...and dissapears again after removal | 276 | //...and dissapears again after removal |
282 | VERIFYEXEC(Sink::Store::remove<Folder>(subfolder)); | 277 | VERIFYEXEC(Sink::Store::remove<Folder>(subfolder)); |