[geary/wip/search-columns-714494] Use phrases in highlighting too



commit 7f26c821795d0394f801dde1e1ab37b627009737
Author: Charles Lindsay <chaz yorba org>
Date:   Mon Dec 16 12:23:25 2013 -0800

    Use phrases in highlighting too

 src/engine/imap-db/imap-db-account.vala |   60 +++++++++++++++++++------------
 1 files changed, 37 insertions(+), 23 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index 27e72f2..c24cf4c 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -727,6 +727,7 @@ private class Geary.ImapDB.Account : BaseObject {
         query.parsed = true;
     }
     
+    // Return a map of column -> phrase, to use as WHERE column MATCH 'phrase'.
     private Gee.HashMap<string, string> get_query_phrases(Geary.SearchQuery query) {
         prepare_search_query(query);
         
@@ -743,9 +744,25 @@ private class Geary.ImapDB.Account : BaseObject {
         return phrases;
     }
     
+    private void sql_add_query_phrases(StringBuilder sql, Gee.HashMap<string, string> query_phrases) {
+        foreach (string field in query_phrases.keys)
+            sql.append(" AND %s MATCH ?".printf(field));
+    }
+    
+    private int sql_bind_query_phrases(Db.Statement stmt, int start_index,
+        Gee.HashMap<string, string> query_phrases) throws Geary.DatabaseError {
+        int i = start_index;
+        // This relies on the keys being returned in the same order every time
+        // from the same map.  It might not be guaranteed, but I feel pretty
+        // confident it'll work unless you change the map in between.
+        foreach (string field in query_phrases.keys)
+            stmt.bind_string(i++, query_phrases.get(field));
+        return i - start_index;
+    }
+    
     // Append each id in the collection to the StringBuilder, in a format
     // suitable for use in an SQL statement IN (...) clause.
-    private void sql_append_ids(StringBuilder s, Gee.Collection<int64?> ids) {
+    private void sql_append_ids(StringBuilder s, Gee.Iterable<int64?> ids) {
         bool first = true;
         foreach (int64? id in ids) {
             assert(id != null);
@@ -785,7 +802,6 @@ private class Geary.ImapDB.Account : BaseObject {
         Gee.HashMap<string, string> query_phrases = get_query_phrases(query);
         if (query_phrases.size == 0)
             return null;
-        string[] ordered_fields = query_phrases.keys.to_array();
         
         Gee.ArrayList<ImapDB.SearchEmailIdentifier> search_results
             = new Gee.ArrayList<ImapDB.SearchEmailIdentifier>();
@@ -814,8 +830,7 @@ private class Geary.ImapDB.Account : BaseObject {
                     FROM MessageSearchTable
                     WHERE 1=1
             """);
-            foreach (string field in ordered_fields)
-                sql.append(" AND %s MATCH ?".printf(field));
+            sql_add_query_phrases(sql, query_phrases);
             sql.append(")");
             
             if (blacklisted_ids_sql != "")
@@ -827,9 +842,7 @@ private class Geary.ImapDB.Account : BaseObject {
                 sql.append(" LIMIT ? OFFSET ?");
             
             Db.Statement stmt = cx.prepare(sql.str);
-            int bind_index = 0;
-            foreach (string field in ordered_fields)
-                stmt.bind_string(bind_index++, query_phrases.get(field));
+            int bind_index = sql_bind_query_phrases(stmt, 0, query_phrases);
             if (limit > 0) {
                 stmt.bind_int(bind_index++, limit);
                 stmt.bind_int(bind_index++, offset);
@@ -873,25 +886,26 @@ private class Geary.ImapDB.Account : BaseObject {
         Gee.Collection<ImapDB.EmailIdentifier> ids, Cancellable? cancellable = null) throws Error {
         check_open();
         
-        Gee.Set<string> search_matches = new Gee.HashSet<string>();
+        Gee.HashMap<string, string> query_phrases = get_query_phrases(query);
+        if (query_phrases.size == 0)
+            return null;
         
-        // Create a question mark for each ID.
-        string id_string = "";
-        for(int i = 0; i < ids.size; i++) {
-            id_string += "?";
-            if (i != ids.size - 1)
-                id_string += ", ";
-        }
+        Gee.Set<string> search_matches = new Gee.HashSet<string>();
         
         yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
-            Db.Statement stmt = cx.prepare("SELECT offsets(MessageSearchTable), * FROM MessageSearchTable " +
-                "WHERE MessageSearchTable MATCH ? AND id IN (%s)".printf(id_string));
-            
-            // Bind query and IDs.
-            int i = 0;
-            stmt.bind_string(i++, prepared_query);
-            foreach(ImapDB.EmailIdentifier id in ids)
-                stmt.bind_rowid(i++, id.message_id);
+            StringBuilder sql = new StringBuilder();
+            sql.append("""
+                SELECT offsets(MessageSearchTable), *
+                FROM MessageSearchTable
+                WHERE id IN (
+            """);
+            sql_append_ids(sql,
+                Geary.traverse<ImapDB.EmailIdentifier>(ids).map<int64?>(id => 
id.message_id).to_gee_iterable());
+            sql.append(")");
+            sql_add_query_phrases(sql, query_phrases);
+            
+            Db.Statement stmt = cx.prepare(sql.str);
+            sql_bind_query_phrases(stmt, 0, query_phrases);
             
             Db.Result result = stmt.exec(cancellable);
             while (!result.finished) {


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