[Patch v2 5/5] lib: add status return to notmuch_query_count_{message,threads}

David Bremner david at tethera.net
Tue Dec 30 12:29:40 PST 2014


We follow many other notmuch_ functions by having a status return and
an output parameter.  I decided not to add compatibility wrappers but
just to break the API because the old API seems worth encouraging
people to move away from.  This change is large than might otherwise be desirable because it updates the CLI, the python bindings and the ruby bindings (but not the go bindings).
---
 bindings/python/notmuch/globals.py |  4 ++--
 bindings/python/notmuch/query.py   | 18 +++++++++++++-----
 bindings/ruby/query.c              | 26 ++++++++++++++++----------
 lib/Makefile.local                 |  4 ++--
 lib/database.cc                    |  8 +++++++-
 lib/notmuch.h                      | 26 +++++++++++++++++++-------
 lib/query.cc                       | 24 +++++++++++++-----------
 notmuch-count.c                    | 14 ++++++++++++--
 notmuch-reply.c                    |  8 +++++++-
 notmuch-search.c                   | 14 ++++++++++++--
 notmuch-show.c                     |  8 +++++++-
 11 files changed, 110 insertions(+), 44 deletions(-)

diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py
index 24b25d3..85aab39 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -24,9 +24,9 @@ from ctypes import CDLL, Structure, POINTER
 try:
     from os import uname
     if uname()[0] == 'Darwin':
-        nmlib = CDLL("libnotmuch.4.dylib")
+        nmlib = CDLL("libnotmuch.5.dylib")
     else:
-        nmlib = CDLL("libnotmuch.so.4")
+        nmlib = CDLL("libnotmuch.so.5")
 except:
     raise ImportError("Could not find shared 'notmuch' library.")
 
diff --git a/bindings/python/notmuch/query.py b/bindings/python/notmuch/query.py
index 94773ac..96fc1cd 100644
--- a/bindings/python/notmuch/query.py
+++ b/bindings/python/notmuch/query.py
@@ -17,7 +17,7 @@ along with notmuch.  If not, see <http://www.gnu.org/licenses/>.
 Copyright 2010 Sebastian Spaeth <Sebastian at SSpaeth.de>
 """
 
-from ctypes import c_char_p, c_uint
+from ctypes import c_char_p, c_uint, POINTER, byref
 from .globals import (
     nmlib,
     Enum,
@@ -179,7 +179,7 @@ class Query(object):
         return Messages(msgs_p, self)
 
     _count_messages = nmlib.notmuch_query_count_messages
-    _count_messages.argtypes = [NotmuchQueryP]
+    _count_messages.argtypes = [NotmuchQueryP, POINTER(c_uint)]
     _count_messages.restype = c_uint
 
     def count_messages(self):
@@ -191,10 +191,14 @@ class Query(object):
         :rtype:   int
         '''
         self._assert_query_is_initialized()
-        return Query._count_messages(self._query)
+        count = c_uint(0)
+        status = Query._count_messages(self._query, byref(count))
+        if status != 0:
+            raise NotmuchError(status)
+        return count.value
 
     _count_threads = nmlib.notmuch_query_count_threads
-    _count_threads.argtypes = [NotmuchQueryP]
+    _count_threads.argtypes = [NotmuchQueryP, POINTER(c_uint)]
     _count_threads.restype = c_uint
 
     def count_threads(self):
@@ -210,7 +214,11 @@ class Query(object):
         :rtype:   int
         '''
         self._assert_query_is_initialized()
-        return Query._count_threads(self._query)
+        count = c_uint(0)
+        status = Query._count_threads(self._query, byref(count))
+        if status != 0:
+            raise NotmuchError(status)
+        return count.value
 
     _destroy = nmlib.notmuch_query_destroy
     _destroy.argtypes = [NotmuchQueryP]
diff --git a/bindings/ruby/query.c b/bindings/ruby/query.c
index a7dacba..d39b6bc 100644
--- a/bindings/ruby/query.c
+++ b/bindings/ruby/query.c
@@ -173,14 +173,17 @@ VALUE
 notmuch_rb_query_count_messages (VALUE self)
 {
     notmuch_query_t *query;
+    notmuch_status_t status;
+    unsigned count;
 
     Data_Get_Notmuch_Query (self, query);
 
-    /* Xapian exceptions are not handled properly.
-     * (function may return 0 after printing a message)
-     * Thus there is nothing we can do here...
-     */
-    return UINT2NUM(notmuch_query_count_messages(query));
+    status = notmuch_query_count_messages(query, &count);
+
+    if (status)
+	notmuch_rb_status_raise (status);
+    else
+	return UINT2NUM(count);
 }
 
 /*
@@ -192,12 +195,15 @@ VALUE
 notmuch_rb_query_count_threads (VALUE self)
 {
     notmuch_query_t *query;
+    notmuch_status_t status;
+    unsigned count;
 
     Data_Get_Notmuch_Query (self, query);
 
-    /* Xapian exceptions are not handled properly.
-     * (function may return 0 after printing a message)
-     * Thus there is nothing we can do here...
-     */
-    return UINT2NUM(notmuch_query_count_threads(query));
+    status = notmuch_query_count_threads(query, &count);
+    if (status)
+	notmuch_rb_status_raise (status);
+    else
+	return UINT2NUM(count);
+
 }
diff --git a/lib/Makefile.local b/lib/Makefile.local
index 4120390..4bf8116 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -5,13 +5,13 @@
 # the library interface, (such as the deletion of an API or a major
 # semantic change that breaks formerly functioning code).
 #
-LIBNOTMUCH_VERSION_MAJOR = 4
+LIBNOTMUCH_VERSION_MAJOR = 5
 
 # The minor version of the library interface. This should be incremented at
 # the time of release for any additions to the library interface,
 # (and when it is incremented, the release version of the library should
 #  be reset to 0).
-LIBNOTMUCH_VERSION_MINOR = 1
+LIBNOTMUCH_VERSION_MINOR = 0
 
 # The release version the library interface. This should be incremented at
 # the time of release if there have been no changes to the interface, (but
diff --git a/lib/database.cc b/lib/database.cc
index 3601f9d..b7fbc63 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -1268,7 +1268,13 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
     if (new_features &
 	(NOTMUCH_FEATURE_FILE_TERMS | NOTMUCH_FEATURE_BOOL_FOLDER)) {
 	notmuch_query_t *query = notmuch_query_create (notmuch, "");
-	total += notmuch_query_count_messages (query);
+	unsigned msg_count;
+
+	status = notmuch_query_count_messages (query, &msg_count);
+	if (status)
+	    goto DONE;
+
+	total += msg_count;
 	notmuch_query_destroy (query);
     }
     if (new_features & NOTMUCH_FEATURE_DIRECTORY_DOCS) {
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 220839b..37bf0bd 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -898,11 +898,15 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
  * This function performs a search and returns Xapian's best
  * guess as to number of matching messages.
  *
- * If a Xapian exception occurs, this function may return 0 (after
- * printing a message).
+ * Return value:
+ *
+ * NOTMUCH_STATUS_SUCCESS: query complete successfully.
+ *
+ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occured. The
+ *      value of *count is not defined.
  */
-unsigned
-notmuch_query_count_messages (notmuch_query_t *query);
+notmuch_status_t
+notmuch_query_count_messages (notmuch_query_t *query, unsigned *count);
 
 /**
  * Return the number of threads matching a search.
@@ -914,10 +918,18 @@ notmuch_query_count_messages (notmuch_query_t *query);
  * Note that this is a significantly heavier operation than
  * notmuch_query_count_messages().
  *
- * If an error occurs, this function may return 0.
+ * Return value:
+ *
+ * NOTMUCH_STATUS_OUT_OF_MEMORY: Memory allocation failed. The value
+ *      of *count is not defined
+
+ * NOTMUCH_STATUS_SUCCESS: query complete successfully.
+ *
+ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occured. The
+ *      value of *count is not defined.
  */
-unsigned
-notmuch_query_count_threads (notmuch_query_t *query);
+notmuch_status_t
+notmuch_query_count_threads (notmuch_query_t *query, unsigned *count);
 
 /**
  * Get the thread ID of 'thread'.
diff --git a/lib/query.cc b/lib/query.cc
index 60ff8bd..10ecf2e 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -508,8 +508,8 @@ notmuch_threads_destroy (notmuch_threads_t *threads)
     talloc_free (threads);
 }
 
-unsigned
-notmuch_query_count_messages (notmuch_query_t *query)
+notmuch_status_t
+notmuch_query_count_messages (notmuch_query_t *query, unsigned *count_out)
 {
     notmuch_database_t *notmuch = query->notmuch;
     const char *query_string = query->query_string;
@@ -565,30 +565,32 @@ notmuch_query_count_messages (notmuch_query_t *query)
 	fprintf (stderr, "A Xapian exception occurred: %s\n",
 		 error.get_msg().c_str());
 	fprintf (stderr, "Query string was: %s\n", query->query_string);
+	return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
 
-    return count;
+    *count_out=count;
+    return NOTMUCH_STATUS_SUCCESS;
 }
 
-unsigned
-notmuch_query_count_threads (notmuch_query_t *query)
+notmuch_status_t
+notmuch_query_count_threads (notmuch_query_t *query, unsigned *count)
 {
     notmuch_messages_t *messages;
     GHashTable *hash;
-    unsigned int count;
     notmuch_sort_t sort;
+    notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
 
     sort = query->sort;
     query->sort = NOTMUCH_SORT_UNSORTED;
     messages = notmuch_query_search_messages (query);
     query->sort = sort;
     if (messages == NULL)
-	return 0;
+	return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
 
     hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
     if (hash == NULL) {
 	talloc_free (messages);
-	return 0;
+	return NOTMUCH_STATUS_OUT_OF_MEMORY;
     }
 
     while (notmuch_messages_valid (messages)) {
@@ -597,7 +599,7 @@ notmuch_query_count_threads (notmuch_query_t *query)
 	char *thread_id_copy = talloc_strdup (messages, thread_id);
 	if (unlikely (thread_id_copy == NULL)) {
 	    notmuch_message_destroy (message);
-	    count = 0;
+	    ret = NOTMUCH_STATUS_OUT_OF_MEMORY;
 	    goto DONE;
 	}
 	g_hash_table_insert (hash, thread_id_copy, NULL);
@@ -605,11 +607,11 @@ notmuch_query_count_threads (notmuch_query_t *query)
 	notmuch_messages_move_to_next (messages);
     }
 
-    count = g_hash_table_size (hash);
+    *count = g_hash_table_size (hash);
 
   DONE:
     g_hash_table_unref (hash);
     talloc_free (messages);
 
-    return count;
+    return ret;
 }
diff --git a/notmuch-count.c b/notmuch-count.c
index 6058f7c..7e3c1b7 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -71,6 +71,8 @@ print_count (notmuch_database_t *notmuch, const char *query_str,
 {
     notmuch_query_t *query;
     size_t i;
+    unsigned count;
+    notmuch_status_t status;
 
     query = notmuch_query_create (notmuch, query_str);
     if (query == NULL) {
@@ -83,10 +85,18 @@ print_count (notmuch_database_t *notmuch, const char *query_str,
 
     switch (output) {
     case OUTPUT_MESSAGES:
-	printf ("%u\n", notmuch_query_count_messages (query));
+	if ((status = notmuch_query_count_messages (query, &count))) {
+	    fprintf (stderr, "Error: %s\n", notmuch_status_to_string (status));
+	    return 1;
+	}
+	printf ("%u\n", count);
 	break;
     case OUTPUT_THREADS:
-	printf ("%u\n", notmuch_query_count_threads (query));
+	if ((status = notmuch_query_count_threads (query, &count))) {
+	    fprintf (stderr, "Error: %s\n", notmuch_status_to_string (status));
+	    return 1;
+	}
+	printf ("%u\n", count);
 	break;
     case OUTPUT_FILES:
 	printf ("%u\n", count_files (query));
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 7c1c809..c5f1b92 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -650,8 +650,14 @@ notmuch_reply_format_sprinter(void *ctx,
     notmuch_messages_t *messages;
     notmuch_message_t *message;
     mime_node_t *node;
+    unsigned count;
+    notmuch_status_t status;
 
-    if (notmuch_query_count_messages (query) != 1) {
+    if ((status = notmuch_query_count_messages (query, &count))) {
+	fprintf (stderr, "Error: %s.\n", notmuch_status_to_string (status));
+	return 1;
+    }
+    if (count != 1) {
 	fprintf (stderr, "Error: search term did not match precisely one message.\n");
 	return 1;
     }
diff --git a/notmuch-search.c b/notmuch-search.c
index 14b9f01..cadfc0c 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -113,7 +113,14 @@ do_search_threads (search_context_t *ctx)
     int i;
 
     if (ctx->offset < 0) {
-	ctx->offset += notmuch_query_count_threads (ctx->query);
+	unsigned count;
+	notmuch_status_t status;
+	if ((status = notmuch_query_count_threads (ctx->query, &count))) {
+	    fprintf (stderr, "Error: %s\n", notmuch_status_to_string (status));
+	    return 1;
+	}
+
+	ctx->offset += count;
 	if (ctx->offset < 0)
 	    ctx->offset = 0;
     }
@@ -414,7 +421,10 @@ do_search_messages (search_context_t *ctx)
     int i;
 
     if (ctx->offset < 0) {
-	ctx->offset += notmuch_query_count_messages (ctx->query);
+	unsigned count;
+	if (notmuch_query_count_messages (ctx->query, &count))
+	    return 1;
+	ctx->offset += count;
 	if (ctx->offset < 0)
 	    ctx->offset = 0;
     }
diff --git a/notmuch-show.c b/notmuch-show.c
index d416fbd..16835a3 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -982,8 +982,14 @@ do_show_single (void *ctx,
 {
     notmuch_messages_t *messages;
     notmuch_message_t *message;
+    unsigned count;
+    notmuch_status_t status;
+    if ((status = notmuch_query_count_messages (query, &count))) {
+	fprintf (stderr, "Error: %s\n", notmuch_status_to_string (status));
+	return 1;
+    }
 
-    if (notmuch_query_count_messages (query) != 1) {
+    if (count != 1) {
 	fprintf (stderr, "Error: search term did not match precisely one message.\n");
 	return 1;
     }
-- 
2.1.3



More information about the notmuch mailing list