diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/datastorequery.cpp | 8 | ||||
-rw-r--r-- | common/domain/applicationdomaintype.h | 1 | ||||
-rw-r--r-- | common/query.h | 135 | ||||
-rw-r--r-- | common/store.cpp | 24 |
4 files changed, 57 insertions, 111 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index 0cc30e5..7341675 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -409,9 +409,6 @@ void DataStoreQuery::setupQuery() | |||
409 | { | 409 | { |
410 | auto baseFilters = mQuery.getBaseFilters(); | 410 | auto baseFilters = mQuery.getBaseFilters(); |
411 | for (const auto &k : baseFilters.keys()) { | 411 | for (const auto &k : baseFilters.keys()) { |
412 | if (k == ApplicationDomain::Entity::Resource::name) { | ||
413 | continue; | ||
414 | } | ||
415 | const auto comparator = baseFilters.value(k); | 412 | const auto comparator = baseFilters.value(k); |
416 | if (comparator.value.canConvert<Query>()) { | 413 | if (comparator.value.canConvert<Query>()) { |
417 | SinkTrace() << "Executing subquery for property: " << k; | 414 | SinkTrace() << "Executing subquery for property: " << k; |
@@ -446,9 +443,6 @@ void DataStoreQuery::setupQuery() | |||
446 | auto filter = Filter::Ptr::create(baseSet, this); | 443 | auto filter = Filter::Ptr::create(baseSet, this); |
447 | //For incremental queries the remaining filters are not sufficient | 444 | //For incremental queries the remaining filters are not sufficient |
448 | for (const auto &f : mQuery.getBaseFilters().keys()) { | 445 | for (const auto &f : mQuery.getBaseFilters().keys()) { |
449 | if (f == ApplicationDomain::Entity::Resource::name) { | ||
450 | continue; | ||
451 | } | ||
452 | filter->propertyFilter.insert(f, mQuery.getFilter(f)); | 446 | filter->propertyFilter.insert(f, mQuery.getFilter(f)); |
453 | } | 447 | } |
454 | baseSet = filter; | 448 | baseSet = filter; |
@@ -459,7 +453,7 @@ void DataStoreQuery::setupQuery() | |||
459 | /* } */ | 453 | /* } */ |
460 | 454 | ||
461 | //Setup the rest of the filter stages on top of the base set | 455 | //Setup the rest of the filter stages on top of the base set |
462 | for (const auto &stage : mQuery.filterStages.mid(1)) { | 456 | for (const auto &stage : mQuery.getFilterStages()) { |
463 | if (auto filter = stage.dynamicCast<Query::Filter>()) { | 457 | if (auto filter = stage.dynamicCast<Query::Filter>()) { |
464 | auto f = Filter::Ptr::create(baseSet, this); | 458 | auto f = Filter::Ptr::create(baseSet, this); |
465 | f->propertyFilter = filter->propertyFilter; | 459 | f->propertyFilter = filter->propertyFilter; |
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index 1c8b45a..7332bfb 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h | |||
@@ -242,7 +242,6 @@ struct SINK_EXPORT Entity : public ApplicationDomainType { | |||
242 | typedef QSharedPointer<Entity> Ptr; | 242 | typedef QSharedPointer<Entity> Ptr; |
243 | using ApplicationDomainType::ApplicationDomainType; | 243 | using ApplicationDomainType::ApplicationDomainType; |
244 | virtual ~Entity(); | 244 | virtual ~Entity(); |
245 | SINK_REFERENCE_PROPERTY(SinkResource, Resource, resource); | ||
246 | }; | 245 | }; |
247 | 246 | ||
248 | struct SINK_EXPORT Event : public Entity { | 247 | struct SINK_EXPORT Event : public Entity { |
diff --git a/common/query.h b/common/query.h index 82b04f7..ae307a2 100644 --- a/common/query.h +++ b/common/query.h | |||
@@ -59,46 +59,6 @@ public: | |||
59 | Comparators comparator; | 59 | Comparators comparator; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static Query ResourceFilter(const QByteArray &identifier) | ||
63 | { | ||
64 | Query query; | ||
65 | query.resources.append(identifier); | ||
66 | return query; | ||
67 | } | ||
68 | |||
69 | static Query ResourceFilter(const QByteArrayList &identifier) | ||
70 | { | ||
71 | Query query; | ||
72 | query.resources = identifier; | ||
73 | return query; | ||
74 | } | ||
75 | |||
76 | static Query ResourceFilter(const ApplicationDomain::SinkResource &entity) | ||
77 | { | ||
78 | return ResourceFilter(entity.identifier()); | ||
79 | } | ||
80 | |||
81 | static Query IdentityFilter(const QByteArray &identifier) | ||
82 | { | ||
83 | Q_ASSERT(!identifier.isEmpty()); | ||
84 | Query query; | ||
85 | query.filter(identifier); | ||
86 | return query; | ||
87 | } | ||
88 | |||
89 | static Query IdentityFilter(const QByteArrayList &identifier) | ||
90 | { | ||
91 | Query query; | ||
92 | query.filter(identifier); | ||
93 | return query; | ||
94 | } | ||
95 | |||
96 | static Query IdentityFilter(const ApplicationDomain::Entity &entity) | ||
97 | { | ||
98 | auto query = IdentityFilter(entity.identifier()); | ||
99 | query.resources << entity.resourceInstanceIdentifier(); | ||
100 | return query; | ||
101 | } | ||
102 | 62 | ||
103 | template <typename T> | 63 | template <typename T> |
104 | Query &request() | 64 | Query &request() |
@@ -124,16 +84,13 @@ public: | |||
124 | Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false) | 84 | Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false) |
125 | { | 85 | { |
126 | filter(value.identifier()); | 86 | filter(value.identifier()); |
127 | filter(ApplicationDomain::SinkResource(value.resourceInstanceIdentifier())); | 87 | resourceFilter(value.resourceInstanceIdentifier()); |
128 | } | 88 | } |
129 | 89 | ||
130 | |||
131 | Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false) | 90 | Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false) |
132 | { | 91 | { |
133 | } | 92 | } |
134 | 93 | ||
135 | QByteArrayList resources; | ||
136 | QByteArrayList accounts; | ||
137 | QByteArrayList requestedProperties; | 94 | QByteArrayList requestedProperties; |
138 | QByteArray parentProperty; | 95 | QByteArray parentProperty; |
139 | QByteArray sortProperty; | 96 | QByteArray sortProperty; |
@@ -147,7 +104,10 @@ public: | |||
147 | virtual ~FilterStage(){}; | 104 | virtual ~FilterStage(){}; |
148 | }; | 105 | }; |
149 | 106 | ||
150 | QList<QSharedPointer<FilterStage>> filterStages; | 107 | QList<QSharedPointer<FilterStage>> getFilterStages() |
108 | { | ||
109 | return mFilterStages; | ||
110 | } | ||
151 | 111 | ||
152 | /* | 112 | /* |
153 | * Filters | 113 | * Filters |
@@ -178,69 +138,45 @@ public: | |||
178 | 138 | ||
179 | Query &filter(const QByteArray &id) | 139 | Query &filter(const QByteArray &id) |
180 | { | 140 | { |
181 | if (filterStages.isEmpty()) { | 141 | mBaseFilterStage.ids << id; |
182 | filterStages << QSharedPointer<Filter>::create(); | ||
183 | } | ||
184 | filterStages.first().staticCast<Filter>()->ids << id; | ||
185 | return *this; | 142 | return *this; |
186 | } | 143 | } |
187 | 144 | ||
188 | Query &filter(const QByteArrayList &ids) | 145 | Query &filter(const QByteArrayList &ids) |
189 | { | 146 | { |
190 | if (filterStages.isEmpty()) { | 147 | mBaseFilterStage.ids << ids; |
191 | filterStages << QSharedPointer<Filter>::create(); | ||
192 | } | ||
193 | filterStages.first().staticCast<Filter>()->ids << ids; | ||
194 | return *this; | 148 | return *this; |
195 | } | 149 | } |
196 | 150 | ||
197 | Query &filter(const QByteArray &property, const Comparator &comparator) | 151 | Query &filter(const QByteArray &property, const Comparator &comparator) |
198 | { | 152 | { |
199 | if (filterStages.isEmpty()) { | 153 | mBaseFilterStage.propertyFilter.insert(property, comparator); |
200 | filterStages << QSharedPointer<Filter>::create(); | ||
201 | } | ||
202 | filterStages.first().staticCast<Filter>()->propertyFilter.insert(property, comparator); | ||
203 | return *this; | 154 | return *this; |
204 | } | 155 | } |
205 | 156 | ||
206 | Comparator getFilter(const QByteArray &property) const | 157 | Comparator getFilter(const QByteArray &property) const |
207 | { | 158 | { |
208 | if (filterStages.isEmpty()) { | 159 | return mBaseFilterStage.propertyFilter.value(property); |
209 | return Comparator(); | ||
210 | } | ||
211 | return filterStages.first().staticCast<Filter>()->propertyFilter.value(property); | ||
212 | } | 160 | } |
213 | 161 | ||
214 | bool hasFilter(const QByteArray &property) const | 162 | bool hasFilter(const QByteArray &property) const |
215 | { | 163 | { |
216 | if (filterStages.isEmpty()) { | 164 | return mBaseFilterStage.propertyFilter.contains(property); |
217 | return false; | ||
218 | } | ||
219 | return filterStages.first().staticCast<Filter>()->propertyFilter.contains(property); | ||
220 | } | 165 | } |
221 | 166 | ||
222 | void setBaseFilters(const QHash<QByteArray, Comparator> &filter) | 167 | void setBaseFilters(const QHash<QByteArray, Comparator> &filter) |
223 | { | 168 | { |
224 | if (filterStages.isEmpty()) { | 169 | mBaseFilterStage.propertyFilter = filter; |
225 | filterStages << QSharedPointer<Filter>::create(); | ||
226 | } | ||
227 | filterStages.first().staticCast<Filter>()->propertyFilter = filter; | ||
228 | } | 170 | } |
229 | 171 | ||
230 | QHash<QByteArray, Comparator> getBaseFilters() const | 172 | QHash<QByteArray, Comparator> getBaseFilters() const |
231 | { | 173 | { |
232 | if (filterStages.isEmpty()) { | 174 | return mBaseFilterStage.propertyFilter; |
233 | return QHash<QByteArray, Comparator>(); | ||
234 | } | ||
235 | return filterStages.first().staticCast<Filter>()->propertyFilter; | ||
236 | } | 175 | } |
237 | 176 | ||
238 | QByteArrayList ids() const | 177 | QByteArrayList ids() const |
239 | { | 178 | { |
240 | if (filterStages.isEmpty()) { | 179 | return mBaseFilterStage.ids; |
241 | return QByteArrayList(); | ||
242 | } | ||
243 | return filterStages.first().staticCast<Filter>()->ids; | ||
244 | } | 180 | } |
245 | 181 | ||
246 | template <typename T> | 182 | template <typename T> |
@@ -257,18 +193,42 @@ public: | |||
257 | return filter(T::name, QVariant::fromValue(q)); | 193 | return filter(T::name, QVariant::fromValue(q)); |
258 | } | 194 | } |
259 | 195 | ||
260 | Query &filter(const ApplicationDomain::SinkResource &resource) | 196 | Filter getResourceFilter() const |
197 | { | ||
198 | return mResourceFilter; | ||
199 | } | ||
200 | |||
201 | Query &resourceFilter(const QByteArray &id) | ||
261 | { | 202 | { |
262 | resources << resource.identifier(); | 203 | mResourceFilter.ids << id; |
263 | return *this; | 204 | return *this; |
264 | } | 205 | } |
265 | 206 | ||
266 | Query &filter(const ApplicationDomain::SinkAccount &account) | 207 | template <typename T> |
208 | Query &resourceFilter(const ApplicationDomain::ApplicationDomainType &entity) | ||
267 | { | 209 | { |
268 | accounts << account.identifier(); | 210 | mResourceFilter.propertyFilter.insert(T::name, Comparator(entity.identifier())); |
269 | return *this; | 211 | return *this; |
270 | } | 212 | } |
271 | 213 | ||
214 | Query &resourceFilter(const QByteArray &name, const Comparator &comparator) | ||
215 | { | ||
216 | mResourceFilter.propertyFilter.insert(name, comparator); | ||
217 | return *this; | ||
218 | } | ||
219 | |||
220 | template <typename T> | ||
221 | Query &resourceContainsFilter(const QVariant &value) | ||
222 | { | ||
223 | return resourceFilter(T::name, Comparator(value, Comparator::Contains)); | ||
224 | } | ||
225 | |||
226 | template <typename T> | ||
227 | Query &resourceFilter(const QVariant &value) | ||
228 | { | ||
229 | return resourceFilter(T::name, value); | ||
230 | } | ||
231 | |||
272 | class Reduce : public FilterStage { | 232 | class Reduce : public FilterStage { |
273 | public: | 233 | public: |
274 | 234 | ||
@@ -318,7 +278,7 @@ public: | |||
318 | Reduce &reduce(const Reduce::Selector &s) | 278 | Reduce &reduce(const Reduce::Selector &s) |
319 | { | 279 | { |
320 | auto reduction = QSharedPointer<Reduce>::create(T::name, s); | 280 | auto reduction = QSharedPointer<Reduce>::create(T::name, s); |
321 | filterStages << reduction; | 281 | mFilterStages << reduction; |
322 | return *reduction; | 282 | return *reduction; |
323 | } | 283 | } |
324 | 284 | ||
@@ -345,7 +305,7 @@ public: | |||
345 | void bloom() | 305 | void bloom() |
346 | { | 306 | { |
347 | auto bloom = QSharedPointer<Bloom>::create(T::name); | 307 | auto bloom = QSharedPointer<Bloom>::create(T::name); |
348 | filterStages << bloom; | 308 | mFilterStages << bloom; |
349 | } | 309 | } |
350 | 310 | ||
351 | //Query fixtures | 311 | //Query fixtures |
@@ -357,7 +317,7 @@ public: | |||
357 | { | 317 | { |
358 | Sink::Query query; | 318 | Sink::Query query; |
359 | if (!mail.resourceInstanceIdentifier().isEmpty()) { | 319 | if (!mail.resourceInstanceIdentifier().isEmpty()) { |
360 | query.filter(ApplicationDomain::SinkResource(mail.resourceInstanceIdentifier())); | 320 | query.resourceFilter(mail.resourceInstanceIdentifier()); |
361 | } | 321 | } |
362 | query.filter(mail.identifier()); | 322 | query.filter(mail.identifier()); |
363 | query.sort<ApplicationDomain::Mail::Date>(); | 323 | query.sort<ApplicationDomain::Mail::Date>(); |
@@ -372,7 +332,7 @@ public: | |||
372 | { | 332 | { |
373 | Sink::Query query; | 333 | Sink::Query query; |
374 | if (!folder.resourceInstanceIdentifier().isEmpty()) { | 334 | if (!folder.resourceInstanceIdentifier().isEmpty()) { |
375 | query.filter(ApplicationDomain::SinkResource(folder.resourceInstanceIdentifier())); | 335 | query.resourceFilter(folder.resourceInstanceIdentifier()); |
376 | } | 336 | } |
377 | query.filter<ApplicationDomain::Mail::Folder>(folder); | 337 | query.filter<ApplicationDomain::Mail::Folder>(folder); |
378 | query.sort<ApplicationDomain::Mail::Date>(); | 338 | query.sort<ApplicationDomain::Mail::Date>(); |
@@ -380,7 +340,10 @@ public: | |||
380 | return query; | 340 | return query; |
381 | } | 341 | } |
382 | 342 | ||
383 | 343 | private: | |
344 | Filter mResourceFilter; | ||
345 | Filter mBaseFilterStage; | ||
346 | QList<QSharedPointer<FilterStage>> mFilterStages; | ||
384 | }; | 347 | }; |
385 | 348 | ||
386 | } | 349 | } |
diff --git a/common/store.cpp b/common/store.cpp index c015ef6..0ecdcd2 100644 --- a/common/store.cpp +++ b/common/store.cpp | |||
@@ -59,25 +59,15 @@ QString Store::getTemporaryFilePath() | |||
59 | */ | 59 | */ |
60 | static QMap<QByteArray, QByteArray> getResources(const Sink::Query &query, const QByteArray &type = QByteArray()) | 60 | static QMap<QByteArray, QByteArray> getResources(const Sink::Query &query, const QByteArray &type = QByteArray()) |
61 | { | 61 | { |
62 | const QList<QByteArray> resourceFilter = query.resources; | 62 | const QList<QByteArray> resourceFilter = query.getResourceFilter().ids; |
63 | const QList<QByteArray> accountFilter = query.accounts; | ||
64 | 63 | ||
65 | auto resourceComparator = query.getFilter(Sink::ApplicationDomain::Entity::Resource::name); | ||
66 | 64 | ||
67 | const auto filterResource = [&](const QByteArray &res) { | 65 | const auto filterResource = [&](const QByteArray &res) { |
68 | const auto configuration = ResourceConfig::getConfiguration(res); | 66 | const auto configuration = ResourceConfig::getConfiguration(res); |
69 | if (!accountFilter.isEmpty() && !accountFilter.contains(configuration.value(ApplicationDomain::SinkResource::Account::name).toByteArray())) { | 67 | for (const auto &filterProperty : query.getResourceFilter().propertyFilter.keys()) { |
70 | return true; | 68 | const auto filter = query.getResourceFilter().propertyFilter.value(filterProperty); |
71 | } | 69 | if (!filter.matches(configuration.value(filterProperty))) { |
72 | //Subquery for the resource | 70 | return true; |
73 | if (resourceComparator.value.canConvert<Query>()) { | ||
74 | const auto subquery = resourceComparator.value.value<Query>(); | ||
75 | const auto baseFilters = subquery.getBaseFilters(); | ||
76 | for (const auto &filterProperty : baseFilters.keys()) { | ||
77 | const auto filter = baseFilters.value(filterProperty); | ||
78 | if (!filter.matches(configuration.value(filterProperty))) { | ||
79 | return true; | ||
80 | } | ||
81 | } | 71 | } |
82 | } | 72 | } |
83 | return false; | 73 | return false; |
@@ -159,7 +149,7 @@ QSharedPointer<QAbstractItemModel> Store::loadModel(Query query) | |||
159 | auto aggregatingEmitter = AggregatingResultEmitter<typename DomainType::Ptr>::Ptr::create(); | 149 | auto aggregatingEmitter = AggregatingResultEmitter<typename DomainType::Ptr>::Ptr::create(); |
160 | model->setEmitter(aggregatingEmitter); | 150 | model->setEmitter(aggregatingEmitter); |
161 | 151 | ||
162 | if (query.liveQuery && query.resources.isEmpty() && !ApplicationDomain::isGlobalType(ApplicationDomain::getTypeName<DomainType>())) { | 152 | if (query.liveQuery && query.getResourceFilter().ids.isEmpty() && !ApplicationDomain::isGlobalType(ApplicationDomain::getTypeName<DomainType>())) { |
163 | SinkTrace() << "Listening for new resources"; | 153 | SinkTrace() << "Listening for new resources"; |
164 | auto facade = FacadeFactory::instance().getFacade<ApplicationDomain::SinkResource>("", ""); | 154 | auto facade = FacadeFactory::instance().getFacade<ApplicationDomain::SinkResource>("", ""); |
165 | Q_ASSERT(facade); | 155 | Q_ASSERT(facade); |
@@ -267,8 +257,8 @@ KAsync::Job<void> Store::removeDataFromDisk(const QByteArray &identifier) | |||
267 | 257 | ||
268 | KAsync::Job<void> Store::synchronize(const Sink::Query &query) | 258 | KAsync::Job<void> Store::synchronize(const Sink::Query &query) |
269 | { | 259 | { |
270 | SinkTrace() << "synchronize" << query.resources; | ||
271 | auto resources = getResources(query).keys(); | 260 | auto resources = getResources(query).keys(); |
261 | SinkTrace() << "synchronize" << resources; | ||
272 | //FIXME only necessary because each doesn't propagate errors | 262 | //FIXME only necessary because each doesn't propagate errors |
273 | auto errorFlag = new bool; | 263 | auto errorFlag = new bool; |
274 | return KAsync::value(resources) | 264 | return KAsync::value(resources) |