summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-05-12 14:00:54 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-05-12 14:00:54 +0200
commitd3cb4e649177443e8ecfd7f86d136fc0a319e2f3 (patch)
tree5a873b810944e1998b8f472db6c59fcc7e307863
parent8730949269771ad4d6bba9ba2414d272f9a0a799 (diff)
downloadsink-d3cb4e649177443e8ecfd7f86d136fc0a319e2f3.tar.gz
sink-d3cb4e649177443e8ecfd7f86d136fc0a319e2f3.zip
Don't add resources that don't match the query during a livequery
-rw-r--r--common/resourcefacade.cpp43
-rw-r--r--common/resourcefacade.h18
-rw-r--r--tests/querytest.cpp35
3 files changed, 75 insertions, 21 deletions
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp
index e6f98a9..dab6aed 100644
--- a/common/resourcefacade.cpp
+++ b/common/resourcefacade.cpp
@@ -96,17 +96,24 @@ template<typename DomainType>
96LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, const QByteArray &identifier, const QByteArray &typeName, ConfigNotifier &configNotifier, const Sink::Log::Context &ctx) 96LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, const QByteArray &identifier, const QByteArray &typeName, ConfigNotifier &configNotifier, const Sink::Log::Context &ctx)
97 : mResultProvider(new ResultProvider<typename DomainType::Ptr>), mConfigStore(identifier, typeName), mGuard(new QObject), mLogCtx(ctx.subContext("config")) 97 : mResultProvider(new ResultProvider<typename DomainType::Ptr>), mConfigStore(identifier, typeName), mGuard(new QObject), mLogCtx(ctx.subContext("config"))
98{ 98{
99
100 auto matchesTypeAndIds = [query, this] (const QByteArray &type, const QByteArray &id) {
101 if (query.hasFilter(ApplicationDomain::SinkResource::ResourceType::name) && query.getFilter(ApplicationDomain::SinkResource::ResourceType::name).value.toByteArray() != type) {
102 SinkTraceCtx(mLogCtx) << "Skipping due to type.";
103 return false;
104 }
105 if (!query.ids().isEmpty() && !query.ids().contains(id)) {
106 return false;
107 }
108 return true;
109 };
110
99 QObject *guard = new QObject; 111 QObject *guard = new QObject;
100 mResultProvider->setFetcher([this, query, guard, &configNotifier](const QSharedPointer<DomainType> &) { 112 mResultProvider->setFetcher([this, query, guard, &configNotifier, matchesTypeAndIds](const QSharedPointer<DomainType> &) {
101 const auto entries = mConfigStore.getEntries(); 113 const auto entries = mConfigStore.getEntries();
102 for (const auto &res : entries.keys()) { 114 for (const auto &res : entries.keys()) {
103 const auto type = entries.value(res); 115 const auto type = entries.value(res);
104 116 if (!matchesTypeAndIds(type, res)){
105 if (query.hasFilter(ApplicationDomain::SinkResource::ResourceType::name) && query.getFilter(ApplicationDomain::SinkResource::ResourceType::name).value.toByteArray() != type) {
106 SinkTraceCtx(mLogCtx) << "Skipping due to type.";
107 continue;
108 }
109 if (!query.ids().isEmpty() && !query.ids().contains(res)) {
110 continue; 117 continue;
111 } 118 }
112 auto entity = readFromConfig<DomainType>(mConfigStore, res, type, query.requestedProperties); 119 auto entity = readFromConfig<DomainType>(mConfigStore, res, type, query.requestedProperties);
@@ -124,8 +131,14 @@ LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query,
124 }); 131 });
125 if (query.liveQuery()) { 132 if (query.liveQuery()) {
126 { 133 {
127 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::added, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { 134 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::added, guard, [this, query, matchesTypeAndIds](const ApplicationDomain::ApplicationDomainType::Ptr &entry, const QByteArray &type) {
128 auto entity = entry.staticCast<DomainType>(); 135 auto entity = entry.staticCast<DomainType>();
136 if (!matchesTypeAndIds(type, entity->identifier())){
137 return;
138 }
139 if (!matchesFilter(query.getBaseFilters(), *entity)){
140 return;
141 }
129 SinkTraceCtx(mLogCtx) << "A new resource has been added: " << entity->identifier(); 142 SinkTraceCtx(mLogCtx) << "A new resource has been added: " << entity->identifier();
130 updateStatus(*entity); 143 updateStatus(*entity);
131 mResultProvider->add(entity); 144 mResultProvider->add(entity);
@@ -133,8 +146,14 @@ LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query,
133 Q_ASSERT(ret); 146 Q_ASSERT(ret);
134 } 147 }
135 { 148 {
136 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::modified, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { 149 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::modified, guard, [this, query, matchesTypeAndIds](const ApplicationDomain::ApplicationDomainType::Ptr &entry, const QByteArray &type) {
137 auto entity = entry.staticCast<DomainType>(); 150 auto entity = entry.staticCast<DomainType>();
151 if (!matchesTypeAndIds(type, entity->identifier())){
152 return;
153 }
154 if (!matchesFilter(query.getBaseFilters(), *entity)){
155 return;
156 }
138 updateStatus(*entity); 157 updateStatus(*entity);
139 mResultProvider->modify(entity); 158 mResultProvider->modify(entity);
140 }); 159 });
@@ -218,7 +237,7 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::create(const DomainType &domai
218 } 237 }
219 configStore.modify(identifier, configurationValues); 238 configStore.modify(identifier, configurationValues);
220 } 239 }
221 sConfigNotifier.add(::readFromConfig<DomainType>(configStore, identifier, type, QByteArrayList{})); 240 sConfigNotifier.add(::readFromConfig<DomainType>(configStore, identifier, type, QByteArrayList{}), type);
222 }); 241 });
223} 242}
224 243
@@ -247,7 +266,7 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::modify(const DomainType &domai
247 } 266 }
248 267
249 const auto type = configStore.getEntries().value(identifier); 268 const auto type = configStore.getEntries().value(identifier);
250 sConfigNotifier.modify(::readFromConfig<DomainType>(configStore, identifier, type, QByteArrayList{})); 269 sConfigNotifier.modify(::readFromConfig<DomainType>(configStore, identifier, type, QByteArrayList{}), type);
251 }); 270 });
252} 271}
253 272
@@ -277,7 +296,7 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::remove(const DomainType &domai
277 SinkTrace() << "Removing: " << identifier; 296 SinkTrace() << "Removing: " << identifier;
278 auto configStore = ConfigStore(configStoreIdentifier, typeName); 297 auto configStore = ConfigStore(configStoreIdentifier, typeName);
279 configStore.remove(identifier); 298 configStore.remove(identifier);
280 sConfigNotifier.remove(QSharedPointer<DomainType>::create(domainObject)); 299 sConfigNotifier.remove(QSharedPointer<DomainType>::create(domainObject), typeName);
281 }); 300 });
282} 301}
283 302
diff --git a/common/resourcefacade.h b/common/resourcefacade.h
index 1cc075c..76fadce 100644
--- a/common/resourcefacade.h
+++ b/common/resourcefacade.h
@@ -36,24 +36,24 @@ class ConfigNotifier : public QObject
36{ 36{
37 Q_OBJECT 37 Q_OBJECT
38public: 38public:
39 void add(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account) 39 void add(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type)
40 { 40 {
41 emit added(account); 41 emit added(account, type);
42 } 42 }
43 43
44 void remove(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account) 44 void remove(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type)
45 { 45 {
46 emit removed(account); 46 emit removed(account, type);
47 } 47 }
48 48
49 void modify(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account) 49 void modify(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type)
50 { 50 {
51 emit modified(account); 51 emit modified(account, type);
52 } 52 }
53signals: 53signals:
54 void added(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account); 54 void added(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type);
55 void removed(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account); 55 void removed(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type);
56 void modified(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account); 56 void modified(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account, const QByteArray &type);
57}; 57};
58 58
59template <typename DomainType> 59template <typename DomainType>
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index 72eca86..4ff1be8 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -625,6 +625,41 @@ private slots:
625 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 625 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
626 auto folders = Sink::Store::read<Folder>(Sink::Query{}.resourceContainsFilter<SinkResource::Capabilities>("cap1")); 626 auto folders = Sink::Store::read<Folder>(Sink::Query{}.resourceContainsFilter<SinkResource::Capabilities>("cap1"));
627 QCOMPARE(folders.size(), 1); 627 QCOMPARE(folders.size(), 1);
628
629 //TODO this should be part of the regular cleanup between tests
630 VERIFYEXEC(Store::remove(resource1));
631 VERIFYEXEC(Store::remove(resource2));
632 }
633
634 void testFilteredLiveResourceSubQuery()
635 {
636 using namespace Sink;
637 using namespace Sink::ApplicationDomain;
638
639 //Setup
640 auto resource1 = ApplicationDomainType::createEntity<SinkResource>();
641 resource1.setResourceType("sink.dummy");
642 resource1.setCapabilities(QByteArrayList() << "cap1");
643 VERIFYEXEC(Store::create(resource1));
644 VERIFYEXEC(Store::create<Folder>(Folder{resource1.identifier()}));
645 VERIFYEXEC(ResourceControl::flushMessageQueue(resource1.identifier()));
646
647 auto model = Sink::Store::loadModel<Folder>(Query{Query::LiveQuery}.resourceContainsFilter<SinkResource::Capabilities>("cap1"));
648 QTRY_COMPARE(model->rowCount(), 1);
649
650 auto resource2 = ApplicationDomainType::createEntity<SinkResource>();
651 resource2.setCapabilities(QByteArrayList() << "cap2");
652 resource2.setResourceType("sink.dummy");
653 VERIFYEXEC(Store::create(resource2));
654 VERIFYEXEC(Store::create<Folder>(Folder{resource2.identifier()}));
655 VERIFYEXEC(ResourceControl::flushMessageQueue(resource2.identifier()));
656
657 //The new resource should be filtered and thus not make it in here
658 QCOMPARE(model->rowCount(), 1);
659
660 //TODO this should be part of the regular cleanup between tests
661 VERIFYEXEC(Store::remove(resource1));
662 VERIFYEXEC(Store::remove(resource2));
628 } 663 }
629 664
630 void testLivequeryUnmatchInThread() 665 void testLivequeryUnmatchInThread()