summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-17 15:16:29 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-17 15:16:29 +0200
commit93c9ebb5d0654626cb8bf2e6b00a5845b210f82c (patch)
treed333bf90e2a2e25c43b1bc6f514a8df5efa6c38f
parent493aae46b3aeffcdb001f697efdc5a42eba672d8 (diff)
downloadsink-93c9ebb5d0654626cb8bf2e6b00a5845b210f82c.tar.gz
sink-93c9ebb5d0654626cb8bf2e6b00a5845b210f82c.zip
Fixed a readEntity call with empty uid
Filtered entites are still passed through as removal, but if there is no other value for the reduction, the reduction result is empty.
-rw-r--r--common/datastorequery.cpp7
-rw-r--r--tests/querytest.cpp54
2 files changed, 61 insertions, 0 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index b77dfc9..276a10a 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -327,6 +327,10 @@ public:
327 mReducedValues.insert(reductionValueBa); 327 mReducedValues.insert(reductionValueBa);
328 auto reductionResult = reduceOnValue(reductionValue); 328 auto reductionResult = reduceOnValue(reductionValue);
329 329
330 //This can happen if we get a removal message from a filtered entity and all entites of the reduction are filtered.
331 if (reductionResult.selection.isEmpty()) {
332 return;
333 }
330 mSelectedValues.insert(reductionValueBa, reductionResult.selection); 334 mSelectedValues.insert(reductionValueBa, reductionResult.selection);
331 readEntity(reductionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { 335 readEntity(reductionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) {
332 callback({entity, operation, reductionResult.aggregateValues, reductionResult.aggregateIds}); 336 callback({entity, operation, reductionResult.aggregateValues, reductionResult.aggregateIds});
@@ -345,11 +349,13 @@ public:
345 auto oldSelectionResult = mSelectedValues.take(reductionValueBa); 349 auto oldSelectionResult = mSelectedValues.take(reductionValueBa);
346 if (oldSelectionResult == selectionResult.selection) { 350 if (oldSelectionResult == selectionResult.selection) {
347 mSelectedValues.insert(reductionValueBa, selectionResult.selection); 351 mSelectedValues.insert(reductionValueBa, selectionResult.selection);
352 Q_ASSERT(!selectionResult.selection.isEmpty());
348 readEntity(selectionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) { 353 readEntity(selectionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) {
349 callback({entity, Sink::Operation_Modification, selectionResult.aggregateValues, selectionResult.aggregateIds}); 354 callback({entity, Sink::Operation_Modification, selectionResult.aggregateValues, selectionResult.aggregateIds});
350 }); 355 });
351 } else { 356 } else {
352 //remove old result 357 //remove old result
358 Q_ASSERT(!oldSelectionResult.isEmpty());
353 readEntity(oldSelectionResult, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) { 359 readEntity(oldSelectionResult, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) {
354 callback({entity, Sink::Operation_Removal}); 360 callback({entity, Sink::Operation_Removal});
355 }); 361 });
@@ -358,6 +364,7 @@ public:
358 if (!selectionResult.selection.isEmpty()) { 364 if (!selectionResult.selection.isEmpty()) {
359 //add new result 365 //add new result
360 mSelectedValues.insert(reductionValueBa, selectionResult.selection); 366 mSelectedValues.insert(reductionValueBa, selectionResult.selection);
367 Q_ASSERT(!selectionResult.selection.isEmpty());
361 readEntity(selectionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) { 368 readEntity(selectionResult.selection, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) {
362 callback({entity, Sink::Operation_Creation, selectionResult.aggregateValues, selectionResult.aggregateIds}); 369 callback({entity, Sink::Operation_Creation, selectionResult.aggregateValues, selectionResult.aggregateIds});
363 }); 370 });
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index 26564b5..fa016a2 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -954,6 +954,60 @@ private slots:
954 QCOMPARE(resetSpy.size(), 0); 954 QCOMPARE(resetSpy.size(), 0);
955 } 955 }
956 956
957 void testFilteredReductionUpdate()
958 {
959 // Setup
960 auto folder1 = Folder::createEntity<Folder>("sink.dummy.instance1");
961 VERIFYEXEC(Sink::Store::create<Folder>(folder1));
962
963 auto folder2 = Folder::createEntity<Folder>("sink.dummy.instance1");
964 VERIFYEXEC(Sink::Store::create<Folder>(folder2));
965
966 // Ensure all local data is processed
967 VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
968
969 Query query;
970 query.setId("testFilteredReductionUpdate");
971 query.setFlags(Query::LiveQuery);
972 query.filter<Mail::Folder>(folder1);
973 query.reduce<Mail::Folder>(Query::Reduce::Selector::max<Mail::Date>()).count("count").collect<Mail::Folder>("folders");
974 query.sort<Mail::Date>();
975
976 auto model = Sink::Store::loadModel<Mail>(query);
977 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
978 QCOMPARE(model->rowCount(), 0);
979
980 QSignalSpy insertedSpy(model.data(), &QAbstractItemModel::rowsInserted);
981 QSignalSpy removedSpy(model.data(), &QAbstractItemModel::rowsRemoved);
982 QSignalSpy changedSpy(model.data(), &QAbstractItemModel::dataChanged);
983 QSignalSpy layoutChangedSpy(model.data(), &QAbstractItemModel::layoutChanged);
984 QSignalSpy resetSpy(model.data(), &QAbstractItemModel::modelReset);
985
986 //Ensure we don't end up with a mail in the thread that was filtered
987 //This tests the case of an otherwise emtpy thread on purpose.
988 {
989 auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
990 mail.setExtractedMessageId("filtered");
991 mail.setFolder(folder2);
992 mail.setExtractedDate(QDateTime{QDate{2017, 2, 3}, QTime{11, 0, 0}});
993 VERIFYEXEC(Sink::Store::create(mail));
994 }
995
996 VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
997 QCOMPARE(model->rowCount(), 0);
998
999 //Ensure the non-filtered still get through.
1000 {
1001 auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
1002 mail.setExtractedMessageId("not-filtered");
1003 mail.setFolder(folder1);
1004 mail.setExtractedDate(QDateTime{QDate{2017, 2, 3}, QTime{11, 0, 0}});
1005 VERIFYEXEC(Sink::Store::create(mail));
1006 }
1007 VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
1008 QTRY_COMPARE(model->rowCount(), 1);
1009 }
1010
957 void testBloom() 1011 void testBloom()
958 { 1012 {
959 // Setup 1013 // Setup