summaryrefslogtreecommitdiffstats
path: root/common/resourcefacade.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-07-06 09:57:51 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-07-06 09:57:51 +0200
commita9f3692a0bceb796d10952307f87fdb77abadbf7 (patch)
treedc66407c956cdf7538a6fb9f4dd17334ae3530e2 /common/resourcefacade.cpp
parente03eac8ef4337a9aa538b7cefc803a6abd4acf24 (diff)
downloadsink-a9f3692a0bceb796d10952307f87fdb77abadbf7.tar.gz
sink-a9f3692a0bceb796d10952307f87fdb77abadbf7.zip
Apply the status to resources
Diffstat (limited to 'common/resourcefacade.cpp')
-rw-r--r--common/resourcefacade.cpp238
1 files changed, 168 insertions, 70 deletions
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp
index 3901f43..f6fd7ca 100644
--- a/common/resourcefacade.cpp
+++ b/common/resourcefacade.cpp
@@ -22,37 +22,168 @@
22#include "query.h" 22#include "query.h"
23#include "definitions.h" 23#include "definitions.h"
24#include "storage.h" 24#include "storage.h"
25#include "resourceaccess.h"
25#include <QDir> 26#include <QDir>
26 27
27template <typename DomainType> 28using namespace Sink;
29
30template<typename DomainType>
28ConfigNotifier LocalStorageFacade<DomainType>::sConfigNotifier; 31ConfigNotifier LocalStorageFacade<DomainType>::sConfigNotifier;
29 32
30template <typename DomainType> 33template <typename DomainType>
31LocalStorageFacade<DomainType>::LocalStorageFacade(const QByteArray &identifier) : Sink::StoreFacade<DomainType>(), mConfigStore(identifier), mResourceInstanceIdentifier(identifier) 34static typename DomainType::Ptr readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type)
32{ 35{
36 auto object = DomainType::Ptr::create(id);
37 object->setProperty("type", type);
38 const auto configurationValues = configStore.get(id);
39 for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) {
40 object->setProperty(it.key(), it.value());
41 }
42 return object;
33} 43}
34 44
45static bool matchesFilter(const QHash<QByteArray, Query::Comparator> &filter, const QMap<QByteArray, QVariant> &properties)
46{
47 for (const auto &filterProperty : filter.keys()) {
48 if (filterProperty == "type") {
49 continue;
50 }
51 if (!filter.value(filterProperty).matches(properties.value(filterProperty))) {
52 return false;
53 }
54 }
55 return true;
56}
57
58template<typename DomainType>
59LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, const QByteArray &identifier, ConfigNotifier &configNotifier)
60 : mResultProvider(new ResultProvider<typename DomainType::Ptr>), mConfigStore(identifier)
61{
62 QObject *guard = new QObject;
63 mResultProvider->setFetcher([this, query, guard, &configNotifier](const QSharedPointer<DomainType> &) {
64 const auto entries = mConfigStore.getEntries();
65 for (const auto &res : entries.keys()) {
66 const auto type = entries.value(res);
67
68 if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) {
69 Trace() << "Skipping due to type.";
70 continue;
71 }
72 if (!query.ids.isEmpty() && !query.ids.contains(res)) {
73 continue;
74 }
75 const auto configurationValues = mConfigStore.get(res);
76 if (!matchesFilter(query.propertyFilter, configurationValues)){
77 Trace() << "Skipping due to filter.";
78 continue;
79 }
80 Trace() << "Found match " << res;
81 auto entity = readFromConfig<DomainType>(mConfigStore, res, type);
82 updateStatus(*entity);
83 mResultProvider->add(entity);
84 }
85 if (query.liveQuery) {
86 {
87 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::added, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) {
88 auto entity = entry.staticCast<DomainType>();
89 updateStatus(*entity);
90 mResultProvider->add(entity);
91 });
92 Q_ASSERT(ret);
93 }
94 {
95 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::modified, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) {
96 auto entity = entry.staticCast<DomainType>();
97 updateStatus(*entity);
98 mResultProvider->modify(entity);
99 });
100 Q_ASSERT(ret);
101 }
102 {
103 auto ret = QObject::connect(&configNotifier, &ConfigNotifier::removed, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) {
104 mResultProvider->remove(entry.staticCast<DomainType>());
105 });
106 Q_ASSERT(ret);
107 }
108 }
109 // TODO initialResultSetComplete should be implicit
110 mResultProvider->initialResultSetComplete(typename DomainType::Ptr());
111 mResultProvider->complete();
112 });
113 mResultProvider->onDone([=]() { delete guard; });
114}
115
116// QByteArrayList getMatchingEntries(const Query &query)
117// {
118// const auto entries = mConfigStore.getEntries();
119// for (const auto &res : entries.keys()) {
120// const auto type = entries.value(res);
121//
122// if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) {
123// Trace() << "Skipping due to type.";
124// continue;
125// }
126// if (!query.ids.isEmpty() && !query.ids.contains(res)) {
127// continue;
128// }
129// const auto configurationValues = mConfigStore.get(res);
130// if (!matchesFilter(query.propertyFilter, configurationValues)){
131// Trace() << "Skipping due to filter.";
132// continue;
133// }
134// Trace() << "Found match " << res;
135// auto entity = readFromConfig<DomainType>(mConfigStore, res, type);
136// updateStatus(*entity);
137// mResultProvider->add(entity);
138// }
139//
140// }
141
142
143template<typename DomainType>
144void LocalStorageQueryRunner<DomainType>::updateStatus(DomainType &entity)
145{
146 if (mStatusUpdater) {
147 mStatusUpdater(entity);
148 }
149}
150
151template<typename DomainType>
152void LocalStorageQueryRunner<DomainType>::setStatusUpdater(const std::function<void(DomainType &)> &updater)
153{
154 mStatusUpdater = updater;
155}
156
157template<typename DomainType>
158void LocalStorageQueryRunner<DomainType>::statusChanged(const QByteArray &identifier)
159{
160 Trace() << "Status changed " << identifier;
161 auto entity = readFromConfig<DomainType>(mConfigStore, identifier, ApplicationDomain::getTypeName<DomainType>());
162 updateStatus(*entity);
163 mResultProvider->modify(entity);
164}
165
166template<typename DomainType>
167typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr LocalStorageQueryRunner<DomainType>::emitter()
168{
169 return mResultProvider->emitter();
170}
171
172
35template <typename DomainType> 173template <typename DomainType>
36LocalStorageFacade<DomainType>::~LocalStorageFacade() 174LocalStorageFacade<DomainType>::LocalStorageFacade(const QByteArray &identifier) : StoreFacade<DomainType>(), mIdentifier(identifier), mConfigStore(identifier)
37{ 175{
38} 176}
39 177
40template <typename DomainType> 178template <typename DomainType>
41typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type) 179LocalStorageFacade<DomainType>::~LocalStorageFacade()
42{ 180{
43 auto object = DomainType::Ptr::create(id);
44 object->setProperty("type", type);
45 const auto configurationValues = configStore.get(id);
46 for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) {
47 object->setProperty(it.key(), it.value());
48 }
49 return object;
50} 181}
51 182
52template <typename DomainType> 183template <typename DomainType>
53typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(const QByteArray &id, const QByteArray &type) 184typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(const QByteArray &id, const QByteArray &type)
54{ 185{
55 return readFromConfig(mConfigStore, id, type); 186 return ::readFromConfig<DomainType>(mConfigStore, id, type);
56} 187}
57 188
58template <typename DomainType> 189template <typename DomainType>
@@ -119,68 +250,13 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::remove(const DomainType &domai
119 }); 250 });
120} 251}
121 252
122static bool matchesFilter(const QHash<QByteArray, Sink::Query::Comparator> &filter, const QMap<QByteArray, QVariant> &properties)
123{
124 for (const auto &filterProperty : filter.keys()) {
125 if (filterProperty == "type") {
126 continue;
127 }
128 if (!filter.value(filterProperty).matches(properties.value(filterProperty))) {
129 return false;
130 }
131 }
132 return true;
133}
134
135template <typename DomainType> 253template <typename DomainType>
136QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr> LocalStorageFacade<DomainType>::load(const Sink::Query &query) 254QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> LocalStorageFacade<DomainType>::load(const Query &query)
137{ 255{
138 QObject *guard = new QObject; 256 auto runner = new LocalStorageQueryRunner<DomainType>(query, mIdentifier, sConfigNotifier);
139 auto resultProvider = new Sink::ResultProvider<typename DomainType::Ptr>(); 257 return qMakePair(KAsync::null<void>(), runner->emitter());
140 auto emitter = resultProvider->emitter();
141 auto identifier = mResourceInstanceIdentifier;
142 resultProvider->setFetcher([identifier, query, guard, resultProvider](const QSharedPointer<DomainType> &) {
143 ConfigStore mConfigStore(identifier);
144 const auto entries = mConfigStore.getEntries();
145 for (const auto &res : entries.keys()) {
146 const auto type = entries.value(res);
147
148 if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) {
149 Trace() << "Skipping due to type.";
150 continue;
151 }
152 if (!query.ids.isEmpty() && !query.ids.contains(res)) {
153 continue;
154 }
155 const auto configurationValues = mConfigStore.get(res);
156 if (!matchesFilter(query.propertyFilter, configurationValues)){
157 Trace() << "Skipping due to filter.";
158 continue;
159 }
160 Trace() << "Found match " << res;
161 resultProvider->add(readFromConfig(mConfigStore, res, type));
162 }
163 if (query.liveQuery) {
164 QObject::connect(&sConfigNotifier, &ConfigNotifier::modified, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) {
165 resultProvider->modify(entry.staticCast<DomainType>());
166 });
167 QObject::connect(&sConfigNotifier, &ConfigNotifier::added, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) {
168 resultProvider->add(entry.staticCast<DomainType>());
169 });
170 QObject::connect(&sConfigNotifier, &ConfigNotifier::removed, guard,[resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) {
171 resultProvider->remove(entry.staticCast<DomainType>());
172 });
173 }
174 // TODO initialResultSetComplete should be implicit
175 resultProvider->initialResultSetComplete(typename DomainType::Ptr());
176 resultProvider->complete();
177 });
178 resultProvider->onDone([=]() { delete resultProvider; delete guard; });
179
180 return qMakePair(KAsync::null<void>(), emitter);
181} 258}
182 259
183
184ResourceFacade::ResourceFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkResource>("resources") 260ResourceFacade::ResourceFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkResource>("resources")
185{ 261{
186} 262}
@@ -201,6 +277,28 @@ KAsync::Job<void> ResourceFacade::remove(const Sink::ApplicationDomain::SinkReso
201 }); 277 });
202} 278}
203 279
280QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename ApplicationDomain::SinkResource::Ptr>::Ptr> ResourceFacade::load(const Sink::Query &query)
281{
282 auto runner = new LocalStorageQueryRunner<ApplicationDomain::SinkResource>(query, mIdentifier, sConfigNotifier);
283 auto monitoredResources = QSharedPointer<QSet<QByteArray>>::create();
284 runner->setStatusUpdater([runner, monitoredResources](ApplicationDomain::SinkResource &resource) {
285 auto resourceAccess = ResourceAccessFactory::instance().getAccess(resource.identifier(), ResourceConfig::getResourceType(resource.identifier()));
286 if (!monitoredResources->contains(resource.identifier())) {
287 //TODO disconnect at some point when the runner is done
288 auto ret = QObject::connect(resourceAccess.data(), &ResourceAccess::notification, [resource, runner, resourceAccess](const Notification &notification) {
289 Trace() << "Received notification in facade: " << notification.type;
290 if (notification.type == Notification::Status) {
291 runner->statusChanged(resource.identifier());
292 }
293 });
294 Q_ASSERT(ret);
295 monitoredResources->insert(resource.identifier());
296 }
297 resource.setStatusStatus(resourceAccess->getResourceStatus());
298 });
299 return qMakePair(KAsync::null<void>(), runner->emitter());
300}
301
204 302
205AccountFacade::AccountFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkAccount>("accounts") 303AccountFacade::AccountFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkAccount>("accounts")
206{ 304{