summaryrefslogtreecommitdiffstats
path: root/common/domain/mail.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/domain/mail.cpp')
-rw-r--r--common/domain/mail.cpp80
1 files changed, 47 insertions, 33 deletions
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp
index 483a2f2..2b6eb84 100644
--- a/common/domain/mail.cpp
+++ b/common/domain/mail.cpp
@@ -60,6 +60,10 @@ static TypeIndex &getIndex()
60 index->addPropertyWithSorting<QByteArray, QDateTime>(Mail::Folder::name, Mail::Date::name); 60 index->addPropertyWithSorting<QByteArray, QDateTime>(Mail::Folder::name, Mail::Date::name);
61 index->addProperty<QByteArray>(Mail::MessageId::name); 61 index->addProperty<QByteArray>(Mail::MessageId::name);
62 index->addProperty<QByteArray>(Mail::ParentMessageId::name); 62 index->addProperty<QByteArray>(Mail::ParentMessageId::name);
63
64 index->addProperty<Mail::MessageId>();
65 index->addSecondaryProperty<Mail::MessageId, Mail::ThreadId>();
66 index->addSecondaryProperty<Mail::ThreadId, Mail::MessageId>();
63 } 67 }
64 return *index; 68 return *index;
65} 69}
@@ -120,42 +124,44 @@ static QString stripOffPrefixes(const QString &subject)
120 124
121static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) 125static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction)
122{ 126{
123 auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name).toByteArray(); 127 auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name);
124 auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name).toByteArray(); 128 auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name);
125 auto subject = bufferAdaptor.getProperty(Mail::Subject::name).toString(); 129 auto subject = bufferAdaptor.getProperty(Mail::Subject::name);
126 130
127 Index msgIdIndex("msgId", transaction); 131 auto normalizedSubject = stripOffPrefixes(subject.toString()).toUtf8();
128 Index msgIdThreadIdIndex("msgIdThreadId", transaction);
129 Index subjectThreadIdIndex("subjectThreadId", transaction);
130 132
131 //Add the message to the index 133 QVector<QByteArray> thread;
132 Q_ASSERT(msgIdIndex.lookup(messageId).isEmpty());
133 msgIdIndex.add(messageId, identifier);
134 134
135 auto normalizedSubject = stripOffPrefixes(subject).toUtf8(); 135 //a child already registered our thread.
136 thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId, transaction);
136 137
137 QByteArray thread;
138 //If parent is already available, add to thread of parent 138 //If parent is already available, add to thread of parent
139 if (!parentMessageId.isEmpty() && !msgIdIndex.lookup(parentMessageId).isEmpty()) { 139 if (thread.isEmpty() && parentMessageId.isValid()) {
140 thread = msgIdThreadIdIndex.lookup(parentMessageId); 140 thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(parentMessageId, transaction);
141 msgIdThreadIdIndex.add(messageId, thread); 141 SinkTrace() << "Found parent";
142 subjectThreadIdIndex.add(normalizedSubject, thread); 142 }
143 } else { 143 if (thread.isEmpty()) {
144 //Try to lookup the thread by subject: 144 //Try to lookup the thread by subject:
145 thread = subjectThreadIdIndex.lookup(normalizedSubject); 145 thread = getIndex().secondaryLookup<Mail::Subject, Mail::ThreadId>(normalizedSubject, transaction);
146 if (!thread.isEmpty()) { 146 if (thread.isEmpty()) {
147 msgIdThreadIdIndex.add(messageId, thread); 147 SinkTrace() << "Created a new thread ";
148 thread << QUuid::createUuid().toByteArray();
148 } else { 149 } else {
149 thread = QUuid::createUuid().toByteArray();
150 subjectThreadIdIndex.add(normalizedSubject, thread);
151 if (!parentMessageId.isEmpty()) {
152 //Register parent with thread for when it becomes available
153 msgIdThreadIdIndex.add(parentMessageId, thread);
154 }
155 } 150 }
156 } 151 }
157 Q_ASSERT(!thread.isEmpty()); 152
158 msgIdThreadIdIndex.add(messageId, thread); 153 //We should have found the thread by now
154 if (!thread.isEmpty()) {
155 if (parentMessageId.isValid()) {
156 //Register parent with thread for when it becomes available
157 getIndex().index<Mail::MessageId, Mail::ThreadId>(parentMessageId, thread.first(), transaction);
158 }
159 getIndex().index<Mail::MessageId, Mail::ThreadId>(messageId, thread.first(), transaction);
160 getIndex().index<Mail::ThreadId, Mail::MessageId>(thread.first(), messageId, transaction);
161 getIndex().index<Mail::Subject, Mail::ThreadId>(normalizedSubject, thread.first(), transaction);
162 } else {
163 SinkWarning() << "Couldn't find a thread for: " << messageId;
164 }
159} 165}
160 166
161void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) 167void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction)
@@ -214,13 +220,21 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Mail>::BufferBuilder> > Ty
214 220
215DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) 221DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction)
216{ 222{
217 223 auto mapper = initializeReadPropertyMapper();
218 224 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper, &transaction](const Sink::Entity &entity, const QByteArray &property) -> QVariant {
219 auto mapper = initializeReadPropertyMapper(); 225 if (property == Mail::ThreadId::name) {
220 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) {
221
222 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); 226 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
227 Q_ASSERT(localBuffer);
228 auto messageId = mapper->getProperty(Mail::MessageId::name, localBuffer);
229 //This is an index property that we have too lookup
230 auto thread = getIndex().secondaryLookup<Mail::MessageId, Mail::ThreadId>(messageId, transaction);
231 Q_ASSERT(!thread.isEmpty());
232 return thread.first();
233 } else {
234 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
235 Q_ASSERT(localBuffer);
223 return mapper->getProperty(property, localBuffer); 236 return mapper->getProperty(property, localBuffer);
224 }); 237 }
238 });
225} 239}
226 240