[pim/kdepim-runtime] resources/imap: fix qresync synchronisation with no messages in the mailbox and special cases
Noham Devillers <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit f140489ea4d9f8a2881a82489230e6d277787f5d by Noham Devillers.
Committed on 17/07/2026 at 14:54.
Pushed by ndevillers into branch 'master'.
fix qresync synchronisation with no messages in the mailbox and special cases
In the case where we delete all the messages in a mailbox in the server, the QRESYNC synchronisation would crash, because the QRESYNC vanished messages would trigger ItemsRetrievedIncremental, and the "no message in the mailbox" case would then trigger ItemsRetrieved, causing an error in the item sync.
Fix that problem, so that ItemsRetrievedIncremental is now only called at the end of the task for vanished and modified messages. Now we should not be bothered by synchronization special cases (no messages, changing uid, etc).
M +8 -6 resources/imap/retrieveitemstask.cpp
M +3 -0 resources/imap/retrieveitemstask.h
https://invent.kde.org/pim/kdepim-runtime/-/commit/f140489ea4d9f8a2881a82489230e6d277787f5d
diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 304a8ae25..116833b44 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -180,13 +180,11 @@ void RetrieveItemsTask::triggerFinalSelect(const QString &mailBox)
void RetrieveItemsTask::onSelectVanished(const KIMAP::ImapSet &messages)
{
- auto removedItems = imapSetToItems(messages);
- itemsRetrievedIncremental(Akonadi::Item::List(), removedItems);
+ m_qresyncVanishedItems = imapSetToItems(messages);
}
void RetrieveItemsTask::onSelectModified(const QMap<qint64, KIMAP::Message> &messages)
{
- Akonadi::Item::List modifiedItems;
KIMAP::FetchJob::FetchScope scope;
// QRESYNC SELECT only warns us about flag changes
scope.mode = KIMAP::FetchJob::FetchScope::Flags;
@@ -194,10 +192,9 @@ void RetrieveItemsTask::onSelectModified(const QMap<qint64, KIMAP::Message> &mes
bool ok;
const auto item = resourceState()->messageHelper()->createItemFromMessage(msg->message, msg->uid, msg->size, msg->attributes, msg->flags, scope, ok);
if (ok) {
- modifiedItems << item;
+ m_qresyncModifiedItems << item;
}
}
- itemsRetrievedIncremental(modifiedItems, Akonadi::Item::List());
}
void RetrieveItemsTask::onFinalSelectDone(KJob *job)
@@ -372,6 +369,9 @@ void RetrieveItemsTask::prepareRetrieval()
// Shortcut:
// If no messages are present on the server, clear local cache and finish
m_incremental = false;
+
+ // the result of previous qresync SELECT is irrelevant, we pass the flag to false to avoid triggering itemsRetrievedIncremental in onItemsRetrieved
+ m_qresyncSelect = false;
if (realMessageCount > 0) {
qCDebug(IMAPRESOURCE_LOG) << "No messages present so we are done, deleting local messages.";
itemsRetrieved(Akonadi::Item::List());
@@ -601,7 +601,9 @@ void RetrieveItemsTask::taskComplete()
qCDebug(IMAPRESOURCE_LOG) << "Applying collection changes";
applyCollectionChanges(m_modifiedCollection);
}
- if (m_incremental || m_qresyncSelect) {
+ if (m_qresyncSelect) {
+ itemsRetrievedIncremental(m_qresyncModifiedItems, m_qresyncVanishedItems);
+ } else if (m_incremental) {
// Calling itemsRetrievalDone() before previous call to itemsRetrievedIncremental()
// behaves like if we called itemsRetrieved(Items::List()), so make sure
// Akonadi knows we did incremental fetch that came up with no changes
diff --git a/resources/imap/retrieveitemstask.h b/resources/imap/retrieveitemstask.h
index 36109d892..2d353ab0e 100644
--- a/resources/imap/retrieveitemstask.h
+++ b/resources/imap/retrieveitemstask.h
@@ -77,5 +77,8 @@ private:
qint64 m_highestModSeq = -1;
QList<QByteArray> m_flags;
+ // QRESYNC related values
bool m_qresyncSelect;
+ Akonadi::Item::List m_qresyncModifiedItems;
+ Akonadi::Item::List m_qresyncVanishedItems;
};