[evolution-data-server] Bug #610353 - Search folder with label matches on substring



commit 0e7f9c5e3d849bc1b89c430311d3a3d13810aa15
Author: Milan Crha <mcrha redhat com>
Date:   Thu Apr 1 14:58:55 2010 +0200

    Bug #610353 - Search folder with label matches on substring

 camel/camel-db.c              |   47 ++++++++++++++++++++++++++++++++++++++++-
 camel/camel-folder-summary.c  |    3 +-
 camel/camel-search-sql-sexp.c |    4 +-
 3 files changed, 50 insertions(+), 4 deletions(-)
---
diff --git a/camel/camel-db.c b/camel/camel-db.c
index fd7674e..8aa64a3 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -28,8 +28,10 @@
 
 #include <config.h>
 
-#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -392,6 +394,47 @@ cdb_sql_exec (sqlite3 *db, const gchar * stmt, CamelException *ex)
 	return 0;
 }
 
+/* checks whether string 'where' contains whole word 'what',
+   case insensitively (ascii, not utf8, same as 'LIKE' in SQLite3)
+*/
+static void
+cdb_match_func (sqlite3_context *ctx, int nArgs, sqlite3_value **values)
+{
+	gboolean matches = FALSE;
+	const gchar *what, *where;
+
+	g_return_if_fail (ctx != NULL);
+	g_return_if_fail (nArgs == 2);
+	g_return_if_fail (values != NULL);
+
+	what = (const gchar *) sqlite3_value_text (values[0]);
+	where = (const gchar *) sqlite3_value_text (values[1]);
+
+	if (what && where && !*what) {
+		matches = TRUE;
+	} else if (what && where) {
+		gboolean word = TRUE;
+		gint i, j;
+
+		for (i = 0, j = 0; where[i] && !matches; i++) {
+			char c = where[i];
+
+			if (c == ' ') {
+				word = TRUE;
+				j = 0;
+			} else if (word && tolower (c) == tolower(what[j])) {
+				j++;
+				if (what[j] == 0 && (where[i + 1] == 0 || isspace (where[i + 1])))
+					matches = TRUE;
+			} else {
+				word = FALSE;
+			}
+		}
+	}
+
+	sqlite3_result_int (ctx, matches ? 1 : 0);
+}
+
 /**
  * camel_db_open:
  *
@@ -432,6 +475,8 @@ camel_db_open (const gchar *path, CamelException *ex)
 	cdb->priv->timer = NULL;
 	d(g_print ("\nDatabase succesfully opened  \n"));
 
+	sqlite3_create_function (db, "MATCH", 2, SQLITE_UTF8, NULL, cdb_match_func, NULL, NULL);
+
 	/* Which is big / costlier ? A Stack frame or a pointer */
 	if (g_getenv("CAMEL_SQLITE_DEFAULT_CACHE_SIZE")!=NULL) {
 		gchar *cache = NULL;
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 7513bf9..41ab96b 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -3331,7 +3331,8 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 
 			if (part[i] == ' ') {
 				part[i] = 0;
-				camel_flag_set(&mi->user_flags, label, TRUE);
+				if (*label)
+					camel_flag_set (&mi->user_flags, label, TRUE);
 				label = &(part[i+1]);
 			}
 		}
diff --git a/camel/camel-search-sql-sexp.c b/camel/camel-search-sql-sexp.c
index b2785ac..def0937 100644
--- a/camel/camel-search-sql-sexp.c
+++ b/camel/camel-search-sql-sexp.c
@@ -464,10 +464,10 @@ user_flag(struct _ESExp *f, gint argc, struct _ESExpResult **argv, gpointer data
 	if (argc != 1) {
 		r->value.string = g_strdup ("(0)");
 	} else {
-		tstr = g_strdup_printf("%%%s%%", argv[0]->value.string);
+		tstr = g_strdup_printf("%s", argv[0]->value.string);
 		qstr = get_db_safe_string(tstr);
 		g_free(tstr);
-		r->value.string = g_strdup_printf("(labels LIKE %s)", qstr);
+		r->value.string = g_strdup_printf("(labels MATCH %s)", qstr);
 		g_free(qstr);
 	}
 



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