diff options
Diffstat (limited to 'common/datastorequery.cpp')
-rw-r--r-- | common/datastorequery.cpp | 94 |
1 files changed, 42 insertions, 52 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index 8897c29..f56ac91 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -19,8 +19,6 @@ | |||
19 | #include "datastorequery.h" | 19 | #include "datastorequery.h" |
20 | 20 | ||
21 | #include "log.h" | 21 | #include "log.h" |
22 | #include "entitybuffer.h" | ||
23 | #include "entity_generated.h" | ||
24 | #include "applicationdomaintype.h" | 22 | #include "applicationdomaintype.h" |
25 | 23 | ||
26 | #include "folder.h" | 24 | #include "folder.h" |
@@ -68,8 +66,8 @@ class Source : public FilterBase { | |||
68 | if (mIt == mIds.constEnd()) { | 66 | if (mIt == mIds.constEnd()) { |
69 | return false; | 67 | return false; |
70 | } | 68 | } |
71 | readEntity(*mIt, [callback](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | 69 | readEntity(*mIt, [callback](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { |
72 | callback({uid, entityBuffer, entityBuffer.operation()}); | 70 | callback({entity, operation}); |
73 | }); | 71 | }); |
74 | mIt++; | 72 | mIt++; |
75 | return mIt != mIds.constEnd(); | 73 | return mIt != mIds.constEnd(); |
@@ -110,23 +108,23 @@ public: | |||
110 | bool next(const std::function<void(const ResultSet::Result &result)> &callback) Q_DECL_OVERRIDE { | 108 | bool next(const std::function<void(const ResultSet::Result &result)> &callback) Q_DECL_OVERRIDE { |
111 | bool foundValue = false; | 109 | bool foundValue = false; |
112 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { | 110 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { |
113 | SinkTrace() << "Filter: " << result.uid << result.operation; | 111 | SinkTrace() << "Filter: " << result.entity.identifier() << result.operation; |
114 | 112 | ||
115 | //Always accept removals. They can't match the filter since the data is gone. | 113 | //Always accept removals. They can't match the filter since the data is gone. |
116 | if (result.operation == Sink::Operation_Removal) { | 114 | if (result.operation == Sink::Operation_Removal) { |
117 | SinkTrace() << "Removal: " << result.uid << result.operation; | 115 | SinkTrace() << "Removal: " << result.entity.identifier() << result.operation; |
118 | callback(result); | 116 | callback(result); |
119 | foundValue = true; | 117 | foundValue = true; |
120 | } else if (matchesFilter(result.uid, result.buffer)) { | 118 | } else if (matchesFilter(result.entity)) { |
121 | SinkTrace() << "Accepted: " << result.uid << result.operation; | 119 | SinkTrace() << "Accepted: " << result.entity.identifier() << result.operation; |
122 | callback(result); | 120 | callback(result); |
123 | foundValue = true; | 121 | foundValue = true; |
124 | //TODO if something did not match the filter so far but does now, turn into an add operation. | 122 | //TODO if something did not match the filter so far but does now, turn into an add operation. |
125 | } else { | 123 | } else { |
126 | SinkTrace() << "Rejected: " << result.uid << result.operation; | 124 | SinkTrace() << "Rejected: " << result.entity.identifier() << result.operation; |
127 | //TODO emit a removal if we had the uid in the result set and this is a modification. | 125 | //TODO emit a removal if we had the uid in the result set and this is a modification. |
128 | //We don't know if this results in a removal from the dataset, so we emit a removal notification anyways | 126 | //We don't know if this results in a removal from the dataset, so we emit a removal notification anyways |
129 | callback({result.uid, result.buffer, Sink::Operation_Removal, result.aggregateValues}); | 127 | callback({result.entity, Sink::Operation_Removal, result.aggregateValues}); |
130 | } | 128 | } |
131 | return false; | 129 | return false; |
132 | })) | 130 | })) |
@@ -134,9 +132,9 @@ public: | |||
134 | return foundValue; | 132 | return foundValue; |
135 | } | 133 | } |
136 | 134 | ||
137 | bool matchesFilter(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | 135 | bool matchesFilter(const ApplicationDomain::ApplicationDomainType &entity) { |
138 | for (const auto &filterProperty : propertyFilter.keys()) { | 136 | for (const auto &filterProperty : propertyFilter.keys()) { |
139 | const auto property = getProperty(entityBuffer.entity(), filterProperty); | 137 | const auto property = entity.getProperty(filterProperty); |
140 | const auto comparator = propertyFilter.value(filterProperty); | 138 | const auto comparator = propertyFilter.value(filterProperty); |
141 | if (!comparator.matches(property)) { | 139 | if (!comparator.matches(property)) { |
142 | SinkTrace() << "Filtering entity due to property mismatch on filter: " << filterProperty << property << ":" << comparator.value; | 140 | SinkTrace() << "Filtering entity due to property mismatch on filter: " << filterProperty << property << ":" << comparator.value; |
@@ -224,7 +222,7 @@ public: | |||
224 | bool next(const std::function<void(const ResultSet::Result &)> &callback) Q_DECL_OVERRIDE { | 222 | bool next(const std::function<void(const ResultSet::Result &)> &callback) Q_DECL_OVERRIDE { |
225 | bool foundValue = false; | 223 | bool foundValue = false; |
226 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { | 224 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { |
227 | auto reductionValue = getProperty(result.buffer.entity(), mReductionProperty); | 225 | auto reductionValue = result.entity.getProperty(mReductionProperty); |
228 | if (!mReducedValues.contains(getByteArray(reductionValue))) { | 226 | if (!mReducedValues.contains(getByteArray(reductionValue))) { |
229 | //Only reduce every value once. | 227 | //Only reduce every value once. |
230 | mReducedValues.insert(getByteArray(reductionValue)); | 228 | mReducedValues.insert(getByteArray(reductionValue)); |
@@ -234,18 +232,18 @@ public: | |||
234 | 232 | ||
235 | QVariantList list; | 233 | QVariantList list; |
236 | for (const auto r : results) { | 234 | for (const auto r : results) { |
237 | readEntity(r, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | 235 | readEntity(r, [&, this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { |
238 | for (auto &aggregator : mAggregators) { | 236 | for (auto &aggregator : mAggregators) { |
239 | if (!aggregator.property.isEmpty()) { | 237 | if (!aggregator.property.isEmpty()) { |
240 | aggregator.process(getProperty(entityBuffer.entity(), aggregator.property)); | 238 | aggregator.process(entity.getProperty(aggregator.property)); |
241 | } else { | 239 | } else { |
242 | aggregator.process(); | 240 | aggregator.process(); |
243 | } | 241 | } |
244 | } | 242 | } |
245 | auto selectionValue = getProperty(entityBuffer.entity(), mSelectionProperty); | 243 | auto selectionValue = entity.getProperty(mSelectionProperty); |
246 | if (!selectionResultValue.isValid() || compare(selectionValue, selectionResultValue, mSelectionComparator)) { | 244 | if (!selectionResultValue.isValid() || compare(selectionValue, selectionResultValue, mSelectionComparator)) { |
247 | selectionResultValue = selectionValue; | 245 | selectionResultValue = selectionValue; |
248 | selectionResult = uid; | 246 | selectionResult = entity.identifier(); |
249 | } | 247 | } |
250 | }); | 248 | }); |
251 | } | 249 | } |
@@ -255,8 +253,8 @@ public: | |||
255 | aggregateValues.insert(aggregator.resultProperty, aggregator.result()); | 253 | aggregateValues.insert(aggregator.resultProperty, aggregator.result()); |
256 | } | 254 | } |
257 | 255 | ||
258 | readEntity(selectionResult, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | 256 | readEntity(selectionResult, [&, this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { |
259 | callback({uid, entityBuffer, Sink::Operation_Creation, aggregateValues}); | 257 | callback({entity, Sink::Operation_Creation, aggregateValues}); |
260 | foundValue = true; | 258 | foundValue = true; |
261 | }); | 259 | }); |
262 | } | 260 | } |
@@ -285,11 +283,11 @@ public: | |||
285 | bool next(const std::function<void(const ResultSet::Result &result)> &callback) Q_DECL_OVERRIDE { | 283 | bool next(const std::function<void(const ResultSet::Result &result)> &callback) Q_DECL_OVERRIDE { |
286 | bool foundValue = false; | 284 | bool foundValue = false; |
287 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { | 285 | while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { |
288 | auto bloomValue = getProperty(result.buffer.entity(), mBloomProperty); | 286 | auto bloomValue = result.entity.getProperty(mBloomProperty); |
289 | auto results = indexLookup(mBloomProperty, bloomValue); | 287 | auto results = indexLookup(mBloomProperty, bloomValue); |
290 | for (const auto r : results) { | 288 | for (const auto r : results) { |
291 | readEntity(r, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | 289 | readEntity(r, [&, this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { |
292 | callback({uid, entityBuffer, Sink::Operation_Creation}); | 290 | callback({entity, Sink::Operation_Creation}); |
293 | foundValue = true; | 291 | foundValue = true; |
294 | }); | 292 | }); |
295 | } | 293 | } |
@@ -300,23 +298,15 @@ public: | |||
300 | } | 298 | } |
301 | }; | 299 | }; |
302 | 300 | ||
303 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore::Ptr store, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) | 301 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore::Ptr store) |
304 | : mQuery(query), mType(type), mGetProperty(getProperty), mStore(store) | 302 | : mQuery(query), mType(type), mStore(store) |
305 | { | 303 | { |
306 | setupQuery(); | 304 | setupQuery(); |
307 | } | 305 | } |
308 | 306 | ||
309 | void DataStoreQuery::readEntity(const QByteArray &key, const BufferCallback &resultCallback) | 307 | void DataStoreQuery::readEntity(const QByteArray &key, const BufferCallback &resultCallback) |
310 | { | 308 | { |
311 | mStore->readLatest(mType, key, [=](const QByteArray &key, const Sink::EntityBuffer &buffer) { | 309 | mStore->readLatest(mType, key, resultCallback); |
312 | resultCallback(DataStore::uidFromKey(key), buffer); | ||
313 | return false; | ||
314 | }); | ||
315 | } | ||
316 | |||
317 | QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArray &property) | ||
318 | { | ||
319 | return mGetProperty(entity, property); | ||
320 | } | 310 | } |
321 | 311 | ||
322 | QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) | 312 | QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) |
@@ -404,28 +394,28 @@ QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, cons | |||
404 | /* } */ | 394 | /* } */ |
405 | /* } */ | 395 | /* } */ |
406 | 396 | ||
407 | template <typename ... Args> | 397 | /* template <typename ... Args> */ |
408 | QSharedPointer<DataStoreQuery> prepareQuery(const QByteArray &type, Args && ... args) | 398 | /* QSharedPointer<DataStoreQuery> prepareQuery(const QByteArray &type, Args && ... args) */ |
409 | { | 399 | /* { */ |
410 | if (type == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { | 400 | /* if (type == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) { */ |
411 | return ApplicationDomain::TypeImplementation<ApplicationDomain::Folder>::prepareQuery(std::forward<Args>(args)...); | 401 | /* return ApplicationDomain::TypeImplementation<ApplicationDomain::Folder>::prepareQuery(std::forward<Args>(args)...); */ |
412 | } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { | 402 | /* } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) { */ |
413 | return ApplicationDomain::TypeImplementation<ApplicationDomain::Mail>::prepareQuery(std::forward<Args>(args)...); | 403 | /* return ApplicationDomain::TypeImplementation<ApplicationDomain::Mail>::prepareQuery(std::forward<Args>(args)...); */ |
414 | } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Event>()) { | 404 | /* } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Event>()) { */ |
415 | return ApplicationDomain::TypeImplementation<ApplicationDomain::Event>::prepareQuery(std::forward<Args>(args)...); | 405 | /* return ApplicationDomain::TypeImplementation<ApplicationDomain::Event>::prepareQuery(std::forward<Args>(args)...); */ |
416 | } | 406 | /* } */ |
417 | Q_ASSERT(false); | 407 | /* Q_ASSERT(false); */ |
418 | return QSharedPointer<DataStoreQuery>(); | 408 | /* return QSharedPointer<DataStoreQuery>(); */ |
419 | } | 409 | /* } */ |
420 | 410 | ||
421 | QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) | 411 | QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) |
422 | { | 412 | { |
423 | Q_ASSERT(!subquery.type.isEmpty()); | 413 | Q_ASSERT(!subquery.type.isEmpty()); |
424 | auto sub = prepareQuery(subquery.type, subquery, mStore); | 414 | auto sub = DataStoreQuery(subquery, subquery.type, mStore); |
425 | auto result = sub->execute(); | 415 | auto result = sub.execute(); |
426 | QByteArrayList ids; | 416 | QByteArrayList ids; |
427 | while (result.next([&ids](const ResultSet::Result &result) { | 417 | while (result.next([&ids](const ResultSet::Result &result) { |
428 | ids << result.uid; | 418 | ids << result.entity.identifier(); |
429 | })) | 419 | })) |
430 | {} | 420 | {} |
431 | return ids; | 421 | return ids; |
@@ -518,7 +508,7 @@ ResultSet DataStoreQuery::update(qint64 baseRevision) | |||
518 | mSource->add(incrementalResultSet); | 508 | mSource->add(incrementalResultSet); |
519 | ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { | 509 | ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { |
520 | if (mCollector->next([this, callback](const ResultSet::Result &result) { | 510 | if (mCollector->next([this, callback](const ResultSet::Result &result) { |
521 | SinkTrace() << "Got incremental result: " << result.uid << result.operation; | 511 | SinkTrace() << "Got incremental result: " << result.entity.identifier() << result.operation; |
522 | callback(result); | 512 | callback(result); |
523 | })) | 513 | })) |
524 | { | 514 | { |
@@ -537,8 +527,8 @@ ResultSet DataStoreQuery::execute() | |||
537 | ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { | 527 | ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { |
538 | if (mCollector->next([this, callback](const ResultSet::Result &result) { | 528 | if (mCollector->next([this, callback](const ResultSet::Result &result) { |
539 | if (result.operation != Sink::Operation_Removal) { | 529 | if (result.operation != Sink::Operation_Removal) { |
540 | SinkTrace() << "Got initial result: " << result.uid << result.operation; | 530 | SinkTrace() << "Got initial result: " << result.entity.identifier() << result.operation; |
541 | callback(ResultSet::Result{result.uid, result.buffer, Sink::Operation_Creation, result.aggregateValues}); | 531 | callback(ResultSet::Result{result.entity, Sink::Operation_Creation, result.aggregateValues}); |
542 | } | 532 | } |
543 | })) | 533 | })) |
544 | { | 534 | { |