From 8348f2ef19928e4331cec485378f51a39a90ae1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Fri, 9 Sep 2022 13:34:12 +0200 Subject: [PATCH] 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 46550808..8c14fa0f 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? get_email_uids_async( + Gee.Collection ids, Cancellable? cancellable) throws Error { + Gee.List 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? get_email_flags_async( Gee.Collection ids, Cancellable? cancellable) throws Error { Gee.Map? map = null; @@ -1882,6 +1894,21 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { return builder.str; } + private Gee.List? do_get_email_uids(Db.Connection cx, + Gee.Collection ids, Cancellable? cancellable) throws Error { + Gee.List? locs = do_get_locations_for_ids(cx, ids, ListFlags.NONE, + cancellable); + if (locs == null) + return null; + + Gee.List uids = new Gee.ArrayList(); + foreach (LocationIdentifier location in locs) { + uids.insert(0, location.uid); + } + + return (uids.size > 0) ? uids : null; + } + private Gee.Map? do_get_email_flags(Db.Connection cx, Gee.Collection ids, Cancellable? cancellable) throws Error { Gee.List? 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 b48e8edb..e8017761 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 to_mark = new Gee.ArrayList(); + private Gee.List to_mark_uids = new Gee.ArrayList(); private Geary.EmailFlags? flags_to_add; private Geary.EmailFlags? flags_to_remove; private Gee.Map? 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? 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 msg_sets = Imap.MessageSet.uid_sparse( - ImapDB.EmailIdentifier.to_uids(original_flags.keys)); + if (to_mark_uids.size > 0) { + Gee.List msg_sets = Imap.MessageSet.uid_sparse(to_mark_uids); yield remote.mark_email_async( msg_sets, flags_to_add, flags_to_remove, cancellable );