diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-01-25 16:29:00 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-02-06 08:38:08 +0100 |
commit | 9b84aff4b68c3cef3328c85ac12418048b169cee (patch) | |
tree | 7014f685e6a8c850f0be7965e1e656d3de72a15d | |
parent | 0a0c197ed487c343675b62dff8456932c8d5ff7f (diff) | |
download | sink-9b84aff4b68c3cef3328c85ac12418048b169cee.tar.gz sink-9b84aff4b68c3cef3328c85ac12418048b169cee.zip |
Store all BLOB properties inline.
BLOB properties had a couple of intended purposes:
* Allow large payloads to be streamed directly to disk, and then be
handled by reference.
* Allow zero-copy handling.
* Keep the database values compact so we can avoid traversing large
BLOBS.
However, they came at the cost of code-complexity, and we lost all the
benefits of our storage layer, such as transactions.
Measurements showed, that for email (the intended primary usecase),
the overhead is hardly measurable, with most parts performing
better, or at least not worse. We additionally also gain file-system
independence, which may help on other platforms.
The biggest drawback is probably that large payloads need to be written
to disk twice, because of the synchronizer queue (once for the queue,
once for the actual data).
-rw-r--r-- | common/definitions.cpp | 2 | ||||
-rw-r--r-- | common/domain/applicationdomaintype.h | 3 | ||||
-rw-r--r-- | common/mailpreprocessor.cpp | 83 | ||||
-rw-r--r-- | common/mailpreprocessor.h | 2 | ||||
-rw-r--r-- | examples/maildirresource/facade.cpp | 7 | ||||
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 90 | ||||
-rw-r--r-- | tests/interresourcemovetest.cpp | 3 | ||||
-rw-r--r-- | tests/mailsynctest.cpp | 2 | ||||
-rw-r--r-- | tests/mailtest.cpp | 10 |
9 files changed, 86 insertions, 116 deletions
diff --git a/common/definitions.cpp b/common/definitions.cpp index 1f4c0cf..b22137a 100644 --- a/common/definitions.cpp +++ b/common/definitions.cpp | |||
@@ -90,5 +90,5 @@ QString Sink::resourceStorageLocation(const QByteArray &resourceInstanceIdentifi | |||
90 | 90 | ||
91 | qint64 Sink::latestDatabaseVersion() | 91 | qint64 Sink::latestDatabaseVersion() |
92 | { | 92 | { |
93 | return 0; | 93 | return 1; |
94 | } | 94 | } |
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index 77754c1..8a0daef 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h | |||
@@ -439,7 +439,8 @@ struct SINK_EXPORT Mail : public Entity { | |||
439 | SINK_PROPERTY(bool, Unread, unread); | 439 | SINK_PROPERTY(bool, Unread, unread); |
440 | SINK_PROPERTY(bool, Important, important); | 440 | SINK_PROPERTY(bool, Important, important); |
441 | SINK_REFERENCE_PROPERTY(Folder, Folder, folder); | 441 | SINK_REFERENCE_PROPERTY(Folder, Folder, folder); |
442 | SINK_BLOB_PROPERTY(MimeMessage, mimeMessage); | 442 | // SINK_BLOB_PROPERTY(MimeMessage, mimeMessage); |
443 | SINK_PROPERTY(QByteArray, MimeMessage, mimeMessage); | ||
443 | SINK_EXTRACTED_PROPERTY(bool, FullPayloadAvailable, fullPayloadAvailable); | 444 | SINK_EXTRACTED_PROPERTY(bool, FullPayloadAvailable, fullPayloadAvailable); |
444 | SINK_PROPERTY(bool, Draft, draft); | 445 | SINK_PROPERTY(bool, Draft, draft); |
445 | SINK_PROPERTY(bool, Trash, trash); | 446 | SINK_PROPERTY(bool, Trash, trash); |
diff --git a/common/mailpreprocessor.cpp b/common/mailpreprocessor.cpp index b1cb1d5..8f5a77d 100644 --- a/common/mailpreprocessor.cpp +++ b/common/mailpreprocessor.cpp | |||
@@ -29,65 +29,6 @@ | |||
29 | 29 | ||
30 | using namespace Sink; | 30 | using namespace Sink; |
31 | 31 | ||
32 | QString MailPropertyExtractor::getFilePathFromMimeMessagePath(const QString &s) const | ||
33 | { | ||
34 | return s; | ||
35 | } | ||
36 | |||
37 | struct MimeMessageReader { | ||
38 | MimeMessageReader(const QString &mimeMessagePath) | ||
39 | : f(mimeMessagePath), | ||
40 | mapped(0) | ||
41 | { | ||
42 | if (mimeMessagePath.isNull()) { | ||
43 | SinkTrace() << "No mime message"; | ||
44 | return; | ||
45 | } | ||
46 | SinkTrace() << "Updating indexed properties " << mimeMessagePath; | ||
47 | if (!f.open(QIODevice::ReadOnly)) { | ||
48 | SinkWarning() << "Failed to open the file: " << mimeMessagePath; | ||
49 | return; | ||
50 | } | ||
51 | if (!f.size()) { | ||
52 | SinkWarning() << "The file is empty."; | ||
53 | return; | ||
54 | } | ||
55 | mapped = f.map(0, f.size()); | ||
56 | if (!mapped) { | ||
57 | SinkWarning() << "Failed to map the file: " << f.errorString(); | ||
58 | return; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | KMime::Message::Ptr mimeMessage() | ||
63 | { | ||
64 | if (!mapped) { | ||
65 | return {}; | ||
66 | } | ||
67 | QByteArray result; | ||
68 | //Seek for end of headers | ||
69 | const auto content = QByteArray::fromRawData(reinterpret_cast<const char*>(mapped), f.size()); | ||
70 | int pos = content.indexOf("\r\n\r\n", 0); | ||
71 | int offset = 2; | ||
72 | if (pos < 0) { | ||
73 | pos = content.indexOf("\n\n", 0); | ||
74 | offset = 1; | ||
75 | } | ||
76 | if (pos > -1) { | ||
77 | const auto header = content.left(pos + offset); //header *must* end with "\n" !! | ||
78 | auto msg = KMime::Message::Ptr(new KMime::Message); | ||
79 | msg->setHead(KMime::CRLFtoLF(header)); | ||
80 | msg->parse(); | ||
81 | return msg; | ||
82 | } | ||
83 | SinkWarning() << "Failed to find end of headers" << content; | ||
84 | return {}; | ||
85 | } | ||
86 | |||
87 | QFile f; | ||
88 | uchar *mapped; | ||
89 | }; | ||
90 | |||
91 | static Sink::ApplicationDomain::Mail::Contact getContact(const KMime::Headers::Generics::MailboxList *header) | 32 | static Sink::ApplicationDomain::Mail::Contact getContact(const KMime::Headers::Generics::MailboxList *header) |
92 | { | 33 | { |
93 | const auto name = header->displayNames().isEmpty() ? QString() : header->displayNames().first(); | 34 | const auto name = header->displayNames().isEmpty() ? QString() : header->displayNames().first(); |
@@ -104,8 +45,18 @@ static QList<Sink::ApplicationDomain::Mail::Contact> getContactList(const KMime: | |||
104 | return list; | 45 | return list; |
105 | } | 46 | } |
106 | 47 | ||
107 | static void updatedIndexedProperties(Sink::ApplicationDomain::Mail &mail, KMime::Message::Ptr msg) | 48 | void MailPropertyExtractor::updatedIndexedProperties(Sink::ApplicationDomain::Mail &mail, const QByteArray &data) |
108 | { | 49 | { |
50 | if (data.isEmpty()) { | ||
51 | return; | ||
52 | } | ||
53 | auto msg = KMime::Message::Ptr(new KMime::Message); | ||
54 | msg->setHead(KMime::CRLFtoLF(data)); | ||
55 | msg->parse(); | ||
56 | if (!msg) { | ||
57 | return; | ||
58 | } | ||
59 | |||
109 | mail.setExtractedSubject(msg->subject(true)->asUnicodeString()); | 60 | mail.setExtractedSubject(msg->subject(true)->asUnicodeString()); |
110 | mail.setExtractedSender(getContact(msg->from(true))); | 61 | mail.setExtractedSender(getContact(msg->from(true))); |
111 | mail.setExtractedTo(getContactList(msg->to(true))); | 62 | mail.setExtractedTo(getContactList(msg->to(true))); |
@@ -156,19 +107,11 @@ static void updatedIndexedProperties(Sink::ApplicationDomain::Mail &mail, KMime: | |||
156 | 107 | ||
157 | void MailPropertyExtractor::newEntity(Sink::ApplicationDomain::Mail &mail) | 108 | void MailPropertyExtractor::newEntity(Sink::ApplicationDomain::Mail &mail) |
158 | { | 109 | { |
159 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(mail.getMimeMessagePath())); | 110 | updatedIndexedProperties(mail, mail.getMimeMessage()); |
160 | auto msg = mimeMessageReader.mimeMessage(); | ||
161 | if (msg) { | ||
162 | updatedIndexedProperties(mail, msg); | ||
163 | } | ||
164 | } | 111 | } |
165 | 112 | ||
166 | void MailPropertyExtractor::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail) | 113 | void MailPropertyExtractor::modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail) |
167 | { | 114 | { |
168 | MimeMessageReader mimeMessageReader(getFilePathFromMimeMessagePath(newMail.getMimeMessagePath())); | 115 | updatedIndexedProperties(newMail, newMail.getMimeMessage()); |
169 | auto msg = mimeMessageReader.mimeMessage(); | ||
170 | if (msg) { | ||
171 | updatedIndexedProperties(newMail, msg); | ||
172 | } | ||
173 | } | 116 | } |
174 | 117 | ||
diff --git a/common/mailpreprocessor.h b/common/mailpreprocessor.h index a24a8d3..d2e79ca 100644 --- a/common/mailpreprocessor.h +++ b/common/mailpreprocessor.h | |||
@@ -27,6 +27,6 @@ public: | |||
27 | virtual void newEntity(Sink::ApplicationDomain::Mail &mail) Q_DECL_OVERRIDE; | 27 | virtual void newEntity(Sink::ApplicationDomain::Mail &mail) Q_DECL_OVERRIDE; |
28 | virtual void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail) Q_DECL_OVERRIDE; | 28 | virtual void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail) Q_DECL_OVERRIDE; |
29 | protected: | 29 | protected: |
30 | virtual QString getFilePathFromMimeMessagePath(const QString &) const; | 30 | static void updatedIndexedProperties(Sink::ApplicationDomain::Mail &mail, const QByteArray &data); |
31 | }; | 31 | }; |
32 | 32 | ||
diff --git a/examples/maildirresource/facade.cpp b/examples/maildirresource/facade.cpp index 5ea3d98..ea02968 100644 --- a/examples/maildirresource/facade.cpp +++ b/examples/maildirresource/facade.cpp | |||
@@ -31,7 +31,7 @@ MaildirResourceMailFacade::MaildirResourceMailFacade(const Sink::ResourceContext | |||
31 | Sink::Log::Context ctx{"maildirfacade"}; | 31 | Sink::Log::Context ctx{"maildirfacade"}; |
32 | if (value.hasProperty(Sink::ApplicationDomain::Mail::MimeMessage::name)) { | 32 | if (value.hasProperty(Sink::ApplicationDomain::Mail::MimeMessage::name)) { |
33 | auto mail = Sink::ApplicationDomain::Mail{value}; | 33 | auto mail = Sink::ApplicationDomain::Mail{value}; |
34 | const auto mimeMessage = mail.getMimeMessagePath(); | 34 | const auto mimeMessage = mail.getMimeMessage(); |
35 | //Transform the mime message property into the actual path on disk. | 35 | //Transform the mime message property into the actual path on disk. |
36 | auto parts = mimeMessage.split('/'); | 36 | auto parts = mimeMessage.split('/'); |
37 | auto key = parts.takeLast(); | 37 | auto key = parts.takeLast(); |
@@ -45,7 +45,10 @@ MaildirResourceMailFacade::MaildirResourceMailFacade(const Sink::ResourceContext | |||
45 | SinkErrorCtx(ctx) << "Failed to find message. Directory: " << path << "Key: " << key << "Number of matching files: " << list.size(); | 45 | SinkErrorCtx(ctx) << "Failed to find message. Directory: " << path << "Key: " << key << "Number of matching files: " << list.size(); |
46 | mail.setProperty(Sink::ApplicationDomain::Mail::MimeMessage::name, QVariant()); | 46 | mail.setProperty(Sink::ApplicationDomain::Mail::MimeMessage::name, QVariant()); |
47 | } else { | 47 | } else { |
48 | mail.setMimeMessagePath(list.at(0).filePath()); | 48 | QFile file{list.at(0).filePath()}; |
49 | if (file.open(QIODevice::ReadOnly)) { | ||
50 | mail.setMimeMessage(file.readAll()); | ||
51 | } | ||
49 | } | 52 | } |
50 | } | 53 | } |
51 | value.setChangedProperties(QSet<QByteArray>()); | 54 | value.setChangedProperties(QSet<QByteArray>()); |
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 735665a..4c94d1d 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -54,8 +54,7 @@ static QString getFilePathFromMimeMessagePath(const QString &mimeMessagePath) | |||
54 | QDir dir(path); | 54 | QDir dir(path); |
55 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); | 55 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); |
56 | if (list.size() != 1) { | 56 | if (list.size() != 1) { |
57 | SinkWarning() << "Failed to find message " << mimeMessagePath; | 57 | SinkWarning() << "Failed to find message. Property value:" << mimeMessagePath << "Assembled path: " << path; |
58 | SinkWarning() << "Failed to find message " << path; | ||
59 | return QString(); | 58 | return QString(); |
60 | } | 59 | } |
61 | return list.first().filePath(); | 60 | return list.first().filePath(); |
@@ -63,10 +62,25 @@ static QString getFilePathFromMimeMessagePath(const QString &mimeMessagePath) | |||
63 | 62 | ||
64 | class MaildirMailPropertyExtractor : public MailPropertyExtractor | 63 | class MaildirMailPropertyExtractor : public MailPropertyExtractor |
65 | { | 64 | { |
65 | void update(Sink::ApplicationDomain::Mail &mail) | ||
66 | { | ||
67 | QFile file{::getFilePathFromMimeMessagePath(mail.getMimeMessage())}; | ||
68 | if (file.open(QIODevice::ReadOnly)) { | ||
69 | updatedIndexedProperties(mail, file.readAll()); | ||
70 | } else { | ||
71 | SinkWarning() << "Failed to open file message " << mail.getMimeMessage(); | ||
72 | } | ||
73 | } | ||
74 | |||
66 | protected: | 75 | protected: |
67 | virtual QString getFilePathFromMimeMessagePath(const QString &mimeMessagePath) const Q_DECL_OVERRIDE | 76 | void newEntity(Sink::ApplicationDomain::Mail &mail) Q_DECL_OVERRIDE |
68 | { | 77 | { |
69 | return ::getFilePathFromMimeMessagePath(mimeMessagePath); | 78 | update(mail); |
79 | } | ||
80 | |||
81 | void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail) Q_DECL_OVERRIDE | ||
82 | { | ||
83 | update(newMail); | ||
70 | } | 84 | } |
71 | }; | 85 | }; |
72 | 86 | ||
@@ -92,6 +106,18 @@ public: | |||
92 | return folderPath; | 106 | return folderPath; |
93 | } | 107 | } |
94 | 108 | ||
109 | QString storeMessage(const QByteArray &data, const QByteArray &folder) | ||
110 | { | ||
111 | const auto path = getPath(folder); | ||
112 | KPIM::Maildir maildir(path, false); | ||
113 | if (!maildir.isValid(true)) { | ||
114 | SinkWarning() << "Maildir is not existing: " << path; | ||
115 | } | ||
116 | SinkWarning() << "Storing message: " << data; | ||
117 | auto identifier = maildir.addEntry(data); | ||
118 | return path + "/" + identifier; | ||
119 | } | ||
120 | |||
95 | QString moveMessage(const QString &oldPath, const QByteArray &folder) | 121 | QString moveMessage(const QString &oldPath, const QByteArray &folder) |
96 | { | 122 | { |
97 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { | 123 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { |
@@ -125,15 +151,21 @@ public: | |||
125 | } | 151 | } |
126 | } | 152 | } |
127 | 153 | ||
154 | bool isPath(const QByteArray &data) | ||
155 | { | ||
156 | return data.startsWith('/'); | ||
157 | } | ||
158 | |||
128 | void newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE | 159 | void newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE |
129 | { | 160 | { |
130 | auto mail = newEntity.cast<ApplicationDomain::Mail>(); | 161 | auto mail = newEntity.cast<ApplicationDomain::Mail>(); |
131 | const auto mimeMessage = mail.getMimeMessagePath(); | 162 | const auto mimeMessage = mail.getMimeMessage(); |
132 | if (!mimeMessage.isNull()) { | 163 | if (!mimeMessage.isNull()) { |
133 | const auto path = moveMessage(mimeMessage, mail.getFolder()); | 164 | if (isPath(mimeMessage)) { |
134 | auto blob = ApplicationDomain::BLOB{path}; | 165 | mail.setMimeMessage(moveMessage(mimeMessage, mail.getFolder()).toUtf8()); |
135 | blob.isExternal = false; | 166 | } else { |
136 | mail.setProperty(ApplicationDomain::Mail::MimeMessage::name, QVariant::fromValue(blob)); | 167 | mail.setMimeMessage(storeMessage(mimeMessage, mail.getFolder()).toUtf8()); |
168 | } | ||
137 | } | 169 | } |
138 | } | 170 | } |
139 | 171 | ||
@@ -141,28 +173,28 @@ public: | |||
141 | { | 173 | { |
142 | auto newMail = newEntity.cast<ApplicationDomain::Mail>(); | 174 | auto newMail = newEntity.cast<ApplicationDomain::Mail>(); |
143 | const ApplicationDomain::Mail oldMail{oldEntity}; | 175 | const ApplicationDomain::Mail oldMail{oldEntity}; |
144 | const auto mimeMessage = newMail.getMimeMessagePath(); | ||
145 | const auto newFolder = newMail.getFolder(); | 176 | const auto newFolder = newMail.getFolder(); |
146 | const bool mimeMessageChanged = !mimeMessage.isNull() && mimeMessage != oldMail.getMimeMessagePath(); | ||
147 | const bool folderChanged = !newFolder.isNull() && newFolder != oldMail.getFolder(); | 177 | const bool folderChanged = !newFolder.isNull() && newFolder != oldMail.getFolder(); |
148 | if (mimeMessageChanged || folderChanged) { | 178 | if (!newMail.getMimeMessage().isNull() || folderChanged) { |
149 | SinkTrace() << "Moving mime message: " << mimeMessageChanged << folderChanged; | 179 | const auto data = newMail.getMimeMessage(); |
150 | auto newPath = moveMessage(mimeMessage, newMail.getFolder()); | 180 | if (isPath(data)) { |
151 | if (newPath != oldMail.getMimeMessagePath()) { | 181 | auto newPath = moveMessage(data, newMail.getFolder()); |
152 | const auto oldPath = getFilePathFromMimeMessagePath(oldMail.getMimeMessagePath()); | 182 | if (newPath != oldMail.getMimeMessage()) { |
153 | auto blob = ApplicationDomain::BLOB{newPath}; | 183 | newMail.setMimeMessage(newPath.toUtf8()); |
154 | blob.isExternal = false; | 184 | //Remove the olde mime message if there is a new one |
155 | newMail.setProperty(ApplicationDomain::Mail::MimeMessage::name, QVariant::fromValue(blob)); | 185 | QFile::remove(getFilePathFromMimeMessagePath(oldMail.getMimeMessage())); |
186 | } | ||
187 | } else { | ||
188 | newMail.setMimeMessage(storeMessage(data, newMail.getFolder()).toUtf8()); | ||
156 | //Remove the olde mime message if there is a new one | 189 | //Remove the olde mime message if there is a new one |
157 | QFile::remove(oldPath); | 190 | QFile::remove(getFilePathFromMimeMessagePath(oldMail.getMimeMessage())); |
158 | } | 191 | } |
159 | } | 192 | } |
160 | 193 | ||
161 | auto mimeMessagePath = newMail.getMimeMessagePath(); | 194 | auto mimeMessagePath = newMail.getMimeMessage(); |
162 | const auto maildirPath = getPath(newMail.getFolder()); | 195 | const auto maildirPath = getPath(newMail.getFolder()); |
163 | KPIM::Maildir maildir(maildirPath, false); | 196 | KPIM::Maildir maildir(maildirPath, false); |
164 | const auto file = getFilePathFromMimeMessagePath(mimeMessagePath); | 197 | QString identifier = KPIM::Maildir::getKeyFromFile(getFilePathFromMimeMessagePath(mimeMessagePath)); |
165 | QString identifier = KPIM::Maildir::getKeyFromFile(file); | ||
166 | 198 | ||
167 | //get flags from | 199 | //get flags from |
168 | KPIM::Maildir::Flags flags; | 200 | KPIM::Maildir::Flags flags; |
@@ -179,7 +211,7 @@ public: | |||
179 | void deletedEntity(const Sink::ApplicationDomain::ApplicationDomainType &oldEntity) Q_DECL_OVERRIDE | 211 | void deletedEntity(const Sink::ApplicationDomain::ApplicationDomainType &oldEntity) Q_DECL_OVERRIDE |
180 | { | 212 | { |
181 | const ApplicationDomain::Mail oldMail{oldEntity}; | 213 | const ApplicationDomain::Mail oldMail{oldEntity}; |
182 | const auto filePath = getFilePathFromMimeMessagePath(oldMail.getMimeMessagePath()); | 214 | const auto filePath = getFilePathFromMimeMessagePath(oldMail.getMimeMessage()); |
183 | QFile::remove(filePath); | 215 | QFile::remove(filePath); |
184 | } | 216 | } |
185 | QByteArray mResourceInstanceIdentifier; | 217 | QByteArray mResourceInstanceIdentifier; |
@@ -327,9 +359,7 @@ public: | |||
327 | mail.setFolder(folderLocalId); | 359 | mail.setFolder(folderLocalId); |
328 | //We only store the directory path + key, so we facade can add the changing bits (flags) | 360 | //We only store the directory path + key, so we facade can add the changing bits (flags) |
329 | auto path = KPIM::Maildir::getDirectoryFromFile(filePath) + maildirKey; | 361 | auto path = KPIM::Maildir::getDirectoryFromFile(filePath) + maildirKey; |
330 | auto blob = ApplicationDomain::BLOB{path}; | 362 | mail.setMimeMessage(path.toUtf8()); |
331 | blob.isExternal = false; | ||
332 | mail.setProperty(ApplicationDomain::Mail::MimeMessage::name, QVariant::fromValue(blob)); | ||
333 | mail.setUnread(!flags.testFlag(KPIM::Maildir::Seen)); | 363 | mail.setUnread(!flags.testFlag(KPIM::Maildir::Seen)); |
334 | mail.setImportant(flags.testFlag(KPIM::Maildir::Flagged)); | 364 | mail.setImportant(flags.testFlag(KPIM::Maildir::Flagged)); |
335 | mail.setExtractedFullPayloadAvailable(true); | 365 | mail.setExtractedFullPayloadAvailable(true); |
@@ -396,7 +426,7 @@ public: | |||
396 | KAsync::Job<QByteArray> replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList<QByteArray> &changedProperties) Q_DECL_OVERRIDE | 426 | KAsync::Job<QByteArray> replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList<QByteArray> &changedProperties) Q_DECL_OVERRIDE |
397 | { | 427 | { |
398 | if (operation == Sink::Operation_Creation) { | 428 | if (operation == Sink::Operation_Creation) { |
399 | const auto remoteId = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | 429 | const auto remoteId = getFilePathFromMimeMessagePath(mail.getMimeMessage()); |
400 | SinkTrace() << "Mail created: " << remoteId; | 430 | SinkTrace() << "Mail created: " << remoteId; |
401 | return KAsync::value(remoteId.toUtf8()); | 431 | return KAsync::value(remoteId.toUtf8()); |
402 | } else if (operation == Sink::Operation_Removal) { | 432 | } else if (operation == Sink::Operation_Removal) { |
@@ -404,7 +434,7 @@ public: | |||
404 | return KAsync::null<QByteArray>(); | 434 | return KAsync::null<QByteArray>(); |
405 | } else if (operation == Sink::Operation_Modification) { | 435 | } else if (operation == Sink::Operation_Modification) { |
406 | SinkTrace() << "Modifying a mail: " << oldRemoteId; | 436 | SinkTrace() << "Modifying a mail: " << oldRemoteId; |
407 | const auto remoteId = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | 437 | const auto remoteId = getFilePathFromMimeMessagePath(mail.getMimeMessage()); |
408 | return KAsync::value(remoteId.toUtf8()); | 438 | return KAsync::value(remoteId.toUtf8()); |
409 | } | 439 | } |
410 | return KAsync::null<QByteArray>(); | 440 | return KAsync::null<QByteArray>(); |
@@ -460,7 +490,7 @@ protected: | |||
460 | 490 | ||
461 | if (domainType == ENTITY_TYPE_MAIL) { | 491 | if (domainType == ENTITY_TYPE_MAIL) { |
462 | auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); | 492 | auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); |
463 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); | 493 | const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessage()); |
464 | 494 | ||
465 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { | 495 | if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { |
466 | if (property == "unread") { | 496 | if (property == "unread") { |
diff --git a/tests/interresourcemovetest.cpp b/tests/interresourcemovetest.cpp index 174befc..37e040e 100644 --- a/tests/interresourcemovetest.cpp +++ b/tests/interresourcemovetest.cpp | |||
@@ -106,7 +106,6 @@ private slots: | |||
106 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); | 106 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); |
107 | QCOMPARE(list.size(), 1); | 107 | QCOMPARE(list.size(), 1); |
108 | const auto mail = list.first(); | 108 | const auto mail = list.first(); |
109 | QVERIFY(!mail.getMimeMessagePath().isEmpty()); | ||
110 | QCOMPARE(mail.getSubject(), subject); | 109 | QCOMPARE(mail.getSubject(), subject); |
111 | QCOMPARE(mail.getMimeMessage(), mimeMessage); | 110 | QCOMPARE(mail.getMimeMessage(), mimeMessage); |
112 | } | 111 | } |
@@ -153,7 +152,6 @@ private slots: | |||
153 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); | 152 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); |
154 | QCOMPARE(list.size(), 1); | 153 | QCOMPARE(list.size(), 1); |
155 | const auto mail = list.first(); | 154 | const auto mail = list.first(); |
156 | QVERIFY(!mail.getMimeMessagePath().isEmpty()); | ||
157 | QCOMPARE(mail.getSubject(), subject); | 155 | QCOMPARE(mail.getSubject(), subject); |
158 | QCOMPARE(mail.getMimeMessage(), mimeMessage); | 156 | QCOMPARE(mail.getMimeMessage(), mimeMessage); |
159 | } | 157 | } |
@@ -164,7 +162,6 @@ private slots: | |||
164 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); | 162 | auto list = Sink::Store::read<Mail>(query.filter<Mail::MessageId>(testuid)); |
165 | QCOMPARE(list.size(), 1); | 163 | QCOMPARE(list.size(), 1); |
166 | const auto mail = list.first(); | 164 | const auto mail = list.first(); |
167 | QVERIFY(!mail.getMimeMessagePath().isEmpty()); | ||
168 | QCOMPARE(mail.getSubject(), subject); | 165 | QCOMPARE(mail.getSubject(), subject); |
169 | QCOMPARE(mail.getMimeMessage(), mimeMessage); | 166 | QCOMPARE(mail.getMimeMessage(), mimeMessage); |
170 | } | 167 | } |
diff --git a/tests/mailsynctest.cpp b/tests/mailsynctest.cpp index 811eace..764b006 100644 --- a/tests/mailsynctest.cpp +++ b/tests/mailsynctest.cpp | |||
@@ -318,7 +318,7 @@ void MailSyncTest::testResyncMails() | |||
318 | ASYNCCOMPARE(mails.size(), 1); | 318 | ASYNCCOMPARE(mails.size(), 1); |
319 | auto mail = mails.first(); | 319 | auto mail = mails.first(); |
320 | ASYNCVERIFY(!mail->getSubject().isEmpty()); | 320 | ASYNCVERIFY(!mail->getSubject().isEmpty()); |
321 | ASYNCVERIFY(!mail->getMimeMessagePath().isEmpty()); | 321 | ASYNCVERIFY(!mail->getMimeMessage().isEmpty()); |
322 | return KAsync::null(); | 322 | return KAsync::null(); |
323 | }); | 323 | }); |
324 | VERIFYEXEC(job); | 324 | VERIFYEXEC(job); |
diff --git a/tests/mailtest.cpp b/tests/mailtest.cpp index 1c24268..88cacd2 100644 --- a/tests/mailtest.cpp +++ b/tests/mailtest.cpp | |||
@@ -164,7 +164,6 @@ void MailTest::testCreateModifyDeleteMail() | |||
164 | auto mail = *mails.first(); | 164 | auto mail = *mails.first(); |
165 | QCOMPARE(mail.getSubject(), subject); | 165 | QCOMPARE(mail.getSubject(), subject); |
166 | QCOMPARE(mail.getFolder(), folder.identifier()); | 166 | QCOMPARE(mail.getFolder(), folder.identifier()); |
167 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); | ||
168 | KMime::Message m; | 167 | KMime::Message m; |
169 | m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); | 168 | m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); |
170 | m.parse(); | 169 | m.parse(); |
@@ -193,7 +192,6 @@ void MailTest::testCreateModifyDeleteMail() | |||
193 | auto mail = *mails.first(); | 192 | auto mail = *mails.first(); |
194 | QCOMPARE(mail.getSubject(), subject2); | 193 | QCOMPARE(mail.getSubject(), subject2); |
195 | QCOMPARE(mail.getFolder(), folder.identifier()); | 194 | QCOMPARE(mail.getFolder(), folder.identifier()); |
196 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); | ||
197 | KMime::Message m; | 195 | KMime::Message m; |
198 | m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); | 196 | m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); |
199 | m.parse(); | 197 | m.parse(); |
@@ -251,8 +249,7 @@ void MailTest::testMoveMail() | |||
251 | auto mail = *mails.first(); | 249 | auto mail = *mails.first(); |
252 | modifiedMail = mail; | 250 | modifiedMail = mail; |
253 | QCOMPARE(mail.getFolder(), folder.identifier()); | 251 | QCOMPARE(mail.getFolder(), folder.identifier()); |
254 | SinkWarning() << "path: " << mail.getMimeMessagePath(); | 252 | QVERIFY(!mail.getMimeMessage().isEmpty()); |
255 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); | ||
256 | }); | 253 | }); |
257 | VERIFYEXEC(job); | 254 | VERIFYEXEC(job); |
258 | } | 255 | } |
@@ -269,8 +266,7 @@ void MailTest::testMoveMail() | |||
269 | QCOMPARE(mails.size(), 1); | 266 | QCOMPARE(mails.size(), 1); |
270 | auto mail = *mails.first(); | 267 | auto mail = *mails.first(); |
271 | QCOMPARE(mail.getFolder(), folder1.identifier()); | 268 | QCOMPARE(mail.getFolder(), folder1.identifier()); |
272 | QVERIFY(QFile(mail.getMimeMessagePath()).exists()); | 269 | QVERIFY(!mail.getMimeMessage().isEmpty()); |
273 | SinkTrace() << "Mime message path: " << mail.getMimeMessagePath(); | ||
274 | }); | 270 | }); |
275 | VERIFYEXEC(job); | 271 | VERIFYEXEC(job); |
276 | } | 272 | } |
@@ -324,7 +320,7 @@ void MailTest::testMarkMailAsRead() | |||
324 | auto mail = mails.first(); | 320 | auto mail = mails.first(); |
325 | ASYNCVERIFY(!mail->getSubject().isEmpty()); | 321 | ASYNCVERIFY(!mail->getSubject().isEmpty()); |
326 | ASYNCCOMPARE(mail->getUnread(), false); | 322 | ASYNCCOMPARE(mail->getUnread(), false); |
327 | ASYNCVERIFY(QFileInfo(mail->getMimeMessagePath()).exists()); | 323 | ASYNCVERIFY(!mail->getMimeMessage().isEmpty()); |
328 | return KAsync::null<void>(); | 324 | return KAsync::null<void>(); |
329 | }); | 325 | }); |
330 | VERIFYEXEC(job2); | 326 | VERIFYEXEC(job2); |