[geary: 6/66] Track and notify messages detached during cleanup



commit cecf66df08c488a726a9379fc72a0694de4f1e23
Author: Chris Heywood <15127-creywood users noreply gitlab gnome org>
Date:   Wed Jan 8 11:31:25 2020 +0100

    Track and notify messages detached during cleanup
    
    Split detach query into two so that messages identifiers can be captured
    which are then used to signal through that the folder has locally
    removed messages

 src/engine/imap-db/imap-db-folder.vala             | 49 ++++++++++++++++++----
 .../imap-engine-account-synchronizer.vala          |  5 ++-
 2 files changed, 46 insertions(+), 8 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala
index 489dc9087..b6ff465c8 100644
--- a/src/engine/imap-db/imap-db-folder.vala
+++ b/src/engine/imap-db/imap-db-folder.vala
@@ -882,16 +882,18 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
         }, cancellable);
     }
 
-    public async void detach_emails_before_timestamp(DateTime cutoff,
+    public async Gee.Collection<Geary.EmailIdentifier>? detach_emails_before_timestamp(DateTime cutoff,
         Cancellable? cancellable) throws Error {
         debug("Detaching emails before %s for folder ID %", cutoff.to_string(), this.folder_id.to_string());
+        Gee.Collection<Geary.EmailIdentifier>? deleted_ids = null;
 
         yield db.exec_transaction_async(Db.TransactionType.WO, (cx) => {
-            // Query was found to be faster than other approaches. MessageLocationTable.ordering
-            // isn't relied on due to IMAP folder UIDs not guaranteed to be in order.
+            // MessageLocationTable.ordering isn't relied on due to IMAP folder
+            // UIDs not guaranteed to be in order.
             StringBuilder sql = new StringBuilder();
             sql.append("""
-                DELETE FROM MessageLocationTable
+                SELECT id, message_id, ordering
+                FROM MessageLocationTable
                 WHERE folder_id = ?
                 AND message_id IN (
                     SELECT id
@@ -902,12 +904,45 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
             """);
 
             Db.Statement stmt = cx.prepare(sql.str);
-            stmt.bind_rowid(0, this.folder_id);
+            stmt.bind_rowid(0, folder_id);
             stmt.bind_int64(1, cutoff.to_unix());
-            stmt.exec(cancellable);
 
-            return Db.TransactionOutcome.COMMIT;
+            Db.Result results = stmt.exec(cancellable);
+
+            StringBuilder? ids_sql_sublist = null;
+            while (!results.finished) {
+                if (ids_sql_sublist == null) {
+                    deleted_ids = new Gee.ArrayList<Geary.EmailIdentifier>();
+                    ids_sql_sublist = new StringBuilder();
+                } else {
+                    ids_sql_sublist.append(",");
+                }
+
+                deleted_ids.add(new ImapDB.EmailIdentifier(results.int64_at(1), new 
Imap.UID(results.int64_at(2))));
+                ids_sql_sublist.append(results.rowid_at(0).to_string());
+
+                results.next(cancellable);
+            }
+
+            if (deleted_ids != null) {
+                sql = new StringBuilder();
+                sql.append("""
+                    DELETE FROM MessageLocationTable
+                    WHERE id IN (
+                """);
+                sql.append(ids_sql_sublist.str);
+                sql.append(")");
+                stmt = cx.prepare(sql.str);
+
+                stmt.exec(cancellable);
+
+                return Db.TransactionOutcome.COMMIT;
+            } else {
+                return Db.TransactionOutcome.DONE;
+            }
         }, cancellable);
+
+        return deleted_ids;
     }
 
     public async void mark_email_async(Gee.Collection<ImapDB.EmailIdentifier> to_mark,
diff --git a/src/engine/imap-engine/imap-engine-account-synchronizer.vala 
b/src/engine/imap-engine/imap-engine-account-synchronizer.vala
index f0f2b84cc..654ca0397 100644
--- a/src/engine/imap-engine/imap-engine-account-synchronizer.vala
+++ b/src/engine/imap-engine/imap-engine-account-synchronizer.vala
@@ -247,7 +247,10 @@ private class Geary.ImapEngine.CheckFolderSync : RefreshFolderSync {
 
         // Detach older emails outside the prefetch window
         if (this.account.information.prefetch_period_days >= 0) {
-            yield local_folder.detach_emails_before_timestamp(prefetch_max_epoch, cancellable);
+            Gee.Collection<Geary.EmailIdentifier>? detached_ids = yield 
local_folder.detach_emails_before_timestamp(prefetch_max_epoch, cancellable);
+            if (detached_ids != null) {
+                this.folder.email_locally_removed(detached_ids);
+            }
         }
 
         // get oldest local email and its time, as well as number


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