summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/datastorequery.cpp8
-rw-r--r--common/domain/applicationdomaintype.h1
-rw-r--r--common/query.h135
-rw-r--r--common/store.cpp24
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
248struct SINK_EXPORT Event : public Entity { 247struct 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 343private:
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 */
60static QMap<QByteArray, QByteArray> getResources(const Sink::Query &query, const QByteArray &type = QByteArray()) 60static 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
268KAsync::Job<void> Store::synchronize(const Sink::Query &query) 258KAsync::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)