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.cpp117
1 files changed, 102 insertions, 15 deletions
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp
index bb5ad58..859ebef 100644
--- a/common/domain/mail.cpp
+++ b/common/domain/mail.cpp
@@ -41,6 +41,7 @@ SINK_DEBUG_AREA("mail");
41 41
42static QMutex sMutex; 42static QMutex sMutex;
43 43
44using namespace Sink;
44using namespace Sink::ApplicationDomain; 45using namespace Sink::ApplicationDomain;
45 46
46static TypeIndex &getIndex() 47static TypeIndex &getIndex()
@@ -49,26 +50,54 @@ static TypeIndex &getIndex()
49 static TypeIndex *index = 0; 50 static TypeIndex *index = 0;
50 if (!index) { 51 if (!index) {
51 index = new TypeIndex("mail"); 52 index = new TypeIndex("mail");
52 index->addProperty<QByteArray>("uid"); 53 index->addProperty<QByteArray>(Mail::Uid::name);
53 index->addProperty<QByteArray>("sender"); 54 index->addProperty<QByteArray>(Mail::Sender::name);
54 index->addProperty<QByteArray>("senderName"); 55 index->addProperty<QByteArray>(Mail::SenderName::name);
55 index->addProperty<QString>("subject"); 56 index->addProperty<QString>(Mail::Subject::name);
56 index->addProperty<QDateTime>("date"); 57 index->addProperty<QDateTime>(Mail::Date::name);
57 index->addProperty<QByteArray>("folder"); 58 index->addProperty<QByteArray>(Mail::Folder::name);
58 index->addPropertyWithSorting<QByteArray, QDateTime>("folder", "date"); 59 index->addPropertyWithSorting<QByteArray, QDateTime>(Mail::Folder::name, Mail::Date::name);
60 index->addProperty<QByteArray>(Mail::MessageId::name);
61 index->addProperty<QByteArray>(Mail::ParentMessageId::name);
59 } 62 }
60 return *index; 63 return *index;
61} 64}
62 65
63ResultSet TypeImplementation<Mail>::queryIndexes(const Sink::Query &query, const QByteArray &resourceInstanceIdentifier, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::Transaction &transaction) 66static void updateThreadingIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction)
64{ 67{
65 return getIndex().query(query, appliedFilters, appliedSorting, transaction); 68 auto messageId = bufferAdaptor.getProperty(Mail::MessageId::name).toByteArray();
69 auto parentMessageId = bufferAdaptor.getProperty(Mail::ParentMessageId::name).toByteArray();
70
71 Index msgIdIndex("msgId", transaction);
72 Index msgIdThreadIdIndex("msgIdThreadId", transaction);
73
74 //Add the message to the index
75 Q_ASSERT(msgIdIndex.lookup(messageId).isEmpty());
76 msgIdIndex.add(messageId, identifier);
77
78 //If parent is already available, add to thread of parent
79 QByteArray thread;
80 if (!parentMessageId.isEmpty() && !msgIdIndex.lookup(parentMessageId).isEmpty()) {
81 thread = msgIdThreadIdIndex.lookup(parentMessageId);
82 msgIdThreadIdIndex.add(messageId, thread);
83 } else {
84 thread = QUuid::createUuid().toByteArray();
85 if (!parentMessageId.isEmpty()) {
86 //Register parent with thread for when it becomes available
87 msgIdThreadIdIndex.add(parentMessageId, thread);
88 }
89 }
90 Q_ASSERT(!thread.isEmpty());
91 msgIdThreadIdIndex.add(messageId, thread);
92
93 //Look for parentMessageId and resolve to local id if available
66} 94}
67 95
68void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) 96void TypeImplementation<Mail>::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction)
69{ 97{
70 SinkTrace() << "Indexing " << identifier; 98 SinkTrace() << "Indexing " << identifier;
71 getIndex().add(identifier, bufferAdaptor, transaction); 99 getIndex().add(identifier, bufferAdaptor, transaction);
100 updateThreadingIndex(identifier, bufferAdaptor, transaction);
72} 101}
73 102
74void TypeImplementation<Mail>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction) 103void TypeImplementation<Mail>::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Sink::Storage::Transaction &transaction)
@@ -91,6 +120,8 @@ QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplem
91 propertyMapper->addMapping<Mail::Draft, Buffer>(&Buffer::draft); 120 propertyMapper->addMapping<Mail::Draft, Buffer>(&Buffer::draft);
92 propertyMapper->addMapping<Mail::Trash, Buffer>(&Buffer::trash); 121 propertyMapper->addMapping<Mail::Trash, Buffer>(&Buffer::trash);
93 propertyMapper->addMapping<Mail::Sent, Buffer>(&Buffer::sent); 122 propertyMapper->addMapping<Mail::Sent, Buffer>(&Buffer::sent);
123 propertyMapper->addMapping<Mail::MessageId, Buffer>(&Buffer::messageId);
124 propertyMapper->addMapping<Mail::ParentMessageId, Buffer>(&Buffer::parentMessageId);
94 return propertyMapper; 125 return propertyMapper;
95} 126}
96 127
@@ -110,16 +141,72 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Mail>::BufferBuilder> > Ty
110 propertyMapper->addMapping<Mail::Draft>(&BufferBuilder::add_draft); 141 propertyMapper->addMapping<Mail::Draft>(&BufferBuilder::add_draft);
111 propertyMapper->addMapping<Mail::Trash>(&BufferBuilder::add_trash); 142 propertyMapper->addMapping<Mail::Trash>(&BufferBuilder::add_trash);
112 propertyMapper->addMapping<Mail::Sent>(&BufferBuilder::add_sent); 143 propertyMapper->addMapping<Mail::Sent>(&BufferBuilder::add_sent);
144 propertyMapper->addMapping<Mail::MessageId>(&BufferBuilder::add_messageId);
145 propertyMapper->addMapping<Mail::ParentMessageId>(&BufferBuilder::add_parentMessageId);
113 return propertyMapper; 146 return propertyMapper;
114} 147}
115 148
116DataStoreQuery TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction) 149class ThreadedDataStoreQuery : public DataStoreQuery
150{
151public:
152 typedef QSharedPointer<ThreadedDataStoreQuery> Ptr;
153 using DataStoreQuery::DataStoreQuery;
154
155protected:
156 ResultSet postSortFilter(ResultSet &resultSet) Q_DECL_OVERRIDE
157 {
158 auto query = mQuery;
159 if (query.threadLeaderOnly) {
160 auto rootCollection = QSharedPointer<QMap<QByteArray, QDateTime>>::create();
161 auto filter = [this, query, rootCollection](const QByteArray &uid, const Sink::EntityBuffer &entity) -> bool {
162 //TODO lookup thread
163 //if we got thread already in the result set compare dates and if newer replace
164 //else insert
165
166 const auto messageId = getProperty(entity.entity(), ApplicationDomain::Mail::MessageId::name).toByteArray();
167
168 Index msgIdIndex("msgId", mTransaction);
169 Index msgIdThreadIdIndex("msgIdThreadId", mTransaction);
170 auto thread = msgIdThreadIdIndex.lookup(messageId);
171 SinkTrace() << "MsgId: " << messageId << " Thread: " << thread << getProperty(entity.entity(), ApplicationDomain::Mail::Date::name).toDateTime();
172
173 if (rootCollection->contains(thread)) {
174 auto date = rootCollection->value(thread);
175 //The mail we have in our result already is newer, so we can ignore this one
176 if (date > getProperty(entity.entity(), ApplicationDomain::Mail::Date::name).toDateTime()) {
177 return false;
178 }
179 qWarning() << "############################################################################";
180 qWarning() << "Found a newer mail, remove the old one";
181 qWarning() << "############################################################################";
182 }
183 rootCollection->insert(thread, getProperty(entity.entity(), ApplicationDomain::Mail::Date::name).toDateTime());
184 return true;
185 };
186 return createFilteredSet(resultSet, filter);
187 } else {
188 return resultSet;
189 }
190 }
191};
192
193DataStoreQuery::Ptr TypeImplementation<Mail>::prepareQuery(const Sink::Query &query, Sink::Storage::Transaction &transaction)
117{ 194{
118 auto mapper = initializeReadPropertyMapper(); 195 if (query.threadLeaderOnly) {
119 return DataStoreQuery(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) { 196 auto mapper = initializeReadPropertyMapper();
197 return ThreadedDataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) {
198
199 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
200 return mapper->getProperty(property, localBuffer);
201 });
120 202
121 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local()); 203 } else {
122 return mapper->getProperty(property, localBuffer); 204 auto mapper = initializeReadPropertyMapper();
123 }); 205 return DataStoreQuery::Ptr::create(query, ApplicationDomain::getTypeName<Mail>(), transaction, getIndex(), [mapper](const Sink::Entity &entity, const QByteArray &property) {
206
207 const auto localBuffer = Sink::EntityBuffer::readBuffer<Buffer>(entity.local());
208 return mapper->getProperty(property, localBuffer);
209 });
210 }
124} 211}
125 212