From c04755a772cbc6b2cf3a80e9c3c17b718e153c55 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 4 Nov 2016 15:07:35 +0100 Subject: User querybase --- common/datastorequery.cpp | 22 ++-- common/datastorequery.h | 6 +- common/query.h | 292 +++++++++++++++++++++++++---------------- common/queryrunner.cpp | 2 +- common/storage/entitystore.cpp | 2 +- common/storage/entitystore.h | 2 +- common/store.cpp | 2 +- common/typeindex.cpp | 6 +- common/typeindex.h | 2 +- 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 { public: typedef QSharedPointer Ptr; - QHash propertyFilter; + QHash propertyFilter; Filter(FilterBase::Ptr source, DataStoreQuery *store) : FilterBase(source, store) @@ -146,18 +146,18 @@ public: typedef QSharedPointer Ptr; struct Aggregator { - Query::Reduce::Aggregator::Operation operation; + QueryBase::Reduce::Aggregator::Operation operation; QByteArray property; QByteArray resultProperty; - Aggregator(Query::Reduce::Aggregator::Operation o, const QByteArray &property_, const QByteArray &resultProperty_) + Aggregator(QueryBase::Reduce::Aggregator::Operation o, const QByteArray &property_, const QByteArray &resultProperty_) : operation(o), property(property_), resultProperty(resultProperty_) { } void process() { - if (operation == Query::Reduce::Aggregator::Count) { + if (operation == QueryBase::Reduce::Aggregator::Count) { mResult = mResult.toInt() + 1; } else { Q_ASSERT(false); @@ -165,7 +165,7 @@ public: } void process(const QVariant &value) { - if (operation == Query::Reduce::Aggregator::Collect) { + if (operation == QueryBase::Reduce::Aggregator::Collect) { mResult = mResult.toList() << value; } else { Q_ASSERT(false); @@ -189,10 +189,10 @@ public: QSet mReducedValues; QByteArray mReductionProperty; QByteArray mSelectionProperty; - Query::Reduce::Selector::Comparator mSelectionComparator; + QueryBase::Reduce::Selector::Comparator mSelectionComparator; QList mAggregators; - Reduce(const QByteArray &reductionProperty, const QByteArray &selectionProperty, Query::Reduce::Selector::Comparator comparator, FilterBase::Ptr source, DataStoreQuery *store) + Reduce(const QByteArray &reductionProperty, const QByteArray &selectionProperty, QueryBase::Reduce::Selector::Comparator comparator, FilterBase::Ptr source, DataStoreQuery *store) : FilterBase(source, store), mReductionProperty(reductionProperty), mSelectionProperty(selectionProperty), @@ -213,8 +213,8 @@ public: return QByteArray(); } - static bool compare(const QVariant &left, const QVariant &right, Query::Reduce::Selector::Comparator comparator) { - if (comparator == Query::Reduce::Selector::Max) { + static bool compare(const QVariant &left, const QVariant &right, QueryBase::Reduce::Selector::Comparator comparator) { + if (comparator == QueryBase::Reduce::Selector::Max) { return left > right; } return false; @@ -302,7 +302,7 @@ public: } }; -DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, EntityStore &store) +DataStoreQuery::DataStoreQuery(const Sink::QueryBase &query, const QByteArray &type, EntityStore &store) : mQuery(query), mType(type), mStore(store) { setupQuery(); @@ -398,7 +398,7 @@ QVector DataStoreQuery::indexLookup(const QByteArray &property, cons /* } */ /* } */ -QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery) +QByteArrayList DataStoreQuery::executeSubquery(const QueryBase &subquery) { Q_ASSERT(!subquery.type().isEmpty()); 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 { public: typedef QSharedPointer Ptr; - DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::EntityStore &store); + DataStoreQuery(const Sink::QueryBase &query, const QByteArray &type, Sink::Storage::EntityStore &store); ResultSet execute(); ResultSet update(qint64 baseRevision); @@ -49,9 +49,9 @@ private: QVector loadIncrementalResultSet(qint64 baseRevision); void setupQuery(); - QByteArrayList executeSubquery(const Sink::Query &subquery); + QByteArrayList executeSubquery(const Sink::QueryBase &subquery); - Sink::Query mQuery; + Sink::QueryBase mQuery; const QByteArray mType; bool mInitialQuery; QSharedPointer 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: return mBaseFilterStage.propertyFilter; } + Filter getFilter() const + { + return mBaseFilterStage; + } + QByteArrayList ids() const { return mBaseFilterStage.ids; @@ -103,9 +108,143 @@ public: return mType; } + void setSortProperty(const QByteArray &property) + { + mSortPorperty = property; + } + + QByteArray sortProperty() const + { + return mSortPorperty; + } + + class FilterStage { + public: + virtual ~FilterStage(){}; + }; + + QList> getFilterStages() + { + return mFilterStages; + } + + class Reduce : public FilterStage { + public: + + class Selector { + public: + enum Comparator { + Min, //get the minimum value + Max, //get the maximum value + First //Get the first result we get + }; + + template + static Selector max() + { + return Selector(SelectionProperty::name, Max); + } + + Selector(const QByteArray &p, Comparator c) + : property(p), + comparator(c) + { + } + + QByteArray property; + Comparator comparator; + }; + + class Aggregator { + public: + enum Operation { + Count, + Collect + }; + + Aggregator(const QByteArray &p, Operation o, const QByteArray &c = QByteArray()) + : resultProperty(p), + operation(o), + propertyToCollect(c) + { + } + + QByteArray resultProperty; + Operation operation; + QByteArray propertyToCollect; + }; + + Reduce(const QByteArray &p, const Selector &s) + : property(p), + selector(s) + { + } + + Reduce &count(const QByteArray &propertyName = "count") + { + aggregators << Aggregator(propertyName, Aggregator::Count); + return *this; + } + + template + Reduce &collect(const QByteArray &propertyName) + { + aggregators << Aggregator(propertyName, Aggregator::Collect, T::name); + return *this; + } + + //Reduce on property + QByteArray property; + Selector selector; + QList aggregators; + + //TODO add aggregate functions like: + //.count() + //.collect(); + //... + // + //Potentially pass-in an identifier under which the result will be available in the result set. + }; + + template + Reduce &reduce(const Reduce::Selector &s) + { + auto reduction = QSharedPointer::create(T::name, s); + mFilterStages << reduction; + return *reduction; + } + + /** + * "Bloom" on a property. + * + * For every encountered value of a property, + * a result set is generated containing all entries with the same value. + * + * Example: + * For an input set of one mail; return all emails with the same threadId. + */ + class Bloom : public FilterStage { + public: + //Property to bloom on + QByteArray property; + Bloom(const QByteArray &p) + : property(p) + { + } + }; + + template + void bloom() + { + auto bloom = QSharedPointer::create(T::name); + mFilterStages << bloom; + } + private: Filter mBaseFilterStage; + QList> mFilterStages; QByteArray mType; + QByteArray mSortPorperty; }; /** @@ -140,7 +279,7 @@ public: template Query &sort() { - sortProperty = T::name; + setSortProperty(T::name); return *this; } @@ -212,7 +351,6 @@ public: QByteArrayList requestedProperties; QByteArray parentProperty; - QByteArray sortProperty; int limit; void setFlags(Flags flags) @@ -230,16 +368,6 @@ public: return mFlags & SynchronousQuery; } - class FilterStage { - public: - virtual ~FilterStage(){}; - }; - - QList> getFilterStages() - { - return mFilterStages; - } - Filter getResourceFilter() const { return mResourceFilter; @@ -276,122 +404,56 @@ public: return resourceFilter(T::name, value); } - class Reduce : public FilterStage { - public: - - class Selector { - public: - enum Comparator { - Min, //get the minimum value - Max, //get the maximum value - First //Get the first result we get - }; - - template - static Selector max() - { - return Selector(SelectionProperty::name, Max); - } - - Selector(const QByteArray &p, Comparator c) - : property(p), - comparator(c) - { - } - - QByteArray property; - Comparator comparator; - }; - - class Aggregator { - public: - enum Operation { - Count, - Collect - }; - - Aggregator(const QByteArray &p, Operation o, const QByteArray &c = QByteArray()) - : resultProperty(p), - operation(o), - propertyToCollect(c) - { - } - - QByteArray resultProperty; - Operation operation; - QByteArray propertyToCollect; - }; - - Reduce(const QByteArray &p, const Selector &s) - : property(p), - selector(s) - { - } - - Reduce &count(const QByteArray &propertyName = "count") - { - aggregators << Aggregator(propertyName, Aggregator::Count); - return *this; - } +private: + Flags mFlags; + Filter mResourceFilter; +}; - template - Reduce &collect(const QByteArray &propertyName) - { - aggregators << Aggregator(propertyName, Aggregator::Collect, T::name); - return *this; - } +class SyncScope : public QueryBase { +public: + template + SyncScope() + { + setType(ApplicationDomain::getTypeName()); + } - //Reduce on property - QByteArray property; - Selector selector; - QList aggregators; + Query::Filter getResourceFilter() const + { + return mResourceFilter; + } - //TODO add aggregate functions like: - //.count() - //.collect(); - //... - // - //Potentially pass-in an identifier under which the result will be available in the result set. - }; + SyncScope &resourceFilter(const QByteArray &id) + { + mResourceFilter.ids << id; + return *this; + } template - Reduce &reduce(const Reduce::Selector &s) + SyncScope &filter(const Query::Comparator &comparator) { - auto reduction = QSharedPointer::create(T::name, s); - mFilterStages << reduction; - return *reduction; + return filter(T::name, comparator); } - /** - * "Bloom" on a property. - * - * For every encountered value of a property, - * a result set is generated containing all entries with the same value. - * - * Example: - * For an input set of one mail; return all emails with the same threadId. - */ - class Bloom : public FilterStage { - public: - //Property to bloom on - QByteArray property; - Bloom(const QByteArray &p) - : property(p) - { - } - }; + SyncScope &filter(const QByteArray &id) + { + QueryBase::filter(id); + return *this; + } - template - void bloom() + SyncScope &filter(const QByteArrayList &ids) { - auto bloom = QSharedPointer::create(T::name); - mFilterStages << bloom; + QueryBase::filter(ids); + return *this; + } + + SyncScope &filter(const QByteArray &property, const Query::Comparator &comparator) + { + QueryBase::filter(property, comparator); + return *this; } private: - Flags mFlags; - Filter mResourceFilter; - QList> mFilterStages; + Query::Filter mResourceFilter; }; } 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::QueryRunner(const Sink::Query &query, const Sink::Resou : QueryRunnerBase(), mResourceContext(context), mResourceAccess(mResourceContext.resourceAccess()), mResultProvider(new ResultProvider), mBatchSize(query.limit) { SinkTrace() << "Starting query"; - if (query.limit && query.sortProperty.isEmpty()) { + if (query.limit && query.sortProperty().isEmpty()) { SinkWarning() << "A limited query without sorting is typically a bad idea."; } auto guardPtr = QPointer(&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 EntityStore::fullScan(const QByteArray &type) return keys.toList().toVector(); } -QVector EntityStore::indexLookup(const QByteArray &type, const Query &query, QSet &appliedFilters, QByteArray &appliedSorting) +QVector EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet &appliedFilters, QByteArray &appliedSorting) { return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction()); } 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: void abortTransaction(); QVector fullScan(const QByteArray &type); - QVector indexLookup(const QByteArray &type, const Query &query, QSet &appliedFilters, QByteArray &appliedSorting); + QVector indexLookup(const QByteArray &type, const QueryBase &query, QSet &appliedFilters, QByteArray &appliedSorting); QVector indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value); void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function &callback); template 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 Store::loadModel(Query query) SinkTrace() << " Parent: " << query.parentProperty; SinkTrace() << " Ids: " << query.ids(); SinkTrace() << " IsLive: " << query.liveQuery(); - SinkTrace() << " Sorting: " << query.sortProperty; + SinkTrace() << " Sorting: " << query.sortProperty(); auto model = QSharedPointer>::create(query, query.requestedProperties); //* 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 } } -static QVector indexLookup(Index &index, Query::Comparator filter) +static QVector indexLookup(Index &index, QueryBase::Comparator filter) { QVector keys; QByteArrayList lookupKeys; @@ -167,11 +167,11 @@ static QVector indexLookup(Index &index, Query::Comparator filter) return keys; } -QVector TypeIndex::query(const Sink::Query &query, QSet &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction) +QVector TypeIndex::query(const Sink::QueryBase &query, QSet &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction) { QVector keys; for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { - if (query.hasFilter(it.key()) && query.sortProperty == it.value()) { + if (query.hasFilter(it.key()) && query.sortProperty() == it.value()) { Index index(indexName(it.key(), it.value()), transaction); keys << indexLookup(index, query.getFilter(it.key())); 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: void add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); void remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction); - QVector query(const Sink::Query &query, QSet &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction); + QVector query(const Sink::QueryBase &query, QSet &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction); QVector lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction); template -- cgit v1.2.3