diff options
Diffstat (limited to 'common/domain/mail.cpp')
-rw-r--r-- | common/domain/mail.cpp | 80 |
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 | ||
121 | static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 125 | static 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 | ||
161 | void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) | 167 | void 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 | ||
215 | DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) | 221 | DataStoreQuery::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 | ||