summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-08 22:57:41 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-08 23:00:00 +0200
commit5162328cd8edba85017185ef5864b2b65f6f18ed (patch)
tree371256e6bf76e1603e2fe08e1c04bff33ecd604c
parent7744e638441fe93ee28bab80c2339e12a8f318d4 (diff)
downloadsink-5162328cd8edba85017185ef5864b2b65f6f18ed.tar.gz
sink-5162328cd8edba85017185ef5864b2b65f6f18ed.zip
Move mimeMessage in preprocessor, and directly move to cur.
We use the maildir as our internal storage, so the message needs to be moved immediately and not only with changereplay.
-rw-r--r--examples/maildirresource/libmaildir/maildir.cpp4
-rw-r--r--examples/maildirresource/maildirresource.cpp76
-rw-r--r--tests/maildirresourcetest.cpp12
3 files changed, 76 insertions, 16 deletions
diff --git a/examples/maildirresource/libmaildir/maildir.cpp b/examples/maildirresource/libmaildir/maildir.cpp
index 670d4ca..1018b4a 100644
--- a/examples/maildirresource/libmaildir/maildir.cpp
+++ b/examples/maildirresource/libmaildir/maildir.cpp
@@ -729,8 +729,8 @@ QString Maildir::addEntryFromPath(const QString& path)
729 return QString(); 729 return QString();
730 } 730 }
731 731
732 if (!f.rename(finalKey)) { 732 if (!f.rename(curKey)) {
733 qWarning() << "Maildir: Failed to add entry: " << finalKey << "! Error: " << f.errorString(); 733 qWarning() << "Maildir: Failed to add entry: " << curKey << "! Error: " << f.errorString();
734 // d->lastError = i18n("Failed to create mail file %1. The error was: %2" , finalKey, f.errorString()); 734 // d->lastError = i18n("Failed to create mail file %1. The error was: %2" , finalKey, f.errorString());
735 return QString(); 735 return QString();
736 } 736 }
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp
index f4833a8..caebd47 100644
--- a/examples/maildirresource/maildirresource.cpp
+++ b/examples/maildirresource/maildirresource.cpp
@@ -54,11 +54,44 @@ class FolderUpdater : public Sink::Preprocessor
54public: 54public:
55 FolderUpdater(const QByteArray &drafts) : mDraftsFolder(drafts) {} 55 FolderUpdater(const QByteArray &drafts) : mDraftsFolder(drafts) {}
56 56
57 QString getPath(const QByteArray &folderIdentifier, Sink::Storage::Transaction &transaction)
58 {
59 if (folderIdentifier.isEmpty()) {
60 return mMaildirPath;
61 }
62 QString folderPath;
63 auto db = Sink::Storage::mainDatabase(transaction, ENTITY_TYPE_FOLDER);
64 db.findLatest(folderIdentifier, [&](const QByteArray &, const QByteArray &value) {
65 Sink::EntityBuffer buffer(value);
66 const Sink::Entity &entity = buffer.entity();
67 const auto adaptor = mFolderAdaptorFactory->createAdaptor(entity);
68 auto folderName = adaptor->getProperty("name").toString();
69 //TODO handle non toplevel folders
70 folderPath = mMaildirPath + "/" + folderName;
71 });
72 return folderPath;
73 }
74
57 void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE 75 void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
58 { 76 {
59 if (newEntity.getProperty("draft").toBool()) { 77 if (newEntity.getProperty("draft").toBool()) {
60 newEntity.setProperty("folder", mDraftsFolder); 78 newEntity.setProperty("folder", mDraftsFolder);
61 } 79 }
80 const auto mimeMessage = newEntity.getProperty("mimeMessage");
81 if (mimeMessage.isValid()) {
82 const auto oldPath = newEntity.getProperty("mimeMessage").toString();
83 if (oldPath.startsWith(Sink::temporaryFileLocation())) {
84 auto folder = newEntity.getProperty("folder").toByteArray();
85 const auto path = getPath(folder, transaction);
86 KPIM::Maildir maildir(path, false);
87 if (!maildir.isValid(true)) {
88 qWarning() << "Maildir is not existing: " << path;
89 }
90 auto identifier = maildir.addEntryFromPath(oldPath);
91 auto newPath = path + "/cur/" + identifier;
92 newEntity.setProperty("mimeMessage", QVariant::fromValue(newPath));
93 }
94 }
62 } 95 }
63 96
64 void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, 97 void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity,
@@ -70,6 +103,33 @@ public:
70 { 103 {
71 } 104 }
72 QByteArray mDraftsFolder; 105 QByteArray mDraftsFolder;
106 QByteArray mResourceInstanceIdentifier;
107 QString mMaildirPath;
108 QSharedPointer<MaildirFolderAdaptorFactory> mFolderAdaptorFactory;
109};
110
111class FolderPreprocessor : public Sink::Preprocessor
112{
113public:
114 FolderPreprocessor() {}
115
116 void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
117 {
118 auto folderName = newEntity.getProperty("name").toString();
119 const auto path = mMaildirPath + "/" + folderName;
120 KPIM::Maildir maildir(path, false);
121 maildir.create();
122 }
123
124 void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity,
125 Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
126 {
127 }
128
129 void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
130 {
131 }
132 QString mMaildirPath;
73}; 133};
74 134
75MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline) 135MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline)
@@ -87,8 +147,9 @@ MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSh
87 auto folderUpdater = new FolderUpdater(QByteArray()); 147 auto folderUpdater = new FolderUpdater(QByteArray());
88 addType(ENTITY_TYPE_MAIL, mMailAdaptorFactory, 148 addType(ENTITY_TYPE_MAIL, mMailAdaptorFactory,
89 QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail> << folderUpdater); 149 QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Mail> << folderUpdater);
150 auto folderPreprocessor = new FolderPreprocessor;
90 addType(ENTITY_TYPE_FOLDER, mFolderAdaptorFactory, 151 addType(ENTITY_TYPE_FOLDER, mFolderAdaptorFactory,
91 QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder>); 152 QVector<Sink::Preprocessor*>() << new DefaultIndexUpdater<Sink::ApplicationDomain::Folder> << folderPreprocessor);
92 153
93 KPIM::Maildir dir(mMaildirPath, true); 154 KPIM::Maildir dir(mMaildirPath, true);
94 mDraftsFolder = dir.addSubFolder("drafts"); 155 mDraftsFolder = dir.addSubFolder("drafts");
@@ -103,6 +164,10 @@ MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSh
103 synchronizationTransaction.commit(); 164 synchronizationTransaction.commit();
104 165
105 folderUpdater->mDraftsFolder = draftsFolderLocalId; 166 folderUpdater->mDraftsFolder = draftsFolderLocalId;
167 folderUpdater->mResourceInstanceIdentifier = mResourceInstanceIdentifier;
168 folderUpdater->mFolderAdaptorFactory = mFolderAdaptorFactory;
169 folderUpdater->mMaildirPath = mMaildirPath;
170 folderPreprocessor->mMaildirPath = mMaildirPath;
106} 171}
107 172
108static QStringList listRecursive( const QString &root, const KPIM::Maildir &dir ) 173static QStringList listRecursive( const QString &root, const KPIM::Maildir &dir )
@@ -321,13 +386,8 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c
321 parentFolderRemoteId = mMaildirPath.toUtf8(); 386 parentFolderRemoteId = mMaildirPath.toUtf8();
322 } 387 }
323 const auto parentFolderPath = parentFolderRemoteId; 388 const auto parentFolderPath = parentFolderRemoteId;
324 KPIM::Maildir maildir(parentFolderPath, false); 389 const auto remoteId = mail.getProperty("mimeMessage").toString().split('/').last();
325 if (!maildir.isValid(true)) { 390 Trace() << "Creating a new mail." << remoteId;
326 return KAsync::error<void>(1, "Invalid folder " + parentFolderPath);
327 }
328 //FIXME move the mime message from the mimeMessage property to the proper place.
329 Trace() << "Creating a new mail.";
330 const auto remoteId = maildir.addEntryFromPath(mail.getProperty("mimeMessage").toString());
331 if (remoteId.isEmpty()) { 391 if (remoteId.isEmpty()) {
332 Warning() << "Failed to create mail: " << remoteId; 392 Warning() << "Failed to create mail: " << remoteId;
333 return KAsync::error<void>(1, "Failed to create mail."); 393 return KAsync::error<void>(1, "Failed to create mail.");
diff --git a/tests/maildirresourcetest.cpp b/tests/maildirresourcetest.cpp
index 372ca5d..ec685a6 100644
--- a/tests/maildirresourcetest.cpp
+++ b/tests/maildirresourcetest.cpp
@@ -196,7 +196,7 @@ private slots:
196 196
197 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 197 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query);
198 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 198 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
199 QCOMPARE(model->rowCount(QModelIndex()), 3); 199 QCOMPARE(model->rowCount(QModelIndex()), 4);
200 QCOMPARE(model->match(model->index(0, 0, QModelIndex()), Qt::DisplayRole, QStringLiteral("newbox"), 1).size(), 1); 200 QCOMPARE(model->match(model->index(0, 0, QModelIndex()), Qt::DisplayRole, QStringLiteral("newbox"), 1).size(), 1);
201 } 201 }
202 202
@@ -312,11 +312,11 @@ private slots:
312 // Ensure all local data is processed 312 // Ensure all local data is processed
313 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 313 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
314 314
315 auto targetPath = tempDir.path() + "/maildir1/new"; 315 auto targetPath = tempDir.path() + "/maildir1/cur";
316 QDir dir(targetPath); 316 QDir dir(targetPath);
317 dir.setFilter(QDir::Files); 317 dir.setFilter(QDir::Files);
318 QTRY_COMPARE(dir.count(), static_cast<unsigned int>(1)); 318 QTRY_COMPARE(dir.count(), static_cast<unsigned int>(2));
319 QFile file(targetPath + "/" + dir.entryList().first()); 319 QFile file(targetPath + "/" + dir.entryList().last());
320 QVERIFY(file.open(QIODevice::ReadOnly)); 320 QVERIFY(file.open(QIODevice::ReadOnly));
321 KMime::Message m; 321 KMime::Message m;
322 m.setContent(file.readAll()); 322 m.setContent(file.readAll());
@@ -360,10 +360,10 @@ private slots:
360 future2.waitForFinished(); 360 future2.waitForFinished();
361 QVERIFY(!future2.errorCode()); 361 QVERIFY(!future2.errorCode());
362 362
363 auto targetPath = tempDir.path() + "/maildir1/newfolder/new"; 363 auto targetPath = tempDir.path() + "/maildir1/newfolder/cur";
364 QDir dir(targetPath); 364 QDir dir(targetPath);
365 dir.setFilter(QDir::Files); 365 dir.setFilter(QDir::Files);
366 QTRY_COMPARE(dir.count(), static_cast<unsigned int>(1)); 366 QCOMPARE(dir.count(), static_cast<unsigned int>(1));
367 } 367 }
368 368
369 void testRemoveMail() 369 void testRemoveMail()