[geary/wip/composer-folks: 4/22] Remove existing contact harvesting mechanism



commit cb8150ce0310e0be0d50f946f63734c75d9ed1e0
Author: Michael Gratton <mike vee net>
Date:   Fri Jun 7 18:06:31 2019 +1000

    Remove existing contact harvesting mechanism
    
    Remove contact harvesting from DB version 005 (version 0.1.1), allowing
    the implementation of both ContactStoreImpl and ImapDB.Database to be
    cleaned up. Remove contact collection from ImapDB.Folder, reducing the
    numer of Gee objects created when creating/merging messages. Finally,
    remove the MessageAddresses object now that it is unused.

 po/POTFILES.in                                     |   1 -
 sql/version-005.sql                                |   2 +-
 src/engine/common/common-contact-store-impl.vala   |  95 ++++++-------
 src/engine/imap-db/imap-db-account.vala            |   7 +-
 src/engine/imap-db/imap-db-database.vala           |  30 +---
 src/engine/imap-db/imap-db-folder.vala             | 112 +++++++--------
 src/engine/imap-db/imap-db-message-addresses.vala  | 151 ---------------------
 .../imap-engine/imap-engine-generic-account.vala   |   2 +-
 src/engine/meson.build                             |   1 -
 test/engine/imap-db/imap-db-database-test.vala     |   6 +-
 10 files changed, 101 insertions(+), 306 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1e1ec5cd..dd26b805 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -222,7 +222,6 @@ src/engine/imap-db/imap-db-database.vala
 src/engine/imap-db/imap-db-email-identifier.vala
 src/engine/imap-db/imap-db-folder.vala
 src/engine/imap-db/imap-db-gc.vala
-src/engine/imap-db/imap-db-message-addresses.vala
 src/engine/imap-db/imap-db-message-row.vala
 src/engine/imap-db/search/imap-db-search-email-identifier.vala
 src/engine/imap-db/search/imap-db-search-folder-properties.vala
diff --git a/sql/version-005.sql b/sql/version-005.sql
index 1b154890..808dccbe 100644
--- a/sql/version-005.sql
+++ b/sql/version-005.sql
@@ -1,6 +1,6 @@
 
 --
--- Create ContactTable for autocompletion contacts. Data is migrated in vala upgrade hooks.
+-- Create ContactTable for autocompletion contacts.
 --
 
 CREATE TABLE ContactTable (
diff --git a/src/engine/common/common-contact-store-impl.vala 
b/src/engine/common/common-contact-store-impl.vala
index 48f4ad4c..550a3110 100644
--- a/src/engine/common/common-contact-store-impl.vala
+++ b/src/engine/common/common-contact-store-impl.vala
@@ -12,15 +12,46 @@
 internal class Geary.ContactStoreImpl : BaseObject, Geary.ContactStore {
 
 
-    // Insert or update a contact in the ContactTable. If contact
-    // already exists, flags are merged and the importance is updated
-    // to the highest importance seen.
-    //
-    // Internal and static since it is used by ImapDB.Database during
-    // upgrades
-    internal static void do_update_contact(Db.Connection cx,
-                                           Contact updated,
-                                           GLib.Cancellable? cancellable)
+    private Geary.Db.Database backing;
+
+
+    internal ContactStoreImpl(Geary.Db.Database backing) {
+        base_ref();
+        this.backing = backing;
+    }
+
+    /** Returns the contact matching the given email address, if any */
+    public async Contact? get_by_rfc822(Geary.RFC822.MailboxAddress mailbox,
+                                        GLib.Cancellable? cancellable)
+        throws GLib.Error {
+        Contact? contact = null;
+        yield this.backing.exec_transaction_async(
+            Db.TransactionType.RO,
+            (cx, cancellable) => {
+                contact = do_fetch_contact(cx, mailbox.address, cancellable);
+                return Db.TransactionOutcome.COMMIT;
+            },
+            cancellable);
+        return contact;
+    }
+
+    public async void update_contacts(Gee.Collection<Contact> updated,
+                                      GLib.Cancellable? cancellable)
+        throws GLib.Error {
+        yield this.backing.exec_transaction_async(
+            Db.TransactionType.RW,
+            (cx, cancellable) => {
+                foreach (Contact contact in updated) {
+                    do_update_contact(cx, contact, cancellable);
+                }
+                return Db.TransactionOutcome.COMMIT;
+            },
+            cancellable);
+    }
+
+    private void do_update_contact(Db.Connection cx,
+                                   Contact updated,
+                                   GLib.Cancellable? cancellable)
         throws GLib.Error {
         Contact? existing = do_fetch_contact(
             cx, updated.email, cancellable
@@ -69,11 +100,9 @@ internal class Geary.ContactStoreImpl : BaseObject, Geary.ContactStore {
         }
     }
 
-    // Static since it is indirectly used by ImapDB.Database during
-    // upgrades
-    private static Contact? do_fetch_contact(Db.Connection cx,
-                                             string email,
-                                             GLib.Cancellable? cancellable)
+    private Contact? do_fetch_contact(Db.Connection cx,
+                                      string email,
+                                      GLib.Cancellable? cancellable)
         throws GLib.Error {
         Db.Statement stmt = cx.prepare(
             "SELECT real_name, highest_importance, normalized_email, flags FROM ContactTable "
@@ -95,42 +124,4 @@ internal class Geary.ContactStoreImpl : BaseObject, Geary.ContactStore {
         return contact;
     }
 
-
-    private Geary.Db.Database backing;
-
-
-    internal ContactStoreImpl(Geary.Db.Database backing) {
-        base_ref();
-        this.backing = backing;
-    }
-
-    /** Returns the contact matching the given email address, if any */
-    public async Contact? get_by_rfc822(Geary.RFC822.MailboxAddress mailbox,
-                                        GLib.Cancellable? cancellable)
-        throws GLib.Error {
-        Contact? contact = null;
-        yield this.backing.exec_transaction_async(
-            Db.TransactionType.RO,
-            (cx, cancellable) => {
-                contact = do_fetch_contact(cx, mailbox.address, cancellable);
-                return Db.TransactionOutcome.COMMIT;
-            },
-            cancellable);
-        return contact;
-    }
-
-    public async void update_contacts(Gee.Collection<Contact> updated,
-                                      GLib.Cancellable? cancellable)
-        throws GLib.Error {
-        yield this.backing.exec_transaction_async(
-            Db.TransactionType.RW,
-            (cx, cancellable) => {
-                foreach (Contact contact in updated) {
-                    do_update_contact(cx, contact, cancellable);
-                }
-                return Db.TransactionOutcome.COMMIT;
-            },
-            cancellable);
-    }
-
 }
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index 87744343..18de3c10 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -89,7 +89,6 @@ private class Geary.ImapDB.Account : BaseObject {
     }
 
     // Only available when the Account is opened
-    public ContactStore contact_store { get; private set; }
     public IntervalProgressMonitor search_index_monitor { get; private set;
         default = new IntervalProgressMonitor(ProgressType.SEARCH_INDEX, 0, 0); }
     public SimpleProgressMonitor upgrade_monitor { get; private set; default = new SimpleProgressMonitor(
@@ -288,8 +287,7 @@ private class Geary.ImapDB.Account : BaseObject {
             schema_dir,
             attachments_dir,
             upgrade_monitor,
-            vacuum_monitor,
-            account_information.primary_mailbox.address
+            vacuum_monitor
         );
 
         try {
@@ -351,8 +349,6 @@ private class Geary.ImapDB.Account : BaseObject {
 
             return false;
         });
-
-        this.contact_store = new ContactStoreImpl(db);
     }
 
     public async void close_async(Cancellable? cancellable) throws Error {
@@ -617,7 +613,6 @@ private class Geary.ImapDB.Account : BaseObject {
                 db,
                 path,
                 db.attachments_path,
-                contact_store,
                 account_information.primary_mailbox.address,
                 folder_id,
                 properties
diff --git a/src/engine/imap-db/imap-db-database.vala b/src/engine/imap-db/imap-db-database.vala
index 02672f52..8c4e4761 100644
--- a/src/engine/imap-db/imap-db-database.vala
+++ b/src/engine/imap-db/imap-db-database.vala
@@ -15,7 +15,6 @@ private class Geary.ImapDB.Database : Geary.Db.VersionedDatabase {
 
     private ProgressMonitor upgrade_monitor;
     private ProgressMonitor vacuum_monitor;
-    private string account_owner_email;
     private bool new_db = false;
 
     private GC? gc = null;
@@ -25,15 +24,11 @@ private class Geary.ImapDB.Database : Geary.Db.VersionedDatabase {
                     GLib.File schema_dir,
                     GLib.File attachments_path,
                     ProgressMonitor upgrade_monitor,
-                    ProgressMonitor vacuum_monitor,
-                    string account_owner_email) {
+                    ProgressMonitor vacuum_monitor) {
         base.persistent(db_file, schema_dir);
         this.attachments_path = attachments_path;
         this.upgrade_monitor = upgrade_monitor;
         this.vacuum_monitor = vacuum_monitor;
-
-        // Update to use all addresses on the account. Bug 768779
-        this.account_owner_email = account_owner_email;
     }
 
     /**
@@ -133,10 +128,6 @@ private class Geary.ImapDB.Database : Geary.Db.VersionedDatabase {
                                                Cancellable? cancellable)
         throws Error {
         switch (version) {
-            case 5:
-                yield post_upgrade_populate_autocomplete(cancellable);
-            break;
-
             case 6:
                 yield post_upgrade_encode_folder_names(cancellable);
             break;
@@ -179,25 +170,6 @@ private class Geary.ImapDB.Database : Geary.Db.VersionedDatabase {
         }
     }
 
-    // Version 5.
-    private async void post_upgrade_populate_autocomplete(Cancellable? cancellable)
-        throws Error {
-        yield exec_transaction_async(Db.TransactionType.RW, (cx) => {
-                Db.Result result = cx.query(
-                    "SELECT sender, from_field, to_field, cc, bcc FROM MessageTable"
-                );
-                while (!result.finished && !cancellable.is_cancelled()) {
-                    MessageAddresses message_addresses =
-                    new MessageAddresses.from_result(account_owner_email, result);
-                    foreach (Contact contact in message_addresses.contacts) {
-                        ContactStoreImpl.do_update_contact(cx, contact, null);
-                    }
-                    result.next();
-                }
-                return Geary.Db.TransactionOutcome.COMMIT;
-            }, cancellable);
-    }
-
     // Version 6.
     private async void post_upgrade_encode_folder_names(Cancellable? cancellable)
         throws Error {
diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala
index a28147d6..f4ed001b 100644
--- a/src/engine/imap-db/imap-db-folder.vala
+++ b/src/engine/imap-db/imap-db-folder.vala
@@ -91,7 +91,6 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
     private Geary.Db.Database db;
     private Geary.FolderPath path;
     private GLib.File attachments_path;
-    private ContactStore contact_store;
     private string account_owner_email;
     private int64 folder_id;
     private Geary.Imap.FolderProperties properties;
@@ -111,14 +110,12 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
     internal Folder(Geary.Db.Database db,
                     Geary.FolderPath path,
                     GLib.File attachments_path,
-                    ContactStore contact_store,
                     string account_owner_email,
                     int64 folder_id,
                     Geary.Imap.FolderProperties properties) {
         this.db = db;
         this.path = path;
         this.attachments_path = attachments_path;
-        this.contact_store = contact_store;
         // Update to use all addresses on the account. Bug 768779
         this.account_owner_email = account_owner_email;
         this.folder_id = folder_id;
@@ -290,19 +287,18 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
             Gee.List<Geary.Email> slice = list.slice(index, stop);
 
             Gee.ArrayList<Geary.EmailIdentifier> complete_ids = new Gee.ArrayList<Geary.EmailIdentifier>();
-            Gee.Collection<Contact> updated_contacts = new Gee.ArrayList<Contact>();
             int total_unread_change = 0;
             yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
                 foreach (Geary.Email email in slice) {
-                    Gee.Collection<Contact>? contacts_this_email = null;
                     Geary.Email.Field pre_fields;
                     Geary.Email.Field post_fields;
                     int unread_change = 0;
-                    bool created = do_create_or_merge_email(cx, email, out pre_fields,
-                        out post_fields, out contacts_this_email, ref unread_change, cancellable);
-
-                    if (contacts_this_email != null)
-                        updated_contacts.add_all(contacts_this_email);
+                    bool created = do_create_or_merge_email(
+                        cx, email,
+                        out pre_fields, out post_fields,
+                        ref unread_change,
+                        cancellable
+                    );
 
                     results.set(email, created);
 
@@ -321,12 +317,6 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
                 return Db.TransactionOutcome.COMMIT;
             }, cancellable);
 
-            if (updated_contacts.size > 0) {
-                yield this.contact_store.update_contacts(
-                    updated_contacts, cancellable
-                );
-            }
-
             if (update_totals) {
                 // Update the email_unread properties.
                 properties.set_status_unseen(
@@ -1373,10 +1363,13 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
      *
      * Returns `true` if created, else was merged and returns `false`.
      */
-    private bool do_create_or_merge_email(Db.Connection cx, Geary.Email email,
-        out Geary.Email.Field pre_fields, out Geary.Email.Field post_fields,
-        out Gee.Collection<Contact> updated_contacts, ref int unread_count_change,
-        Cancellable? cancellable) throws Error {
+    private bool do_create_or_merge_email(Db.Connection cx,
+                                          Geary.Email email,
+                                          out Geary.Email.Field pre_fields,
+                                          out Geary.Email.Field post_fields,
+                                          ref int unread_count_change,
+                                          GLib.Cancellable? cancellable)
+        throws GLib.Error {
 
         // This should only ever get invoked for messages that came
         // from the IMAP layer, which should not have a message id,
@@ -1424,15 +1417,22 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
             // special-case flag-only updates, which happens often and
             // will only write to the DB if necessary.
             if (email.fields != Geary.Email.Field.FLAGS) {
-                do_merge_email(cx, location, email, out pre_fields, out post_fields,
-                    out updated_contacts, ref unread_count_change, cancellable);
+                do_merge_email(
+                    cx, location, email,
+                    out pre_fields, out post_fields,
+                    ref unread_count_change,
+                    cancellable
+                );
 
                 // Already associated with folder and flags were known.
                 if (is_associated && pre_fields.is_all_set(Geary.Email.Field.FLAGS))
                     unread_count_change = 0;
             } else {
-                do_merge_email_flags(cx, location, email, out pre_fields, out post_fields,
-                    out updated_contacts, ref unread_count_change, cancellable);
+                do_merge_email_flags(
+                    cx, location, email,
+                    out pre_fields, out post_fields,
+                    ref unread_count_change, cancellable
+                );
             }
         } else {
             // Message was not found, so create a new message for it
@@ -1485,12 +1485,6 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
 
             do_add_email_to_search_table(cx, message_id, email, cancellable);
 
-            MessageAddresses message_addresses =
-                new MessageAddresses.from_email(account_owner_email, email);
-            foreach (Contact contact in message_addresses.contacts)
-                do_update_contact(cx, contact, cancellable);
-            updated_contacts = message_addresses.contacts;
-
             // Update unread count if our new email is unread.
             if (email.email_flags != null && email.email_flags.is_unread())
                 unread_count_change++;
@@ -1782,13 +1776,12 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
         return true;
     }
 
-    private void do_merge_message_row(Db.Connection cx, MessageRow row,
-        out Geary.Email.Field new_fields, out Gee.Collection<Contact> updated_contacts,
-        ref int unread_count_change, Cancellable? cancellable) throws Error {
-
-        // Initialize to an empty list, in case we return early.
-        updated_contacts = new Gee.LinkedList<Contact>();
-
+    private void do_merge_message_row(Db.Connection cx,
+                                      MessageRow row,
+                                      out Geary.Email.Field new_fields,
+                                      ref int unread_count_change,
+                                      GLib.Cancellable? cancellable)
+        throws GLib.Error {
         Geary.Email.Field available_fields;
         if (!do_fetch_email_fields(cx, row.id, out available_fields, cancellable))
             throw new EngineError.NOT_FOUND("No message with ID %s found in database", row.id.to_string());
@@ -1918,13 +1911,6 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
         stmt.bind_rowid(1, row.id);
 
         stmt.exec(cancellable);
-
-        // Update the autocompletion table.
-        MessageAddresses message_addresses =
-            new MessageAddresses.from_row(account_owner_email, row);
-        foreach (Geary.Contact contact in message_addresses.contacts)
-            do_update_contact(cx, contact, cancellable);
-        updated_contacts = message_addresses.contacts;
     }
 
     private void do_merge_email_in_search_table(Db.Connection cx, int64 message_id,
@@ -2007,15 +1993,16 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
 
     // This *replaces* the stored flags, it does not OR them ... this is simply a fast-path over
     // do_merge_email(), as updating FLAGS happens often and doesn't require a lot of extra work
-    private void do_merge_email_flags(Db.Connection cx, LocationIdentifier location, Geary.Email email,
-        out Geary.Email.Field pre_fields, out Geary.Email.Field post_fields,
-        out Gee.Collection<Contact> updated_contacts, ref int unread_count_change,
-        Cancellable? cancellable) throws Error {
+    private void do_merge_email_flags(Db.Connection cx,
+                                      LocationIdentifier location,
+                                      Geary.Email email,
+                                      out Geary.Email.Field pre_fields,
+                                      out Geary.Email.Field post_fields,
+                                      ref int unread_count_change,
+                                      GLib.Cancellable? cancellable)
+        throws GLib.Error {
         assert(email.fields == Geary.Email.Field.FLAGS);
 
-        // no contacts were harmed in the production of this email
-        updated_contacts = new Gee.ArrayList<Contact>();
-
         // fetch MessageRow and its fields, note that the fields now include FLAGS if they didn't
         // already
         MessageRow row = do_fetch_message_row(cx, location.message_id, Geary.Email.Field.FLAGS,
@@ -2050,13 +2037,14 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
         }
     }
 
-    private void do_merge_email(Db.Connection cx, LocationIdentifier location, Geary.Email email,
-        out Geary.Email.Field pre_fields, out Geary.Email.Field post_fields,
-        out Gee.Collection<Contact> updated_contacts, ref int unread_count_change,
-        Cancellable? cancellable) throws Error {
-        // Default to an empty list, in case we never call do_merge_message_row.
-        updated_contacts = new Gee.LinkedList<Contact>();
-
+    private void do_merge_email(Db.Connection cx,
+                                LocationIdentifier location,
+                                Geary.Email email,
+                                out Geary.Email.Field pre_fields,
+                                out Geary.Email.Field post_fields,
+                                ref int unread_count_change,
+                                GLib.Cancellable? cancellable)
+        throws GLib.Error {
         // fetch message from database and merge in this email
         MessageRow row = do_fetch_message_row(cx, location.message_id,
             email.fields | Email.REQUIRED_FOR_MESSAGE | Attachment.REQUIRED_FIELDS,
@@ -2090,8 +2078,12 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
             }
 
             Geary.Email.Field new_fields;
-            do_merge_message_row(cx, row, out new_fields, out updated_contacts,
-                ref new_unread_count, cancellable);
+            do_merge_message_row(
+                cx, row,
+                out new_fields,
+                ref new_unread_count,
+                cancellable
+            );
 
             if (do_check_for_message_search_row(cx, location.message_id, cancellable))
                 do_merge_email_in_search_table(cx, location.message_id, new_fields, combined_email, 
cancellable);
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 2f74b8b9..811dc6f6 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -83,7 +83,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
         base(config, imap, smtp);
 
         this.local = local;
-        this.contact_store = local.contact_store;
+        this.contact_store = new ContactStoreImpl(local.db);
 
         imap.min_pool_size = IMAP_MIN_POOL_SIZE;
         imap.notify["current-status"].connect(
diff --git a/src/engine/meson.build b/src/engine/meson.build
index 5a593fa6..b82d7e01 100644
--- a/src/engine/meson.build
+++ b/src/engine/meson.build
@@ -176,7 +176,6 @@ geary_engine_vala_sources = files(
   'imap-db/imap-db-email-identifier.vala',
   'imap-db/imap-db-folder.vala',
   'imap-db/imap-db-gc.vala',
-  'imap-db/imap-db-message-addresses.vala',
   'imap-db/imap-db-message-row.vala',
   'imap-db/search/imap-db-search-email-identifier.vala',
   'imap-db/search/imap-db-search-folder.vala',
diff --git a/test/engine/imap-db/imap-db-database-test.vala b/test/engine/imap-db/imap-db-database-test.vala
index a61038d5..9e1b6e00 100644
--- a/test/engine/imap-db/imap-db-database-test.vala
+++ b/test/engine/imap-db/imap-db-database-test.vala
@@ -35,8 +35,7 @@ class Geary.ImapDB.DatabaseTest : TestCase {
             GLib.File.new_for_path(_SOURCE_ROOT_DIR).get_child("sql"),
             this.tmp_dir.get_child("attachments"),
             new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_UPGRADE),
-            new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM),
-            "test example com"
+            new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM)
         );
 
         db.open.begin(
@@ -96,8 +95,7 @@ class Geary.ImapDB.DatabaseTest : TestCase {
             GLib.File.new_for_path(_SOURCE_ROOT_DIR).get_child("sql"),
             attachments_dir,
             new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_UPGRADE),
-            new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM),
-            "test example com"
+            new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM)
         );
 
         db.open.begin(


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