summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/datastorequery.cpp94
-rw-r--r--common/datastorequery.h18
-rw-r--r--common/domain/event.cpp10
-rw-r--r--common/domain/event.h2
-rw-r--r--common/domain/folder.cpp9
-rw-r--r--common/domain/folder.h1
-rw-r--r--common/domain/mail.cpp23
-rw-r--r--common/domain/mail.h1
-rw-r--r--common/queryrunner.cpp18
-rw-r--r--common/resultset.h4
-rw-r--r--common/storage/entitystore.cpp9
-rw-r--r--common/storage/entitystore.h2
12 files changed, 66 insertions, 125 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
303DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore::Ptr store, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) 301DataStoreQuery::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
309void DataStoreQuery::readEntity(const QByteArray &key, const BufferCallback &resultCallback) 307void 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
317QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArray &property)
318{
319 return mGetProperty(entity, property);
320} 310}
321 311
322QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) 312QVector<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
407template <typename ... Args> 397/* template <typename ... Args> */
408QSharedPointer<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
421QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) 411QByteArrayList 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 {
diff --git a/common/datastorequery.h b/common/datastorequery.h
index 77c8ed5..92235fd 100644
--- a/common/datastorequery.h
+++ b/common/datastorequery.h
@@ -35,21 +35,20 @@ class DataStoreQuery {
35public: 35public:
36 typedef QSharedPointer<DataStoreQuery> Ptr; 36 typedef QSharedPointer<DataStoreQuery> Ptr;
37 37
38 DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::EntityStore::Ptr store, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty); 38 DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::EntityStore::Ptr store);
39 ResultSet execute(); 39 ResultSet execute();
40 ResultSet update(qint64 baseRevision); 40 ResultSet update(qint64 baseRevision);
41 41
42private: 42private:
43 43
44 typedef std::function<bool(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> FilterFunction; 44 typedef std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> FilterFunction;
45 typedef std::function<void(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> BufferCallback; 45 typedef std::function<void(const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> BufferCallback;
46 46
47 virtual QVariant getProperty(const Sink::Entity &entity, const QByteArray &property);
48 QVector<QByteArray> indexLookup(const QByteArray &property, const QVariant &value); 47 QVector<QByteArray> indexLookup(const QByteArray &property, const QVariant &value);
49 48
50 virtual void readEntity(const QByteArray &key, const BufferCallback &resultCallback); 49 virtual void readEntity(const QByteArray &key, const BufferCallback &resultCallback);
51 50
52 ResultSet createFilteredSet(ResultSet &resultSet, const std::function<bool(const QByteArray &, const Sink::EntityBuffer &buffer)> &); 51 ResultSet createFilteredSet(ResultSet &resultSet, const FilterFunction &);
53 QVector<QByteArray> loadIncrementalResultSet(qint64 baseRevision); 52 QVector<QByteArray> loadIncrementalResultSet(qint64 baseRevision);
54 53
55 void setupQuery(); 54 void setupQuery();
@@ -57,7 +56,6 @@ private:
57 56
58 Sink::Query mQuery; 57 Sink::Query mQuery;
59 const QByteArray mType; 58 const QByteArray mType;
60 std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> mGetProperty;
61 bool mInitialQuery; 59 bool mInitialQuery;
62 QSharedPointer<FilterBase> mCollector; 60 QSharedPointer<FilterBase> mCollector;
63 QSharedPointer<Source> mSource; 61 QSharedPointer<Source> mSource;
@@ -85,18 +83,12 @@ public:
85 83
86 virtual ~FilterBase(){} 84 virtual ~FilterBase(){}
87 85
88 void readEntity(const QByteArray &key, const std::function<void(const QByteArray &, const Sink::EntityBuffer &buffer)> &callback) 86 void readEntity(const QByteArray &key, const std::function<void(const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> &callback)
89 { 87 {
90 Q_ASSERT(mDatastore); 88 Q_ASSERT(mDatastore);
91 mDatastore->readEntity(key, callback); 89 mDatastore->readEntity(key, callback);
92 } 90 }
93 91
94 QVariant getProperty(const Sink::Entity &entity, const QByteArray &property)
95 {
96 Q_ASSERT(mDatastore);
97 return mDatastore->getProperty(entity, property);
98 }
99
100 QVector<QByteArray> indexLookup(const QByteArray &property, const QVariant &value) 92 QVector<QByteArray> indexLookup(const QByteArray &property, const QVariant &value)
101 { 93 {
102 Q_ASSERT(mDatastore); 94 Q_ASSERT(mDatastore);
diff --git a/common/domain/event.cpp b/common/domain/event.cpp
index 6717187..d50652d 100644
--- a/common/domain/event.cpp
+++ b/common/domain/event.cpp
@@ -87,13 +87,3 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Event>::BufferBuilder> > T
87 propertyMapper->addMapping<Event::Attachment>(&BufferBuilder::add_attachment); 87 propertyMapper->addMapping<Event::Attachment>(&BufferBuilder::add_attachment);
88 return propertyMapper; 88 return propertyMapper;
89} 89}
90
91DataStoreQuery::Ptr TypeImplementation<Event>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store)
92{
93 auto mapper = initializeReadPropertyMapper();
94 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Event>(), store, [mapper](const Sink::Entity &entity, const QByteArray &property) {
95
96 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
97 return mapper->getProperty(property, localBuffer);
98 });
99}
diff --git a/common/domain/event.h b/common/domain/event.h
index ce9691d..18e0f20 100644
--- a/common/domain/event.h
+++ b/common/domain/event.h
@@ -56,8 +56,6 @@ public:
56 typedef Sink::ApplicationDomain::Buffer::EventBuilder BufferBuilder; 56 typedef Sink::ApplicationDomain::Buffer::EventBuilder BufferBuilder;
57 static void configureIndex(TypeIndex &index); 57 static void configureIndex(TypeIndex &index);
58 static QSet<QByteArray> indexedProperties(); 58 static QSet<QByteArray> indexedProperties();
59 static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store);
60
61 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 59 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
62 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 60 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
63 static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper(); 61 static QSharedPointer<ReadPropertyMapper<Buffer> > initializeReadPropertyMapper();
diff --git a/common/domain/folder.cpp b/common/domain/folder.cpp
index 34e59f6..94727a3 100644
--- a/common/domain/folder.cpp
+++ b/common/domain/folder.cpp
@@ -91,12 +91,3 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Folder>::BufferBuilder> >
91 propertyMapper->addMapping<Folder::SpecialPurpose>(&BufferBuilder::add_specialpurpose); 91 propertyMapper->addMapping<Folder::SpecialPurpose>(&BufferBuilder::add_specialpurpose);
92 return propertyMapper; 92 return propertyMapper;
93} 93}
94
95DataStoreQuery::Ptr TypeImplementation<Folder>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store)
96{
97 auto mapper = initializeReadPropertyMapper();
98 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Folder>(), store, [mapper](const Sink::Entity &entity, const QByteArray &property) {
99 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
100 return mapper->getProperty(property, localBuffer);
101 });
102}
diff --git a/common/domain/folder.h b/common/domain/folder.h
index 0a52b01..ea0d79a 100644
--- a/common/domain/folder.h
+++ b/common/domain/folder.h
@@ -49,7 +49,6 @@ public:
49 typedef Sink::ApplicationDomain::Buffer::Folder Buffer; 49 typedef Sink::ApplicationDomain::Buffer::Folder Buffer;
50 typedef Sink::ApplicationDomain::Buffer::FolderBuilder BufferBuilder; 50 typedef Sink::ApplicationDomain::Buffer::FolderBuilder BufferBuilder;
51 static void configureIndex(TypeIndex &index); 51 static void configureIndex(TypeIndex &index);
52 static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store);
53 static QSet<QByteArray> indexedProperties(); 52 static QSet<QByteArray> indexedProperties();
54 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 53 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
55 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 54 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp
index 9e3a824..b0a3aae 100644
--- a/common/domain/mail.cpp
+++ b/common/domain/mail.cpp
@@ -225,26 +225,3 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Mail>::BufferBuilder> > Ty
225} 225}
226 226
227 227
228DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr store)
229{
230 auto mapper = initializeReadPropertyMapper();
231 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), store, [mapper, store](const Sink::Entity &entity, const QByteArray &property) -> QVariant {
232 if (property == Mail::ThreadId::name) {
233 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
234 Q_ASSERT(localBuffer);
235 auto messageId = mapper->getProperty(Mail::MessageId::name, localBuffer);
236 //FIXME
237 //This is an index property that we have too lookup
238 /* auto thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); */
239 /* auto thread = store->secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId); */
240 /* Q_ASSERT(!thread.isEmpty()); */
241 /* return thread.first(); */
242 return QVariant();
243 } else {
244 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
245 Q_ASSERT(localBuffer);
246 return mapper->getProperty(property, localBuffer);
247 }
248 });
249}
250
diff --git a/common/domain/mail.h b/common/domain/mail.h
index 6c1f670..81a0d1c 100644
--- a/common/domain/mail.h
+++ b/common/domain/mail.h
@@ -49,7 +49,6 @@ public:
49 typedef Sink::ApplicationDomain::Buffer::Mail Buffer; 49 typedef Sink::ApplicationDomain::Buffer::Mail Buffer;
50 typedef Sink::ApplicationDomain::Buffer::MailBuilder BufferBuilder; 50 typedef Sink::ApplicationDomain::Buffer::MailBuilder BufferBuilder;
51 static void configureIndex(TypeIndex &index); 51 static void configureIndex(TypeIndex &index);
52 static QSharedPointer<DataStoreQuery> prepareQuery(const Sink::Query &query, Sink::Storage::EntityStore::Ptr storage);
53 static QSet<QByteArray> indexedProperties(); 52 static QSet<QByteArray> indexedProperties();
54 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 53 static void index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
55 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction); 54 static void removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::DataStore::Transaction &transaction);
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index 4422229..67e83ea 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -176,10 +176,7 @@ QueryWorker<DomainType>::~QueryWorker()
176template <class DomainType> 176template <class DomainType>
177void QueryWorker<DomainType>::resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const ResultSet::Result &result) 177void QueryWorker<DomainType>::resultProviderCallback(const Sink::Query &query, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, const ResultSet::Result &result)
178{ 178{
179 auto adaptor = mResourceContext.adaptorFactory<DomainType>().createAdaptor(result.buffer.entity()); 179 auto valueCopy = Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(result.entity, query.requestedProperties).template staticCast<DomainType>();
180 Q_ASSERT(adaptor);
181 auto domainObject = DomainType{mResourceContext.instanceId(), result.uid, result.buffer.revision(), adaptor};
182 auto valueCopy = Sink::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<DomainType>(domainObject, query.requestedProperties).template staticCast<DomainType>();
183 for (auto it = result.aggregateValues.constBegin(); it != result.aggregateValues.constEnd(); it++) { 180 for (auto it = result.aggregateValues.constBegin(); it != result.aggregateValues.constEnd(); it++) {
184 valueCopy->setProperty(it.key(), it.value()); 181 valueCopy->setProperty(it.key(), it.value());
185 } 182 }
@@ -208,12 +205,10 @@ QPair<qint64, qint64> QueryWorker<DomainType>::executeIncrementalQuery(const Sin
208 QTime time; 205 QTime time;
209 time.start(); 206 time.start();
210 207
211 auto entityStore = EntityStore::Ptr::create(mResourceContext);
212
213 const qint64 baseRevision = resultProvider.revision() + 1; 208 const qint64 baseRevision = resultProvider.revision() + 1;
214 209 auto entityStore = EntityStore::Ptr::create(mResourceContext);
215 auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, entityStore); 210 auto preparedQuery = DataStoreQuery{query, ApplicationDomain::getTypeName<DomainType>(), entityStore};
216 auto resultSet = preparedQuery->update(baseRevision); 211 auto resultSet = preparedQuery.update(baseRevision);
217 SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); 212 SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed());
218 auto replayedEntities = resultSet.replaySet(0, 0, [this, query, &resultProvider](const ResultSet::Result &result) { 213 auto replayedEntities = resultSet.replaySet(0, 0, [this, query, &resultProvider](const ResultSet::Result &result) {
219 resultProviderCallback(query, resultProvider, result); 214 resultProviderCallback(query, resultProvider, result);
@@ -242,9 +237,8 @@ QPair<qint64, qint64> QueryWorker<DomainType>::executeInitialQuery(
242 } 237 }
243 238
244 auto entityStore = EntityStore::Ptr::create(mResourceContext); 239 auto entityStore = EntityStore::Ptr::create(mResourceContext);
245 240 auto preparedQuery = DataStoreQuery{query, ApplicationDomain::getTypeName<DomainType>(), entityStore};
246 auto preparedQuery = ApplicationDomain::TypeImplementation<DomainType>::prepareQuery(query, entityStore); 241 auto resultSet = preparedQuery.execute();
247 auto resultSet = preparedQuery->execute();
248 242
249 SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); 243 SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed());
250 auto replayedEntities = resultSet.replaySet(offset, batchsize, [this, query, &resultProvider](const ResultSet::Result &result) { 244 auto replayedEntities = resultSet.replaySet(offset, batchsize, [this, query, &resultProvider](const ResultSet::Result &result) {
diff --git a/common/resultset.h b/common/resultset.h
index a86a2e2..4f2c278 100644
--- a/common/resultset.h
+++ b/common/resultset.h
@@ -24,6 +24,7 @@
24#include <functional> 24#include <functional>
25#include "metadata_generated.h" 25#include "metadata_generated.h"
26#include "entitybuffer.h" 26#include "entitybuffer.h"
27#include "applicationdomaintype.h"
27 28
28/* 29/*
29 * An iterator to a result set. 30 * An iterator to a result set.
@@ -34,8 +35,7 @@ class ResultSet
34{ 35{
35public: 36public:
36 struct Result { 37 struct Result {
37 QByteArray uid; 38 Sink::ApplicationDomain::ApplicationDomainType entity;
38 Sink::EntityBuffer buffer;
39 Sink::Operation operation; 39 Sink::Operation operation;
40 QMap<QByteArray, QVariant> aggregateValues; 40 QMap<QByteArray, QVariant> aggregateValues;
41 }; 41 };
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 9615eca..fe63f0b 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -184,6 +184,15 @@ void EntityStore::readLatest(const QByteArray &type, const QByteArray &uid, cons
184 }); 184 });
185} 185}
186 186
187void EntityStore::readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &, Sink::Operation)> callback)
188{
189 readLatest(type, uid, [&](const QByteArray &uid, const EntityBuffer &buffer) {
190 auto adaptor = d->resourceContext.adaptorFactory(type).createAdaptor(buffer.entity());
191 //TODO cache max revision for the duration of the transaction.
192 callback(ApplicationDomain::ApplicationDomainType{d->resourceContext.instanceId(), uid, DataStore::maxRevision(d->getTransaction()), adaptor}, buffer.operation());
193 });
194}
195
187ApplicationDomain::ApplicationDomainType EntityStore::readLatest(const QByteArray &type, const QByteArray &uid) 196ApplicationDomain::ApplicationDomainType EntityStore::readLatest(const QByteArray &type, const QByteArray &uid)
188{ 197{
189 ApplicationDomain::ApplicationDomainType dt; 198 ApplicationDomain::ApplicationDomainType dt;
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h
index de29e87..455e9c3 100644
--- a/common/storage/entitystore.h
+++ b/common/storage/entitystore.h
@@ -26,6 +26,7 @@
26#include "query.h" 26#include "query.h"
27#include "storage.h" 27#include "storage.h"
28#include "resourcecontext.h" 28#include "resourcecontext.h"
29#include "metadata_generated.h"
29 30
30namespace Sink { 31namespace Sink {
31class EntityBuffer; 32class EntityBuffer;
@@ -56,6 +57,7 @@ public:
56 57
57 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); 58 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
58 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); 59 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
60 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> callback);
59 61
60 ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid); 62 ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid);
61 63