summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/resultprovider.h19
-rw-r--r--tests/clientapitest.cpp50
2 files changed, 62 insertions, 7 deletions
diff --git a/common/resultprovider.h b/common/resultprovider.h
index 86138db..a2ed0b5 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -344,22 +344,25 @@ public:
344 auto ptr = emitter.data(); 344 auto ptr = emitter.data();
345 emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent, bool replayedAll) { 345 emitter->onInitialResultSetComplete([this, ptr](const DomainType &parent, bool replayedAll) {
346 auto hashValue = qHash(parent); 346 auto hashValue = qHash(parent);
347 if (replayedAll) {
348 mAllResultsReplayed.remove(hashValue, ptr);
349 }
347 mInitialResultSetInProgress.remove(hashValue, ptr); 350 mInitialResultSetInProgress.remove(hashValue, ptr);
348 callInitialResultCompleteIfDone(parent, replayedAll); 351 callInitialResultCompleteIfDone(parent);
349 }); 352 });
350 emitter->onComplete([this]() { this->complete(); }); 353 emitter->onComplete([this]() { this->complete(); });
351 emitter->onClear([this]() { this->clear(); }); 354 emitter->onClear([this]() { this->clear(); });
352 mEmitter << emitter; 355 mEmitter << emitter;
353 } 356 }
354 357
355 void callInitialResultCompleteIfDone(const DomainType &parent, bool replayedAll) 358 void callInitialResultCompleteIfDone(const DomainType &parent)
356 { 359 {
357 auto hashValue = qHash(parent); 360 auto hashValue = qHash(parent);
358 // Normally a parent is only in a single resource, except the toplevel (invalid) parent 361 // Normally a parent is only in a single resource, except the toplevel (invalid) parent
359 if (!mInitialResultSetInProgress.contains(hashValue) && mAllResultsFetched && !mResultEmitted) { 362 if (!mInitialResultSetInProgress.contains(hashValue) && mAllResultsFetched && !mResultEmitted) {
363 bool allResourcesReplayedAll = mAllResultsReplayed.isEmpty();
360 mResultEmitted = true; 364 mResultEmitted = true;
361 //FIXME set replayed all only to true if all had set it to true 365 this->initialResultSetComplete(parent, allResourcesReplayedAll);
362 this->initialResultSetComplete(parent, true);
363 } 366 }
364 } 367 }
365 368
@@ -370,18 +373,22 @@ public:
370 } else { 373 } else {
371 mResultEmitted = false; 374 mResultEmitted = false;
372 mAllResultsFetched = false; 375 mAllResultsFetched = false;
376 mAllResultsReplayed.clear();
377 const auto hashValue = qHash(parent);
373 for (const auto &emitter : mEmitter) { 378 for (const auto &emitter : mEmitter) {
374 mInitialResultSetInProgress.insert(qHash(parent), emitter.data()); 379 mInitialResultSetInProgress.insert(hashValue, emitter.data());
380 mAllResultsReplayed.insert(hashValue, emitter.data());
375 emitter->fetch(parent); 381 emitter->fetch(parent);
376 } 382 }
377 mAllResultsFetched = true; 383 mAllResultsFetched = true;
378 callInitialResultCompleteIfDone(parent, true); 384 callInitialResultCompleteIfDone(parent);
379 } 385 }
380 } 386 }
381 387
382private: 388private:
383 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter; 389 QList<typename ResultEmitter<DomainType>::Ptr> mEmitter;
384 QMultiMap<qint64, ResultEmitter<DomainType> *> mInitialResultSetInProgress; 390 QMultiMap<qint64, ResultEmitter<DomainType> *> mInitialResultSetInProgress;
391 QMultiMap<qint64, ResultEmitter<DomainType> *> mAllResultsReplayed;
385 bool mAllResultsFetched; 392 bool mAllResultsFetched;
386 bool mResultEmitted; 393 bool mResultEmitted;
387}; 394};
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp
index 55fdcfc..fb1bdeb 100644
--- a/tests/clientapitest.cpp
+++ b/tests/clientapitest.cpp
@@ -69,13 +69,25 @@ public:
69 SinkTraceCtx(ctx) << "Running the fetcher."; 69 SinkTraceCtx(ctx) << "Running the fetcher.";
70 } 70 }
71 SinkTraceCtx(ctx) << "-------------------------."; 71 SinkTraceCtx(ctx) << "-------------------------.";
72 for (const auto &res : results) { 72 int count = 0;
73 for (int i = offset; i < results.size(); i++) {
74 const auto res = results.at(i);
75 count++;
73 // SinkTraceCtx(ctx) << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); 76 // SinkTraceCtx(ctx) << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray();
74 auto parentProperty = res->getProperty("parent").toByteArray(); 77 auto parentProperty = res->getProperty("parent").toByteArray();
75 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty().isEmpty()) { 78 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty().isEmpty()) {
76 // SinkTraceCtx(ctx) << "Found a hit" << res->identifier(); 79 // SinkTraceCtx(ctx) << "Found a hit" << res->identifier();
77 resultProvider->add(res); 80 resultProvider->add(res);
78 } 81 }
82 if (query.limit()) {
83 if (count >= query.limit()) {
84 SinkTraceCtx(ctx) << "Aborting early after " << count << "results.";
85 offset = i + 1;
86 bool fetchedAll = (i + 1 >= results.size());
87 resultProvider->initialResultSetComplete(parent, fetchedAll);
88 return 0;
89 }
90 }
79 } 91 }
80 resultProvider->initialResultSetComplete(parent, true); 92 resultProvider->initialResultSetComplete(parent, true);
81 return 0; 93 return 0;
@@ -89,6 +101,7 @@ public:
89 QList<typename T::Ptr> results; 101 QList<typename T::Ptr> results;
90 Sink::ResultProviderInterface<typename T::Ptr> *mResultProvider; 102 Sink::ResultProviderInterface<typename T::Ptr> *mResultProvider;
91 bool runAsync = false; 103 bool runAsync = false;
104 int offset = 0;
92}; 105};
93 106
94 107
@@ -285,6 +298,41 @@ private slots:
285 QVERIFY(gotValue); 298 QVERIFY(gotValue);
286 } 299 }
287 300
301 void testMultiresourceIncrementalLoad()
302 {
303 auto facade1 = TestDummyResourceFacade<Sink::ApplicationDomain::Event>::registerFacade("dummyresource.instance1");
304 for (int i = 0; i < 4; i++) {
305 facade1->results << QSharedPointer<Sink::ApplicationDomain::Event>::create("resource1", "id" + QByteArray::number(i), 0, QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create());
306 }
307 auto facade2 = TestDummyResourceFacade<Sink::ApplicationDomain::Event>::registerFacade("dummyresource.instance2");
308 for (int i = 0; i < 6; i++) {
309 facade2->results << QSharedPointer<Sink::ApplicationDomain::Event>::create("resource2", "id" + QByteArray::number(i), 0, QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create());
310 }
311 ResourceConfig::addResource("dummyresource.instance1", "dummyresource");
312 ResourceConfig::addResource("dummyresource.instance2", "dummyresource");
313
314 Sink::Query query;
315 query.limit(2);
316
317 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
318 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
319 QCOMPARE(model->rowCount(QModelIndex()), 4);
320
321 //Try to fetch another round
322 QVERIFY(model->canFetchMore(QModelIndex()));
323 model->fetchMore(QModelIndex());
324 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
325 QCOMPARE(model->rowCount(QModelIndex()), 8);
326
327 //Try to fetch the last round
328 QVERIFY(model->canFetchMore(QModelIndex()));
329 model->fetchMore(QModelIndex());
330 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
331 QCOMPARE(model->rowCount(QModelIndex()), 10);
332
333 QVERIFY(!model->canFetchMore(QModelIndex()));
334 }
335
288 void testModelStress() 336 void testModelStress()
289 { 337 {
290 auto facade = TestDummyResourceFacade<Sink::ApplicationDomain::Folder>::registerFacade(); 338 auto facade = TestDummyResourceFacade<Sink::ApplicationDomain::Folder>::registerFacade();