[Xfce4-commits] <postler:master> Interpret spaces in search as AND conditions

Christian Dywan noreply at xfce.org
Mon Jul 11 23:14:01 CEST 2011


Updating branch refs/heads/master
         to bb4be23780ed26841d2c1ed40f0d3a2ab43356e7 (commit)
       from 2e798c28c9bab5540d6be5335cfdcea76137f717 (commit)

commit bb4be23780ed26841d2c1ed40f0d3a2ab43356e7
Author: Christian Dywan <christian at twotoasts.de>
Date:   Sun Jul 10 23:26:03 2011 +0200

    Interpret spaces in search as AND conditions

 postler/postler-index.vala |   58 +++++++++++++++++++++++++++----------------
 1 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/postler/postler-index.vala b/postler/postler-index.vala
index ad940c9..f33c480 100644
--- a/postler/postler-index.vala
+++ b/postler/postler-index.vala
@@ -227,7 +227,9 @@ namespace Postler {
             statement_remove.reset ();
         }
 
-        string search_statement (string folder, string sql,
+        const string[] any_fields = { "subject", "sender", "excerpt" };
+
+        void search_statement (string folder, string sql,
             ref Sqlite.Statement statement) throws GLib.Error {
 
             /* file:// or search:field/value */
@@ -245,42 +247,55 @@ namespace Postler {
                     field = "excerpt";
                 /* We can use the prepared statement for uri search */
                 if (field != "uri") {
-                    /* any is an alias for subject, sender, attachment, excerpt */
-                    /* FIXME: attachment is not indexed yet */
-                    if (field == "any")
-                        field = "sender LIKE ?2 OR excerpt LIKE ?2 OR subject";
+                    var cond = new StringBuilder ("(");
+                    foreach (string word in parts[1].split (" ")) {
+                        /* * is a wildcard, ' must be escaped by doubling it */
+                        string escaped = word.replace ("*", "%").replace ("\'", "\'\'");
+                        /* any is an alias for subject, sender, attachment, excerpt */
+                        /* FIXME: attachment is not indexed yet */
+                        if (field == "any") {
+                            var any_cond = new StringBuilder ("(");
+                            foreach (string any_field in any_fields)
+                                any_cond.append_printf ("%s LIKE '%%%s%%' OR ", any_field, escaped);
+                            cond.append_printf ("%s) AND ",
+                                any_cond.truncate (any_cond.len - 3).str);
+                        }
+                        else
+                            cond.append_printf ("%s LIKE '%%%s%%' AND ", field, escaped);
+                    }
+                    cond.truncate (cond.len - 4);
                     /* Filter out Trash and Junk */
-                    string real_sql = sql.replace ("$CASE",
-                        "AND uri NOT LIKE '%/Trash/%' AND uri NOT LIKE '%/Junk/%'");
-                    if (database.prepare_v2 (real_sql.replace ("$FIELD", field),
+                    cond.append (") AND uri NOT LIKE '%/Trash/%' AND uri NOT LIKE '%/Junk/%'");
+                    if (database.prepare_v2 (sql.replace ("$CASE", cond.str),
                                              -1, out statement) != Sqlite.OK)
                         throw new GLib.FileError.FAILED (_("Failed to list messages: %s"), database.errmsg ());
+                    return;
                 }
-                /* Space is a wildcard */
-                /* * is a wildcard */
-                return "%%%s%%".printf (parts[1].replace (" ", "%").replace ("*", "%"));
+                if (statement.bind_text (2, "%%%s%%".printf (parts[1]), -1) != Sqlite.OK)
+                    throw new GLib.FileError.FAILED (_("Failed to list messages: %s"), database.errmsg ());
+                return;
             }
-            return folder;
+            if (statement.bind_text (2, folder, -1) != Sqlite.OK)
+                throw new GLib.FileError.FAILED (_("Failed to list messages: %s"), database.errmsg ());
         }
 
         public int64[] unread_messages (string folder) throws GLib.Error {
             unowned string sql = """
                 SELECT unread, COUNT (*) FROM messages
-                WHERE $FIELD LIKE ?2 $CASE GROUP BY unread
+                WHERE $CASE GROUP BY unread
                 """;
 
             if (statement_unread == null) {
-                if (database.prepare_v2 (sql.replace ("$FIELD", "uri").replace ("$CASE", ""),
+                if (database.prepare_v2 (sql.replace ("$CASE", "uri LIKE ?2"),
                                          -1, out statement_unread) != Sqlite.OK)
                     throw new GLib.FileError.FAILED (_("Failed to count unread messages: %s"), database.errmsg ());
             }
             Sqlite.Statement? temporary_statement = null;
-            string search_value = search_statement (folder, sql, ref temporary_statement);
+            search_statement (folder, sql, ref temporary_statement);
             unowned Sqlite.Statement statement = temporary_statement != null
                                                ? temporary_statement : statement_unread;
             int result = Sqlite.ERROR;
-            bool success = statement.bind_text (2, search_value, -1) == Sqlite.OK
-             && (row_or_done ((result = statement.step ())));
+            bool success = row_or_done ((result = statement.step ()));
             if (!success) {
                 statement.reset ();
                 throw new GLib.FileError.FAILED (_("Failed to count unread messages: %s"), database.errmsg ());
@@ -360,24 +375,23 @@ namespace Postler {
         public string[] get_messages (string folder) throws GLib.Error {
             unowned string sql = """
                 SELECT threads AS thread_id FROM messages
-                WHERE $FIELD LIKE ?2 $CASE GROUP BY threads
+                WHERE $CASE GROUP BY threads
                 HAVING (SELECT COUNT (*) FROM messages WHERE id = thread_id)
                 ORDER BY date ASC
                 """;
 
             if (statement_list == null) {
-                if (database.prepare_v2 (sql.replace ("$FIELD", "uri").replace ("$CASE", ""),
+                if (database.prepare_v2 (sql.replace ("$CASE", "uri LIKE ?2"),
                                          -1, out statement_list) != Sqlite.OK)
                     throw new GLib.FileError.FAILED (_("Failed to list messages: %s"), database.errmsg ());
             }
 
             Sqlite.Statement? temporary_statement = null;
-            string search_value = search_statement (folder, sql, ref temporary_statement);
+            search_statement (folder, sql, ref temporary_statement);
             unowned Sqlite.Statement statement = temporary_statement != null
                                                ? temporary_statement : statement_list;
-            bool success = statement.bind_text (2, search_value, -1) == Sqlite.OK;
             int result = Sqlite.ERROR;
-            success = success && row_or_done (((result = statement.step ())));
+            bool success = row_or_done (((result = statement.step ())));
             if (!success) {
                 statement.reset ();
                 throw new GLib.FileError.FAILED (_("Failed to list messages: %s"), database.errmsg ());



More information about the Xfce4-commits mailing list