[geary/gnumdk/fix_unread_count] engine: Mark all email UIDs in remote replay




commit 5d291b56a8dfafc9c505840a0aacf14ede9a1c20
Author: Cédric Bellegarde <cedric bellegarde adishatz org>
Date:   Fri Sep 9 13:34:12 2022 +0200

    engine: Mark all email UIDs in remote replay
    
    Local replay and remote replay were marking email based on email identifier.
    
    Works locally, but remotely we need to work on all email UIDs.
    
    Fix #364

 src/engine/imap-db/imap-db-folder.vala             | 27 ++++++++++++++++++++++
 .../replay-ops/imap-engine-mark-email.vala         | 10 +++++---
 2 files changed, 34 insertions(+), 3 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala
index 465508080..8c14fa0f0 100644
--- a/src/engine/imap-db/imap-db-folder.vala
+++ b/src/engine/imap-db/imap-db-folder.vala
@@ -1122,6 +1122,18 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
             unread_updated(unread_status);
     }
 
+    internal async Gee.List<Imap.UID>? get_email_uids_async(
+        Gee.Collection<EmailIdentifier> ids, Cancellable? cancellable) throws Error {
+        Gee.List<Imap.UID> uids = null;
+        yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => {
+            uids = do_get_email_uids(cx, ids, cancellable);
+
+            return Db.TransactionOutcome.SUCCESS;
+        }, cancellable);
+
+        return uids;
+    }
+
     internal async Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags>? get_email_flags_async(
         Gee.Collection<EmailIdentifier> ids, Cancellable? cancellable) throws Error {
         Gee.Map<EmailIdentifier, Geary.EmailFlags>? map = null;
@@ -1882,6 +1894,21 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
         return builder.str;
     }
 
+    private Gee.List<Imap.UID>? do_get_email_uids(Db.Connection cx,
+        Gee.Collection<ImapDB.EmailIdentifier> ids, Cancellable? cancellable) throws Error {
+        Gee.List<LocationIdentifier>? locs = do_get_locations_for_ids(cx, ids, ListFlags.NONE,
+            cancellable);
+        if (locs == null)
+            return null;
+
+        Gee.List<Imap.UID> uids = new Gee.ArrayList<Imap.UID>();
+        foreach (LocationIdentifier location in locs) {
+            uids.insert(0, location.uid);
+        }
+
+        return (uids.size > 0) ? uids : null;
+    }
+
     private Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags>? do_get_email_flags(Db.Connection cx,
         Gee.Collection<ImapDB.EmailIdentifier> ids, Cancellable? cancellable) throws Error {
         Gee.List<LocationIdentifier>? locs = do_get_locations_for_ids(cx, ids, ListFlags.NONE,
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala 
b/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala
index b48e8edbf..e80177613 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-mark-email.vala
@@ -7,6 +7,7 @@
 private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation {
     private MinimalFolder engine;
     private Gee.List<ImapDB.EmailIdentifier> to_mark = new Gee.ArrayList<ImapDB.EmailIdentifier>();
+    private Gee.List<Imap.UID> to_mark_uids = new Gee.ArrayList<Imap.UID>();
     private Geary.EmailFlags? flags_to_add;
     private Geary.EmailFlags? flags_to_remove;
     private Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags>? original_flags = null;
@@ -48,6 +49,10 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation
         yield engine.local_folder.mark_email_async(original_flags.keys, flags_to_add, flags_to_remove,
             cancellable);
 
+        // We can't rely on email identifier for remote replay
+        // An email identifier id can match multiple uids
+        to_mark_uids = yield engine.local_folder.get_email_uids_async(to_mark, cancellable);
+
         // Notify using flags from DB.
         Gee.Map<EmailIdentifier, Geary.EmailFlags>? map = yield engine.local_folder.get_email_flags_async(
             original_flags.keys, cancellable);
@@ -60,9 +65,8 @@ private class Geary.ImapEngine.MarkEmail : Geary.ImapEngine.SendReplayOperation
     public override async void replay_remote_async(Imap.FolderSession remote)
         throws GLib.Error {
         // potentially empty due to writebehind operation
-        if (original_flags.size > 0) {
-            Gee.List<Imap.MessageSet> msg_sets = Imap.MessageSet.uid_sparse(
-                ImapDB.EmailIdentifier.to_uids(original_flags.keys));
+        if (to_mark_uids.size > 0) {
+            Gee.List<Imap.MessageSet> msg_sets = Imap.MessageSet.uid_sparse(to_mark_uids);
             yield remote.mark_email_async(
                 msg_sets, flags_to_add, flags_to_remove, cancellable
             );


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]