summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/datastorequery.cpp22
-rw-r--r--common/datastorequery.h6
-rw-r--r--common/query.h292
-rw-r--r--common/queryrunner.cpp2
-rw-r--r--common/storage/entitystore.cpp2
-rw-r--r--common/storage/entitystore.h2
-rw-r--r--common/store.cpp2
-rw-r--r--common/typeindex.cpp6
-rw-r--r--common/typeindex.h2
9 files changed, 199 insertions, 137 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 0987d68..de2d124 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -91,7 +91,7 @@ class Filter : public FilterBase {
91public: 91public:
92 typedef QSharedPointer<Filter> Ptr; 92 typedef QSharedPointer<Filter> Ptr;
93 93
94 QHash<QByteArray, Sink::Query::Comparator> propertyFilter; 94 QHash<QByteArray, Sink::QueryBase::Comparator> propertyFilter;
95 95
96 Filter(FilterBase::Ptr source, DataStoreQuery *store) 96 Filter(FilterBase::Ptr source, DataStoreQuery *store)
97 : FilterBase(source, store) 97 : FilterBase(source, store)
@@ -146,18 +146,18 @@ public:
146 typedef QSharedPointer<Reduce> Ptr; 146 typedef QSharedPointer<Reduce> Ptr;
147 147
148 struct Aggregator { 148 struct Aggregator {
149 Query::Reduce::Aggregator::Operation operation; 149 QueryBase::Reduce::Aggregator::Operation operation;
150 QByteArray property; 150 QByteArray property;
151 QByteArray resultProperty; 151 QByteArray resultProperty;
152 152
153 Aggregator(Query::Reduce::Aggregator::Operation o, const QByteArray &property_, const QByteArray &resultProperty_) 153 Aggregator(QueryBase::Reduce::Aggregator::Operation o, const QByteArray &property_, const QByteArray &resultProperty_)
154 : operation(o), property(property_), resultProperty(resultProperty_) 154 : operation(o), property(property_), resultProperty(resultProperty_)
155 { 155 {
156 156
157 } 157 }
158 158
159 void process() { 159 void process() {
160 if (operation == Query::Reduce::Aggregator::Count) { 160 if (operation == QueryBase::Reduce::Aggregator::Count) {
161 mResult = mResult.toInt() + 1; 161 mResult = mResult.toInt() + 1;
162 } else { 162 } else {
163 Q_ASSERT(false); 163 Q_ASSERT(false);
@@ -165,7 +165,7 @@ public:
165 } 165 }
166 166
167 void process(const QVariant &value) { 167 void process(const QVariant &value) {
168 if (operation == Query::Reduce::Aggregator::Collect) { 168 if (operation == QueryBase::Reduce::Aggregator::Collect) {
169 mResult = mResult.toList() << value; 169 mResult = mResult.toList() << value;
170 } else { 170 } else {
171 Q_ASSERT(false); 171 Q_ASSERT(false);
@@ -189,10 +189,10 @@ public:
189 QSet<QByteArray> mReducedValues; 189 QSet<QByteArray> mReducedValues;
190 QByteArray mReductionProperty; 190 QByteArray mReductionProperty;
191 QByteArray mSelectionProperty; 191 QByteArray mSelectionProperty;
192 Query::Reduce::Selector::Comparator mSelectionComparator; 192 QueryBase::Reduce::Selector::Comparator mSelectionComparator;
193 QList<Aggregator> mAggregators; 193 QList<Aggregator> mAggregators;
194 194
195 Reduce(const QByteArray &reductionProperty, const QByteArray &selectionProperty, Query::Reduce::Selector::Comparator comparator, FilterBase::Ptr source, DataStoreQuery *store) 195 Reduce(const QByteArray &reductionProperty, const QByteArray &selectionProperty, QueryBase::Reduce::Selector::Comparator comparator, FilterBase::Ptr source, DataStoreQuery *store)
196 : FilterBase(source, store), 196 : FilterBase(source, store),
197 mReductionProperty(reductionProperty), 197 mReductionProperty(reductionProperty),
198 mSelectionProperty(selectionProperty), 198 mSelectionProperty(selectionProperty),
@@ -213,8 +213,8 @@ public:
213 return QByteArray(); 213 return QByteArray();
214 } 214 }
215 215
216 static bool compare(const QVariant &left, const QVariant &right, Query::Reduce::Selector::Comparator comparator) { 216 static bool compare(const QVariant &left, const QVariant &right, QueryBase::Reduce::Selector::Comparator comparator) {
217 if (comparator == Query::Reduce::Selector::Max) { 217 if (comparator == QueryBase::Reduce::Selector::Max) {
218 return left > right; 218 return left > right;
219 } 219 }
220 return false; 220 return false;
@@ -302,7 +302,7 @@ public:
302 } 302 }
303}; 303};
304 304
305DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore &store) 305DataStoreQuery::DataStoreQuery(const Sink::QueryBase &query, const QByteArray &type, EntityStore &store)
306 : mQuery(query), mType(type), mStore(store) 306 : mQuery(query), mType(type), mStore(store)
307{ 307{
308 setupQuery(); 308 setupQuery();
@@ -398,7 +398,7 @@ QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, cons
398/* } */ 398/* } */
399/* } */ 399/* } */
400 400
401QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) 401QByteArrayList DataStoreQuery::executeSubquery(const QueryBase &subquery)
402{ 402{
403 Q_ASSERT(!subquery.type().isEmpty()); 403 Q_ASSERT(!subquery.type().isEmpty());
404 auto sub = DataStoreQuery(subquery, subquery.type(), mStore); 404 auto sub = DataStoreQuery(subquery, subquery.type(), mStore);
diff --git a/common/datastorequery.h b/common/datastorequery.h
index 5f4149e..65503a8 100644
--- a/common/datastorequery.h
+++ b/common/datastorequery.h
@@ -32,7 +32,7 @@ class DataStoreQuery {
32public: 32public:
33 typedef QSharedPointer<DataStoreQuery> Ptr; 33 typedef QSharedPointer<DataStoreQuery> Ptr;
34 34
35 DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::EntityStore &store); 35 DataStoreQuery(const Sink::QueryBase &query, const QByteArray &type, Sink::Storage::EntityStore &store);
36 ResultSet execute(); 36 ResultSet execute();
37 ResultSet update(qint64 baseRevision); 37 ResultSet update(qint64 baseRevision);
38 38
@@ -49,9 +49,9 @@ private:
49 QVector<QByteArray> loadIncrementalResultSet(qint64 baseRevision); 49 QVector<QByteArray> loadIncrementalResultSet(qint64 baseRevision);
50 50
51 void setupQuery(); 51 void setupQuery();
52 QByteArrayList executeSubquery(const Sink::Query &subquery); 52 QByteArrayList executeSubquery(const Sink::QueryBase &subquery);
53 53
54 Sink::Query mQuery; 54 Sink::QueryBase mQuery;
55 const QByteArray mType; 55 const QByteArray mType;
56 bool mInitialQuery; 56 bool mInitialQuery;
57 QSharedPointer<FilterBase> mCollector; 57 QSharedPointer<FilterBase> mCollector;
diff --git a/common/query.h b/common/query.h
index c9d52b7..b858610 100644
--- a/common/query.h
+++ b/common/query.h
@@ -73,6 +73,11 @@ public:
73 return mBaseFilterStage.propertyFilter; 73 return mBaseFilterStage.propertyFilter;
74 } 74 }
75 75
76 Filter getFilter() const
77 {
78 return mBaseFilterStage;
79 }
80
76 QByteArrayList ids() const 81 QByteArrayList ids() const
77 { 82 {
78 return mBaseFilterStage.ids; 83 return mBaseFilterStage.ids;
@@ -103,9 +108,143 @@ public:
103 return mType; 108 return mType;
104 } 109 }
105 110
111 void setSortProperty(const QByteArray &property)
112 {
113 mSortPorperty = property;
114 }
115
116 QByteArray sortProperty() const
117 {
118 return mSortPorperty;
119 }
120
121 class FilterStage {
122 public:
123 virtual ~FilterStage(){};
124 };
125
126 QList<QSharedPointer<FilterStage>> getFilterStages()
127 {
128 return mFilterStages;
129 }
130
131 class Reduce : public FilterStage {
132 public:
133
134 class Selector {
135 public:
136 enum Comparator {
137 Min, //get the minimum value
138 Max, //get the maximum value
139 First //Get the first result we get
140 };
141
142 template <typename SelectionProperty>
143 static Selector max()
144 {
145 return Selector(SelectionProperty::name, Max);
146 }
147
148 Selector(const QByteArray &p, Comparator c)
149 : property(p),
150 comparator(c)
151 {
152 }
153
154 QByteArray property;
155 Comparator comparator;
156 };
157
158 class Aggregator {
159 public:
160 enum Operation {
161 Count,
162 Collect
163 };
164
165 Aggregator(const QByteArray &p, Operation o, const QByteArray &c = QByteArray())
166 : resultProperty(p),
167 operation(o),
168 propertyToCollect(c)
169 {
170 }
171
172 QByteArray resultProperty;
173 Operation operation;
174 QByteArray propertyToCollect;
175 };
176
177 Reduce(const QByteArray &p, const Selector &s)
178 : property(p),
179 selector(s)
180 {
181 }
182
183 Reduce &count(const QByteArray &propertyName = "count")
184 {
185 aggregators << Aggregator(propertyName, Aggregator::Count);
186 return *this;
187 }
188
189 template <typename T>
190 Reduce &collect(const QByteArray &propertyName)
191 {
192 aggregators << Aggregator(propertyName, Aggregator::Collect, T::name);
193 return *this;
194 }
195
196 //Reduce on property
197 QByteArray property;
198 Selector selector;
199 QList<Aggregator> aggregators;
200
201 //TODO add aggregate functions like:
202 //.count()
203 //.collect<Mail::sender>();
204 //...
205 //
206 //Potentially pass-in an identifier under which the result will be available in the result set.
207 };
208
209 template <typename T>
210 Reduce &reduce(const Reduce::Selector &s)
211 {
212 auto reduction = QSharedPointer<Reduce>::create(T::name, s);
213 mFilterStages << reduction;
214 return *reduction;
215 }
216
217 /**
218 * "Bloom" on a property.
219 *
220 * For every encountered value of a property,
221 * a result set is generated containing all entries with the same value.
222 *
223 * Example:
224 * For an input set of one mail; return all emails with the same threadId.
225 */
226 class Bloom : public FilterStage {
227 public:
228 //Property to bloom on
229 QByteArray property;
230 Bloom(const QByteArray &p)
231 : property(p)
232 {
233 }
234 };
235
236 template <typename T>
237 void bloom()
238 {
239 auto bloom = QSharedPointer<Bloom>::create(T::name);
240 mFilterStages << bloom;
241 }
242
106private: 243private:
107 Filter mBaseFilterStage; 244 Filter mBaseFilterStage;
245 QList<QSharedPointer<FilterStage>> mFilterStages;
108 QByteArray mType; 246 QByteArray mType;
247 QByteArray mSortPorperty;
109}; 248};
110 249
111/** 250/**
@@ -140,7 +279,7 @@ public:
140 template <typename T> 279 template <typename T>
141 Query &sort() 280 Query &sort()
142 { 281 {
143 sortProperty = T::name; 282 setSortProperty(T::name);
144 return *this; 283 return *this;
145 } 284 }
146 285
@@ -212,7 +351,6 @@ public:
212 351
213 QByteArrayList requestedProperties; 352 QByteArrayList requestedProperties;
214 QByteArray parentProperty; 353 QByteArray parentProperty;
215 QByteArray sortProperty;
216 int limit; 354 int limit;
217 355
218 void setFlags(Flags flags) 356 void setFlags(Flags flags)
@@ -230,16 +368,6 @@ public:
230 return mFlags & SynchronousQuery; 368 return mFlags & SynchronousQuery;
231 } 369 }
232 370
233 class FilterStage {
234 public:
235 virtual ~FilterStage(){};
236 };
237
238 QList<QSharedPointer<FilterStage>> getFilterStages()
239 {
240 return mFilterStages;
241 }
242
243 Filter getResourceFilter() const 371 Filter getResourceFilter() const
244 { 372 {
245 return mResourceFilter; 373 return mResourceFilter;
@@ -276,122 +404,56 @@ public:
276 return resourceFilter(T::name, value); 404 return resourceFilter(T::name, value);
277 } 405 }
278 406
279 class Reduce : public FilterStage { 407private:
280 public: 408 Flags mFlags;
281 409 Filter mResourceFilter;
282 class Selector { 410};
283 public:
284 enum Comparator {
285 Min, //get the minimum value
286 Max, //get the maximum value
287 First //Get the first result we get
288 };
289
290 template <typename SelectionProperty>
291 static Selector max()
292 {
293 return Selector(SelectionProperty::name, Max);
294 }
295
296 Selector(const QByteArray &p, Comparator c)
297 : property(p),
298 comparator(c)
299 {
300 }
301
302 QByteArray property;
303 Comparator comparator;
304 };
305
306 class Aggregator {
307 public:
308 enum Operation {
309 Count,
310 Collect
311 };
312
313 Aggregator(const QByteArray &p, Operation o, const QByteArray &c = QByteArray())
314 : resultProperty(p),
315 operation(o),
316 propertyToCollect(c)
317 {
318 }
319
320 QByteArray resultProperty;
321 Operation operation;
322 QByteArray propertyToCollect;
323 };
324
325 Reduce(const QByteArray &p, const Selector &s)
326 : property(p),
327 selector(s)
328 {
329 }
330
331 Reduce &count(const QByteArray &propertyName = "count")
332 {
333 aggregators << Aggregator(propertyName, Aggregator::Count);
334 return *this;
335 }
336 411
337 template <typename T> 412class SyncScope : public QueryBase {
338 Reduce &collect(const QByteArray &propertyName) 413public:
339 { 414 template<typename T>
340 aggregators << Aggregator(propertyName, Aggregator::Collect, T::name); 415 SyncScope()
341 return *this; 416 {
342 } 417 setType(ApplicationDomain::getTypeName<T>());
418 }
343 419
344 //Reduce on property 420 Query::Filter getResourceFilter() const
345 QByteArray property; 421 {
346 Selector selector; 422 return mResourceFilter;
347 QList<Aggregator> aggregators; 423 }
348 424
349 //TODO add aggregate functions like: 425 SyncScope &resourceFilter(const QByteArray &id)
350 //.count() 426 {
351 //.collect<Mail::sender>(); 427 mResourceFilter.ids << id;
352 //... 428 return *this;
353 // 429 }
354 //Potentially pass-in an identifier under which the result will be available in the result set.
355 };
356 430
357 template <typename T> 431 template <typename T>
358 Reduce &reduce(const Reduce::Selector &s) 432 SyncScope &filter(const Query::Comparator &comparator)
359 { 433 {
360 auto reduction = QSharedPointer<Reduce>::create(T::name, s); 434 return filter(T::name, comparator);
361 mFilterStages << reduction;
362 return *reduction;
363 } 435 }
364 436
365 /** 437 SyncScope &filter(const QByteArray &id)
366 * "Bloom" on a property. 438 {
367 * 439 QueryBase::filter(id);
368 * For every encountered value of a property, 440 return *this;
369 * a result set is generated containing all entries with the same value. 441 }
370 *
371 * Example:
372 * For an input set of one mail; return all emails with the same threadId.
373 */
374 class Bloom : public FilterStage {
375 public:
376 //Property to bloom on
377 QByteArray property;
378 Bloom(const QByteArray &p)
379 : property(p)
380 {
381 }
382 };
383 442
384 template <typename T> 443 SyncScope &filter(const QByteArrayList &ids)
385 void bloom()
386 { 444 {
387 auto bloom = QSharedPointer<Bloom>::create(T::name); 445 QueryBase::filter(ids);
388 mFilterStages << bloom; 446 return *this;
447 }
448
449 SyncScope &filter(const QByteArray &property, const Query::Comparator &comparator)
450 {
451 QueryBase::filter(property, comparator);
452 return *this;
389 } 453 }
390 454
391private: 455private:
392 Flags mFlags; 456 Query::Filter mResourceFilter;
393 Filter mResourceFilter;
394 QList<QSharedPointer<FilterStage>> mFilterStages;
395}; 457};
396 458
397} 459}
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index 780b341..cf6fcf8 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -63,7 +63,7 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou
63 : QueryRunnerBase(), mResourceContext(context), mResourceAccess(mResourceContext.resourceAccess()), mResultProvider(new ResultProvider<typename DomainType::Ptr>), mBatchSize(query.limit) 63 : QueryRunnerBase(), mResourceContext(context), mResourceAccess(mResourceContext.resourceAccess()), mResultProvider(new ResultProvider<typename DomainType::Ptr>), mBatchSize(query.limit)
64{ 64{
65 SinkTrace() << "Starting query"; 65 SinkTrace() << "Starting query";
66 if (query.limit && query.sortProperty.isEmpty()) { 66 if (query.limit && query.sortProperty().isEmpty()) {
67 SinkWarning() << "A limited query without sorting is typically a bad idea."; 67 SinkWarning() << "A limited query without sorting is typically a bad idea.";
68 } 68 }
69 auto guardPtr = QPointer<QObject>(&guard); 69 auto guardPtr = QPointer<QObject>(&guard);
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 3c3840a..3512e34 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -338,7 +338,7 @@ QVector<QByteArray> EntityStore::fullScan(const QByteArray &type)
338 return keys.toList().toVector(); 338 return keys.toList().toVector();
339} 339}
340 340
341QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting) 341QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting)
342{ 342{
343 return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction()); 343 return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction());
344} 344}
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h
index 0e7572a..be3817b 100644
--- a/common/storage/entitystore.h
+++ b/common/storage/entitystore.h
@@ -54,7 +54,7 @@ public:
54 void abortTransaction(); 54 void abortTransaction();
55 55
56 QVector<QByteArray> fullScan(const QByteArray &type); 56 QVector<QByteArray> fullScan(const QByteArray &type);
57 QVector<QByteArray> indexLookup(const QByteArray &type, const Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting); 57 QVector<QByteArray> indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting);
58 QVector<QByteArray> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value); 58 QVector<QByteArray> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value);
59 void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback); 59 void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback);
60 template<typename EntityType, typename PropertyType> 60 template<typename EntityType, typename PropertyType>
diff --git a/common/store.cpp b/common/store.cpp
index 5d6e197..2ea5e22 100644
--- a/common/store.cpp
+++ b/common/store.cpp
@@ -135,7 +135,7 @@ QSharedPointer<QAbstractItemModel> Store::loadModel(Query query)
135 SinkTrace() << " Parent: " << query.parentProperty; 135 SinkTrace() << " Parent: " << query.parentProperty;
136 SinkTrace() << " Ids: " << query.ids(); 136 SinkTrace() << " Ids: " << query.ids();
137 SinkTrace() << " IsLive: " << query.liveQuery(); 137 SinkTrace() << " IsLive: " << query.liveQuery();
138 SinkTrace() << " Sorting: " << query.sortProperty; 138 SinkTrace() << " Sorting: " << query.sortProperty();
139 auto model = QSharedPointer<ModelResult<DomainType, typename DomainType::Ptr>>::create(query, query.requestedProperties); 139 auto model = QSharedPointer<ModelResult<DomainType, typename DomainType::Ptr>>::create(query, query.requestedProperties);
140 140
141 //* Client defines lifetime of model 141 //* Client defines lifetime of model
diff --git a/common/typeindex.cpp b/common/typeindex.cpp
index 036b662..b0494f3 100644
--- a/common/typeindex.cpp
+++ b/common/typeindex.cpp
@@ -148,7 +148,7 @@ void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDoma
148 } 148 }
149} 149}
150 150
151static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter) 151static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter)
152{ 152{
153 QVector<QByteArray> keys; 153 QVector<QByteArray> keys;
154 QByteArrayList lookupKeys; 154 QByteArrayList lookupKeys;
@@ -167,11 +167,11 @@ static QVector<QByteArray> indexLookup(Index &index, Query::Comparator filter)
167 return keys; 167 return keys;
168} 168}
169 169
170QVector<QByteArray> TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction) 170QVector<QByteArray> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction)
171{ 171{
172 QVector<QByteArray> keys; 172 QVector<QByteArray> keys;
173 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { 173 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) {
174 if (query.hasFilter(it.key()) && query.sortProperty == it.value()) { 174 if (query.hasFilter(it.key()) && query.sortProperty() == it.value()) {
175 Index index(indexName(it.key(), it.value()), transaction); 175 Index index(indexName(it.key(), it.value()), transaction);
176 keys << indexLookup(index, query.getFilter(it.key())); 176 keys << indexLookup(index, query.getFilter(it.key()));
177 appliedFilters << it.key(); 177 appliedFilters << it.key();
diff --git a/common/typeindex.h b/common/typeindex.h
index 3cffb1e..b1aec38 100644
--- a/common/typeindex.h
+++ b/common/typeindex.h
@@ -68,7 +68,7 @@ public:
68 void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); 68 void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction);
69 void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); 69 void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction);
70 70
71 QVector<QByteArray> query(const Sink::Query &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction); 71 QVector<QByteArray> query(const Sink::QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction);
72 QVector<QByteArray> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction); 72 QVector<QByteArray> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction);
73 73
74 template <typename Left, typename Right> 74 template <typename Left, typename Right>