From d33febbc056ea90330485cd8d0b4bb7dd08baabe Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Thu, 29 Dec 2016 16:44:16 +0100 Subject: [PATCH] Don't merge emails if they do not share the same Message-ID. Bug 713530 In some cases, it may happen that a mail is being sent multiple times simultaneously to the same recipient. The only modified field being the Message-ID, we have to check it as well as message's size before merging 2 mails together. Otherwise, at each start-up Geary will try to fetch "missing mails" but will never succeed to do so. --- src/engine/imap-db/imap-db-folder.vala | 14 ++++++++++---- .../imap-engine-account-synchronizer.vala | 11 ++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala index 66f97269..18d01232 100644 --- a/src/engine/imap-db/imap-db-folder.vala +++ b/src/engine/imap-db/imap-db-folder.vala @@ -1234,13 +1234,19 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { return null; } - + // look for duplicate in IMAP message properties - Db.Statement stmt = cx.prepare( - "SELECT id FROM MessageTable WHERE internaldate=? AND rfc822_size=?"); + Db.Statement stmt; + if (email.message_id != null) + stmt = cx.prepare("SELECT id FROM MessageTable WHERE internaldate=? AND rfc822_size=? AND message_id=?"); + else + stmt = cx.prepare("SELECT id FROM MessageTable WHERE internaldate=? AND rfc822_size=?"); + stmt.bind_string(0, internaldate); stmt.bind_int64(1, rfc822_size); - + if (email.message_id != null) + stmt.bind_string(2, email.message_id.to_string()); + Db.Result results = stmt.exec(cancellable); // no duplicates found if (results.finished) diff --git a/src/engine/imap-engine/imap-engine-account-synchronizer.vala b/src/engine/imap-engine/imap-engine-account-synchronizer.vala index a41c72f8..f2899e32 100644 --- a/src/engine/imap-engine/imap-engine-account-synchronizer.vala +++ b/src/engine/imap-engine/imap-engine-account-synchronizer.vala @@ -398,17 +398,18 @@ private class Geary.ImapEngine.AccountSynchronizer : Geary.BaseObject { // if past max_epoch, then just pull in everything and be done with it if (current_epoch.compare(max_epoch) < 0) { - debug("Background sync reached max epoch of %s, fetching all mail from %s", - max_epoch.to_string(), folder.to_string()); - + debug("Background sync reached max epoch of %s, fetching all mail from %s (already got %d of %d emails)", + max_epoch.to_string(), folder.to_string(), local_count, folder.properties.email_total); + yield folder.list_email_by_id_async(null, 1, Geary.Email.Field.NONE, Geary.Folder.ListFlags.OLDEST_TO_NEWEST, bg_cancellable); } else { // don't go past proscribed epoch if (current_epoch.compare(epoch) < 0) current_epoch = epoch; - - debug("Background sync'ing %s to %s", folder.to_string(), current_epoch.to_string()); + + debug("Background sync'ing %s to %s (already got %d of %d emails)", + folder.to_string(), current_epoch.to_string(), local_count, folder.properties.email_total); Geary.EmailIdentifier? earliest_span_id = yield folder.find_earliest_email_async(current_epoch, oldest_local_id, bg_cancellable); if (earliest_span_id == null && current_epoch.compare(epoch) <= 0) {