[evolution-data-server] libebook: Support phone number specific queries



commit 663c169ef8a02c2900c56284b21055aa1aa67045
Author: Mathias Hasselmann <mathias openismus com>
Date:   Wed Dec 12 00:09:24 2012 +0100

    libebook: Support phone number specific queries
    
    This adds new values to the EBookQueryTest enumeration:
    
     * E_BOOK_QUERY_EQUALS_PHONE_NUMBER
     * E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER
     * E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER
    
    This values get translated to the binary sexp functions "eqphone",
    "eqphone_national" and "eqphone_short".
    
    See: https://bugzilla.gnome.org/show_bug.cgi?id=689622

 addressbook/libebook/e-book-query.c                |   71 ++++++++++++++++---
 addressbook/libebook/e-book-query.h                |   18 +++++-
 addressbook/libedata-book/e-book-backend-sexp.c    |   73 +++++++++++++++++++-
 tests/libebook/client/test-client-custom-summary.c |   12 +++
 tests/libebook/data/vcards/custom-1.vcf            |    2 +-
 tests/libebook/test-query.c                        |   18 +++++
 6 files changed, 179 insertions(+), 15 deletions(-)
---
diff --git a/addressbook/libebook/e-book-query.c b/addressbook/libebook/e-book-query.c
index 1d845c4..7960b71 100644
--- a/addressbook/libebook/e-book-query.c
+++ b/addressbook/libebook/e-book-query.c
@@ -519,6 +519,33 @@ func_endswith (struct _ESExp *f,
 }
 
 static ESExpResult *
+func_eqphone (struct _ESExp *f,
+              gint argc,
+              struct _ESExpResult **argv,
+              gpointer data)
+{
+	return func_field_test (E_BOOK_QUERY_EQUALS_PHONE_NUMBER, f, argc, argv, data);
+}
+
+static ESExpResult *
+func_eqphone_national (struct _ESExp *f,
+                       gint argc,
+                       struct _ESExpResult **argv,
+                       gpointer data)
+{
+	return func_field_test (E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER, f, argc, argv, data);
+}
+
+static ESExpResult *
+func_eqphone_short (struct _ESExp *f,
+                    gint argc,
+                    struct _ESExpResult **argv,
+                    gpointer data)
+{
+	return func_field_test (E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER, f, argc, argv, data);
+}
+
+static ESExpResult *
 func_exists (struct _ESExp *f,
              gint argc,
              struct _ESExpResult **argv,
@@ -578,6 +605,9 @@ static const struct {
 	{ "is", func_is, 0 },
 	{ "beginswith", func_beginswith, 0 },
 	{ "endswith", func_endswith, 0 },
+	{ "eqphone", func_eqphone, 0 },
+	{ "eqphone_national", func_eqphone_national, 0 },
+	{ "eqphone_short", func_eqphone_short, 0 },
 	{ "exists", func_exists, 0 },
 	{ "exists_vcard", func_exists_vcard, 0 }
 };
@@ -636,6 +666,29 @@ e_book_query_from_string (const gchar *query_string)
 	return retval;
 }
 
+static const char *
+field_test_name (EBookQueryTest field_test)
+{
+	switch (field_test) {
+	case E_BOOK_QUERY_IS:
+		return "is";
+	case E_BOOK_QUERY_CONTAINS:
+		return "contains";
+	case E_BOOK_QUERY_BEGINS_WITH:
+		return "beginswith";
+	case E_BOOK_QUERY_ENDS_WITH:
+		return "endswith";
+	case E_BOOK_QUERY_EQUALS_PHONE_NUMBER:
+		return "eqphone";
+	case E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER:
+		return "eqphone_national";
+	case E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER:
+		return "eqphone_short";
+	}
+
+	return NULL;
+}
+
 /**
  * e_book_query_to_string:
  * @q: an #EBookQuery
@@ -652,7 +705,6 @@ e_book_query_to_string (EBookQuery *q)
 	GString *encoded = g_string_new ("");
 	gint i;
 	gchar *s = NULL;
-	const gchar *cs;
 
 	switch (q->type) {
 	case E_BOOK_QUERY_TYPE_AND:
@@ -686,21 +738,18 @@ e_book_query_to_string (EBookQuery *q)
 		}
 		break;
 	case E_BOOK_QUERY_TYPE_FIELD_TEST:
-		switch (q->query.field_test.test) {
-		case E_BOOK_QUERY_IS: cs = "is"; break;
-		case E_BOOK_QUERY_CONTAINS: cs = "contains"; break;
-		case E_BOOK_QUERY_BEGINS_WITH: cs = "beginswith"; break;
-		case E_BOOK_QUERY_ENDS_WITH: cs = "endswith"; break;
-		default:
-			g_assert_not_reached ();
-			break;
+		s = field_test_name (q->query.field_test.test);
+
+		if (s == NULL) {
+			g_string_free (str, TRUE);
+			g_warn_if_reached ();
+			return NULL;
 		}
 
 		e_sexp_encode_string (encoded, q->query.field_test.value);
 
 		g_string_append_printf (
-			str, "%s \"%s\" %s",
-			cs,
+			str, "%s \"%s\" %s", s,
 			q->query.field_test.field_name,
 			encoded->str);
 		break;
diff --git a/addressbook/libebook/e-book-query.h b/addressbook/libebook/e-book-query.h
index 59c8987..82342b4 100644
--- a/addressbook/libebook/e-book-query.h
+++ b/addressbook/libebook/e-book-query.h
@@ -20,14 +20,30 @@ typedef struct EBookQuery EBookQuery;
  * @E_BOOK_QUERY_CONTAINS: check if a field contains the test value
  * @E_BOOK_QUERY_BEGINS_WITH: check if a field starts with the test value
  * @E_BOOK_QUERY_ENDS_WITH: check if a field ends with the test value
+ * @E_BOOK_QUERY_EQUALS_PHONE_NUMBER: check that a field and the test value
+ * match exactly when interpreted as phone number, that is after stripping
+ * formatting like dashes, dots and spaces. See E_PHONE_NUMBER_MATCH_EXACT.
+ * @E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER: check that a field and the
+ * test value match when interpreted as phone number, except for the
+ * (omitted) country code.
+ * @E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER: check that a field and the test
+ * value match is the sense that both values appear to be phone numbers,
+ * and one might be a part (suffix) of the other.
  *
  * The kind of test a query created by e_book_query_field_test() shall perform.
+ *
+ * See also: E_PHONE_NUMBER_MATCH_EXACT, E_PHONE_NUMBER_MATCH_NATIONAL and
+ * E_PHONE_NUMBER_MATCH_SHORT.
  **/
 typedef enum {
   E_BOOK_QUERY_IS,
   E_BOOK_QUERY_CONTAINS,
   E_BOOK_QUERY_BEGINS_WITH,
-  E_BOOK_QUERY_ENDS_WITH
+  E_BOOK_QUERY_ENDS_WITH,
+
+  E_BOOK_QUERY_EQUALS_PHONE_NUMBER,
+  E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER,
+  E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER
 
   /*
     Consider these "coming soon".
diff --git a/addressbook/libedata-book/e-book-backend-sexp.c b/addressbook/libedata-book/e-book-backend-sexp.c
index 2789a73..5ef2ffb 100644
--- a/addressbook/libedata-book/e-book-backend-sexp.c
+++ b/addressbook/libedata-book/e-book-backend-sexp.c
@@ -18,10 +18,10 @@
  * 02110-1301, USA.
  */
 
-#include <string.h>
-
 #include "e-book-backend-sexp.h"
 
+#include <string.h>
+
 #define E_BOOK_BACKEND_SEXP_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_BOOK_BACKEND_SEXP, EBookBackendSExpPrivate))
@@ -745,6 +745,72 @@ func_beginswith (struct _ESExp *f,
 }
 
 static gboolean
+eqphone_helper (const gchar *ps1,
+                const gchar *ps2,
+                EPhoneNumberMatch required_match)
+{
+	const EPhoneNumberMatch actual_match =
+		e_phone_number_compare_strings (ps1, ps2, NULL);
+
+	return actual_match >= E_PHONE_NUMBER_MATCH_EXACT
+		&& actual_match <= required_match;
+}
+
+static gboolean
+eqphone_exact_helper (const gchar *ps1,
+                      const gchar *ps2)
+{
+	return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_EXACT);
+}
+
+static gboolean
+eqphone_national_helper (const gchar *ps1,
+                         const gchar *ps2)
+{
+	return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_NATIONAL);
+}
+
+static gboolean
+eqphone_short_helper (const gchar *ps1,
+                      const gchar *ps2)
+{
+	return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_SHORT);
+}
+
+static ESExpResult *
+func_eqphone (struct _ESExp *f,
+              gint argc,
+              struct _ESExpResult **argv,
+              gpointer data)
+{
+	SearchContext *ctx = data;
+
+	return entry_compare (ctx, f, argc, argv, eqphone_exact_helper);
+}
+
+static ESExpResult *
+func_eqphone_national (struct _ESExp *f,
+                       gint argc,
+                       struct _ESExpResult **argv,
+                       gpointer data)
+{
+	SearchContext *ctx = data;
+
+	return entry_compare (ctx, f, argc, argv, eqphone_national_helper);
+}
+
+static ESExpResult *
+func_eqphone_short (struct _ESExp *f,
+                    gint argc,
+                    struct _ESExpResult **argv,
+                    gpointer data)
+{
+	SearchContext *ctx = data;
+
+	return entry_compare (ctx, f, argc, argv, eqphone_short_helper);
+}
+
+static gboolean
 exists_helper (const gchar *ps1,
                const gchar *ps2)
 {
@@ -895,6 +961,9 @@ static struct {
 	{ "is", func_is, 0 },
 	{ "beginswith", func_beginswith, 0 },
 	{ "endswith", func_endswith, 0 },
+	{ "eqphone", func_eqphone, 0 },
+	{ "eqphone_national", func_eqphone_national, 0 },
+	{ "eqphone_short", func_eqphone_short, 0 },
 	{ "exists", func_exists, 0 },
 	{ "exists_vcard", func_exists_vcard, 0 },
 };
diff --git a/tests/libebook/client/test-client-custom-summary.c b/tests/libebook/client/test-client-custom-summary.c
index c7f88f0..654fd5b 100644
--- a/tests/libebook/client/test-client-custom-summary.c
+++ b/tests/libebook/client/test-client-custom-summary.c
@@ -186,6 +186,18 @@ main (gint argc,
 		"/client/search/suffix/email", search_test,
 		e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_ENDS_WITH, "jackson.com"),
 		2);
+	add_client_test (
+		"/client/search/eqphone/exact/phone", search_test,
+		e_book_query_vcard_field_test(EVC_TEL, E_BOOK_QUERY_EQUALS_PHONE_NUMBER, "+1 221.542.3789"),
+		1);
+	add_client_test (
+		"/client/search/eqphone/national/phone", search_test,
+		e_book_query_vcard_field_test(EVC_TEL, E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER, "221.542.3789"),
+		1);
+	add_client_test (
+		"/client/search/eqphone/short/phone", search_test,
+		e_book_query_vcard_field_test(EVC_TEL, E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER, "5423789"),
+		1);
 
 	/* Add search tests that fetch uids */
 	add_client_test (
diff --git a/tests/libebook/data/vcards/custom-1.vcf b/tests/libebook/data/vcards/custom-1.vcf
index bc9a23c..6d7241b 100644
--- a/tests/libebook/data/vcards/custom-1.vcf
+++ b/tests/libebook/data/vcards/custom-1.vcf
@@ -1,5 +1,5 @@
 BEGIN:VCARD
 FN:Micheal Jackson
-TEL;HOME:+1234567
+TEL;HOME:+1-221-5423789
 EMAIL;TYPE=home,work:micheal jackson com
 END:VCARD
diff --git a/tests/libebook/test-query.c b/tests/libebook/test-query.c
index cc687c8..f2a155b 100644
--- a/tests/libebook/test-query.c
+++ b/tests/libebook/test-query.c
@@ -137,5 +137,23 @@ main (gint argc,
 	                                         "5423789"),
 	                "(endswith \"phone\" \"5423789\")");
 
+	add_query_test ("/libebook/test-query/sexp/eqphone",
+
+	                e_book_query_orv (e_book_query_field_test (E_CONTACT_TEL,
+	                                                           E_BOOK_QUERY_EQUALS_PHONE_NUMBER,
+	                                                           "+1-2215423789"),
+	                                  e_book_query_field_test (E_CONTACT_TEL,
+	                                                           E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER,
+	                                                           "2215423789"),
+	                                  e_book_query_field_test (E_CONTACT_TEL,
+	                                                           E_BOOK_QUERY_EQUALS_SHORT_PHONE_NUMBER,
+	                                                           "5423789"),
+	                                  NULL),
+
+	                "(or (eqphone \"phone\" \"+1-2215423789\")"
+	                   " (eqphone_national \"phone\" \"2215423789\")"
+	                   " (eqphone_short \"phone\" \"5423789\")"
+	                   " )");
+
 	return g_test_run ();
 }



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