diff options
Diffstat (limited to 'common/datastorequery.cpp')
-rw-r--r-- | common/datastorequery.cpp | 121 |
1 files changed, 76 insertions, 45 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index 95df1a0..7c0fdea 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -141,51 +141,78 @@ public: | |||
141 | } | 141 | } |
142 | }; | 142 | }; |
143 | 143 | ||
144 | /* class Reduction : public FilterBase { */ | 144 | class Reduce : public FilterBase { |
145 | /* public: */ | 145 | public: |
146 | /* typedef QSharedPointer<Reduction> Ptr; */ | 146 | typedef QSharedPointer<Reduce> Ptr; |
147 | |||
148 | QHash<QByteArray, QVariant> mAggregateValues; | ||
149 | QByteArray mReductionProperty; | ||
150 | QByteArray mSelectionProperty; | ||
151 | enum SelectionComparator { | ||
152 | Max | ||
153 | /* Min, */ | ||
154 | /* First */ | ||
155 | }; | ||
156 | SelectionComparator mSelectionComparator; | ||
147 | 157 | ||
148 | /* QHash<QByteArray, QDateTime> aggregateValues; */ | 158 | Reduce(const QByteArray &reductionProperty, const QByteArray &selectionProperty, SelectionComparator comparator, FilterBase::Ptr source, DataStoreQuery *store) |
159 | : FilterBase(source, store), | ||
160 | mReductionProperty(reductionProperty), | ||
161 | mSelectionProperty(selectionProperty), | ||
162 | mSelectionComparator(comparator) | ||
163 | { | ||
149 | 164 | ||
150 | /* Reduction(FilterBase::Ptr source, DataStoreQuery *store) */ | 165 | } |
151 | /* : FilterBase(source, store) */ | ||
152 | /* { */ | ||
153 | 166 | ||
154 | /* } */ | 167 | virtual ~Reduce(){} |
155 | 168 | ||
156 | /* virtual ~Reduction(){} */ | 169 | static QByteArray getByteArray(const QVariant &value) |
157 | 170 | { | |
158 | /* bool next(const std::function<void(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> &callback) Q_DECL_OVERRIDE { */ | 171 | if (value.type() == QVariant::DateTime) { |
159 | /* bool foundValue = false; */ | 172 | return value.toDateTime().toString().toLatin1(); |
160 | /* while(!foundValue && mSource->next([this, callback, &foundValue](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { */ | 173 | } |
161 | /* const auto operation = entityBuffer.operation(); */ | 174 | if (value.isValid() && !value.toByteArray().isEmpty()) { |
162 | /* SinkTrace() << "Filter: " << uid << operation; */ | 175 | return value.toByteArray(); |
163 | /* //Always accept removals. They can't match the filter since the data is gone. */ | 176 | } |
164 | /* if (operation == Sink::Operation_Removal) { */ | 177 | return QByteArray(); |
165 | /* callback(uid, entityBuffer); */ | 178 | } |
166 | /* foundValue = true; */ | ||
167 | /* } else if (matchesFilter(uid, entityBuffer)) { */ | ||
168 | /* callback(uid, entityBuffer); */ | ||
169 | /* foundValue = true; */ | ||
170 | /* } */ | ||
171 | /* return false; */ | ||
172 | /* })) */ | ||
173 | /* {} */ | ||
174 | /* return foundValue; */ | ||
175 | /* } */ | ||
176 | 179 | ||
177 | /* bool matchesFilter(const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { */ | 180 | static bool compare(const QVariant &left, const QVariant &right, SelectionComparator comparator) |
178 | /* for (const auto &filterProperty : propertyFilter.keys()) { */ | 181 | { |
179 | /* const auto property = getProperty(entityBuffer.entity(), filterProperty); */ | 182 | if (comparator == Max) { |
180 | /* const auto comparator = propertyFilter.value(filterProperty); */ | 183 | return left > right; |
181 | /* if (!comparator.matches(property)) { */ | 184 | } |
182 | /* SinkTrace() << "Filtering entity due to property mismatch on filter: " << filterProperty << property << ":" << comparator.value; */ | 185 | return false; |
183 | /* return false; */ | 186 | } |
184 | /* } */ | 187 | |
185 | /* } */ | 188 | bool next(const std::function<void(Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> &callback) Q_DECL_OVERRIDE { |
186 | /* return true; */ | 189 | bool foundValue = false; |
187 | /* } */ | 190 | while(!foundValue && mSource->next([this, callback, &foundValue](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { |
188 | /* }; */ | 191 | auto reductionValue = getProperty(entityBuffer.entity(), mReductionProperty); |
192 | if (!mAggregateValues.contains(getByteArray(reductionValue))) { | ||
193 | QVariant selectionResultValue; | ||
194 | QByteArray selectionResult; | ||
195 | auto results = indexLookup(mReductionProperty, reductionValue); | ||
196 | for (const auto r : results) { | ||
197 | readEntity(r, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | ||
198 | auto selectionValue = getProperty(entityBuffer.entity(), mSelectionProperty); | ||
199 | if (!selectionResultValue.isValid() || compare(selectionValue, selectionResultValue, mSelectionComparator)) { | ||
200 | selectionResultValue = selectionValue; | ||
201 | selectionResult = uid; | ||
202 | } | ||
203 | }); | ||
204 | } | ||
205 | readEntity(selectionResult, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | ||
206 | callback(Sink::Operation_Creation, uid, entityBuffer); | ||
207 | foundValue = true; | ||
208 | }); | ||
209 | } | ||
210 | return false; | ||
211 | })) | ||
212 | {} | ||
213 | return foundValue; | ||
214 | } | ||
215 | }; | ||
189 | 216 | ||
190 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) | 217 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) |
191 | : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) | 218 | : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) |
@@ -230,6 +257,11 @@ QVariant DataStoreQuery::getProperty(const Sink::Entity &entity, const QByteArra | |||
230 | return mGetProperty(entity, property); | 257 | return mGetProperty(entity, property); |
231 | } | 258 | } |
232 | 259 | ||
260 | QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, const QVariant &value) | ||
261 | { | ||
262 | return mTypeIndex.lookup(property, value, mTransaction); | ||
263 | } | ||
264 | |||
233 | /* ResultSet DataStoreQuery::filterAndSortSet(ResultSet &resultSet, const FilterFunction &filter, const QByteArray &sortProperty) */ | 265 | /* ResultSet DataStoreQuery::filterAndSortSet(ResultSet &resultSet, const FilterFunction &filter, const QByteArray &sortProperty) */ |
234 | /* { */ | 266 | /* { */ |
235 | /* const bool sortingRequired = !sortProperty.isEmpty(); */ | 267 | /* const bool sortingRequired = !sortProperty.isEmpty(); */ |
@@ -347,11 +379,10 @@ void DataStoreQuery::setupQuery() | |||
347 | /* baseSet = Sort::Ptr::create(baseSet, mQuery.sortProperty); */ | 379 | /* baseSet = Sort::Ptr::create(baseSet, mQuery.sortProperty); */ |
348 | /* } */ | 380 | /* } */ |
349 | 381 | ||
350 | /* if (mQuery.threadLeaderOnly) { */ | 382 | if (mQuery.threadLeaderOnly) { |
351 | /* auto reduce = Reduce::Ptr::create(baseSet, this); */ | 383 | auto reduce = Reduce::Ptr::create("threadId", "date", Reduce::Max, baseSet, this); |
352 | 384 | baseSet = reduce; | |
353 | /* baseSet = reduce; */ | 385 | } |
354 | /* } */ | ||
355 | 386 | ||
356 | mCollector = Collector::Ptr::create(baseSet, this); | 387 | mCollector = Collector::Ptr::create(baseSet, this); |
357 | } | 388 | } |