summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/datastorequery.cpp37
-rw-r--r--common/query.h5
-rw-r--r--tests/mailthreadtest.cpp28
3 files changed, 65 insertions, 5 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 7c0fdea..f352b74 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -214,6 +214,39 @@ public:
214 } 214 }
215}; 215};
216 216
217class Bloom : public FilterBase {
218public:
219 typedef QSharedPointer<Bloom> Ptr;
220
221 QByteArray mBloomProperty;
222
223 Bloom(const QByteArray &bloomProperty, FilterBase::Ptr source, DataStoreQuery *store)
224 : FilterBase(source, store),
225 mBloomProperty(bloomProperty)
226 {
227
228 }
229
230 virtual ~Bloom(){}
231
232 bool next(const std::function<void(Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> &callback) Q_DECL_OVERRIDE {
233 bool foundValue = false;
234 while(!foundValue && mSource->next([this, callback, &foundValue](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) {
235 auto bloomValue = getProperty(entityBuffer.entity(), mBloomProperty);
236 auto results = indexLookup(mBloomProperty, bloomValue);
237 for (const auto r : results) {
238 readEntity(r, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) {
239 callback(Sink::Operation_Creation, uid, entityBuffer);
240 foundValue = true;
241 });
242 }
243 return false;
244 }))
245 {}
246 return foundValue;
247 }
248};
249
217DataStoreQuery::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) 250DataStoreQuery::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)
218 : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) 251 : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty)
219{ 252{
@@ -383,6 +416,10 @@ void DataStoreQuery::setupQuery()
383 auto reduce = Reduce::Ptr::create("threadId", "date", Reduce::Max, baseSet, this); 416 auto reduce = Reduce::Ptr::create("threadId", "date", Reduce::Max, baseSet, this);
384 baseSet = reduce; 417 baseSet = reduce;
385 } 418 }
419 if (mQuery.bloomThread) {
420 auto reduce = Bloom::Ptr::create("threadId", baseSet, this);
421 baseSet = reduce;
422 }
386 423
387 mCollector = Collector::Ptr::create(baseSet, this); 424 mCollector = Collector::Ptr::create(baseSet, this);
388} 425}
diff --git a/common/query.h b/common/query.h
index 0808432..1b909e5 100644
--- a/common/query.h
+++ b/common/query.h
@@ -195,13 +195,13 @@ public:
195 return *this; 195 return *this;
196 } 196 }
197 197
198 Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false) 198 Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false), bloomThread(false)
199 { 199 {
200 ids << value.identifier(); 200 ids << value.identifier();
201 resources << value.resourceInstanceIdentifier(); 201 resources << value.resourceInstanceIdentifier();
202 } 202 }
203 203
204 Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false) 204 Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false), bloomThread(false)
205 { 205 {
206 } 206 }
207 207
@@ -237,6 +237,7 @@ public:
237 bool liveQuery; 237 bool liveQuery;
238 bool synchronousQuery; 238 bool synchronousQuery;
239 bool threadLeaderOnly; 239 bool threadLeaderOnly;
240 bool bloomThread;
240}; 241};
241} 242}
242 243
diff --git a/tests/mailthreadtest.cpp b/tests/mailthreadtest.cpp
index a3df56b..89e5a85 100644
--- a/tests/mailthreadtest.cpp
+++ b/tests/mailthreadtest.cpp
@@ -133,6 +133,21 @@ void MailThreadTest::testIndexInMixedOrder()
133 query.sort<Mail::Date>(); 133 query.sort<Mail::Date>();
134 query.filter<Mail::Folder>(folder); 134 query.filter<Mail::Folder>(folder);
135 135
136 Mail threadLeader;
137
138 //Ensure we find the thread leader
139 {
140 auto job = Store::fetchAll<Mail>(query)
141 .syncThen<void, QList<Mail::Ptr>>([=, &threadLeader](const QList<Mail::Ptr> &mails) {
142 QCOMPARE(mails.size(), 1);
143 auto mail = *mails.first();
144 threadLeader = mail;
145 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
146 });
147 VERIFYEXEC(job);
148 }
149
150 //Ensure we find the thread leader still
136 { 151 {
137 auto job = Store::fetchAll<Mail>(query) 152 auto job = Store::fetchAll<Mail>(query)
138 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 153 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
@@ -149,17 +164,24 @@ void MailThreadTest::testIndexInMixedOrder()
149 mail.setFolder(folder); 164 mail.setFolder(folder);
150 VERIFYEXEC(Store::create(mail)); 165 VERIFYEXEC(Store::create(mail));
151 } 166 }
152
153 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 167 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
168
169 //Ensure the thread is complete
154 { 170 {
171 Sink::Query query;
172 query.resources << mResourceInstanceIdentifier;
173 query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>();
174 query.bloomThread = true;
175 query.sort<Mail::Date>();
176 query.ids << threadLeader.identifier();
177
155 auto job = Store::fetchAll<Mail>(query) 178 auto job = Store::fetchAll<Mail>(query)
156 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 179 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
157 QCOMPARE(mails.size(), 1); 180 QCOMPARE(mails.size(), 2);
158 auto mail = *mails.first(); 181 auto mail = *mails.first();
159 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1")); 182 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
160 }); 183 });
161 VERIFYEXEC(job); 184 VERIFYEXEC(job);
162 //TODO ensure we also find message 1 as part of thread.
163 } 185 }
164 186
165 /* VERIFYEXEC(Store::remove(mail)); */ 187 /* VERIFYEXEC(Store::remove(mail)); */