Add notmuch_message_add_tag and notmuch_message_remove_tag
authorCarl Worth <cworth@cworth.org>
Wed, 21 Oct 2009 22:53:38 +0000 (15:53 -0700)
committerCarl Worth <cworth@cworth.org>
Wed, 21 Oct 2009 22:56:33 +0000 (15:56 -0700)
With these two added, we now have enough functionality in the
library to implement "notmuch restore".

database.cc
message.cc
notmuch-private.h
notmuch.h

index e46fe5d8915dd55910a9822560ddb3ba0e37427d..b5986627336f4c55442fddf71ef0353ee42c8aa8 100644 (file)
@@ -64,6 +64,8 @@ thread_id_generate (thread_id_t *thread_id)
     }
 }
 
+/* XXX: We should drop this function and convert all callers to call
+ * _notmuch_message_add_term instead. */
 static void
 add_term (Xapian::Document doc,
          const char *prefix_name,
index 22c7598d05e6d721b31e3791e569e7da8bf4a210..338d953f2dfb744f8b98c677ab1cf5c711a1f823 100644 (file)
@@ -205,6 +205,106 @@ notmuch_message_get_thread_ids (notmuch_message_t *message)
     return thread_ids;
 }
 
+/* Synchronize changes made to message->doc into the database. */
+static void
+_notmuch_message_sync (notmuch_message_t *message)
+{
+    Xapian::WritableDatabase *db = message->notmuch->xapian_db;
+
+    db->replace_document (message->doc_id, message->doc);
+}
+
+notmuch_private_status_t
+_notmuch_message_add_term (notmuch_message_t *message,
+                          const char *prefix_name,
+                          const char *value)
+{
+
+    char *term;
+
+    if (value == NULL)
+       return NOTMUCH_PRIVATE_STATUS_NULL_POINTER;
+
+    term = talloc_asprintf (message, "%s%s",
+                           _find_prefix (prefix_name), value);
+
+    if (strlen (term) > NOTMUCH_TERM_MAX)
+       return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG;
+
+    message->doc.add_term (term);
+    _notmuch_message_sync (message);
+
+    talloc_free (term);
+
+    return NOTMUCH_PRIVATE_STATUS_SUCCESS;
+}
+
+notmuch_private_status_t
+_notmuch_message_remove_term (notmuch_message_t *message,
+                             const char *prefix_name,
+                             const char *value)
+{
+    char *term;
+
+    if (value == NULL)
+       return NOTMUCH_PRIVATE_STATUS_NULL_POINTER;
+
+    term = talloc_asprintf (message, "%s%s",
+                           _find_prefix (prefix_name), value);
+
+    if (strlen (term) > NOTMUCH_TERM_MAX)
+       return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG;
+
+    message->doc.remove_term (term);
+    _notmuch_message_sync (message);
+
+    talloc_free (term);
+
+    return NOTMUCH_PRIVATE_STATUS_SUCCESS;
+}
+
+notmuch_status_t
+notmuch_message_add_tag (notmuch_message_t *message, const char *tag)
+{
+    notmuch_private_status_t status;
+
+    if (tag == NULL)
+       return NOTMUCH_STATUS_NULL_POINTER;
+
+    if (strlen (tag) > NOTMUCH_TAG_MAX)
+       return NOTMUCH_STATUS_TAG_TOO_LONG;
+
+    status = _notmuch_message_add_term (message, "tag", tag);
+    if (status) {
+       fprintf (stderr, "Internal error: _notmuch_message_add_term return unexpected value: %d\n",
+                status);
+       exit (1);
+    }
+
+    return NOTMUCH_STATUS_SUCCESS;
+}
+
+notmuch_status_t
+notmuch_message_remove_tag (notmuch_message_t *message, const char *tag)
+{
+    notmuch_private_status_t status;
+
+    if (tag == NULL)
+       return NOTMUCH_STATUS_NULL_POINTER;
+
+    if (strlen (tag) > NOTMUCH_TAG_MAX)
+       return NOTMUCH_STATUS_TAG_TOO_LONG;
+
+    status = _notmuch_message_remove_term (message, "tag", tag);
+    if (status) {
+       fprintf (stderr, "Internal error: _notmuch_message_remove_term return unexpected value: %d\n",
+                status);
+       exit (1);
+    }
+
+    return NOTMUCH_STATUS_SUCCESS;
+}
+
 void
 notmuch_message_destroy (notmuch_message_t *message)
 {
index 7cd003f84e5607f997362cc4e1aec4a69d7c5c29..bb3f62c1aa32e5eadf05c216de14a55e94d54284 100644 (file)
@@ -81,6 +81,20 @@ typedef enum {
  * programmatically. */
 #define NOTMUCH_TERM_MAX 245
 
+typedef enum _notmuch_private_status {
+    /* First, copy all the public status values. */
+    NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
+    NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
+    NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
+    NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
+    NOTMUCH_PRIVATE_STATUS_TAG_TOO_LONG = NOTMUCH_STATUS_TAG_TOO_LONG,
+
+    /* Then add our own private values. */
+    NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG,
+
+    NOTMUCH_PRIVATE_STATUS_LAST_STATUS
+} notmuch_private_status_t;
+
 /* message.cc */
 
 notmuch_message_t *
@@ -88,10 +102,24 @@ _notmuch_message_create (const void *talloc_owner,
                         notmuch_database_t *notmuch,
                         unsigned int doc_id);
 
-/* Lookup a prefix value by name. */
+/* Lookup a prefix value by name.
+ *
+ * XXX: This should really be static inside of message.cc, and we can
+ * do that once we convert database.cc to use the
+ * _notmuch_message_add/remove_term functions. */
 const char *
 _find_prefix (const char *name);
 
+notmuch_private_status_t
+_notmuch_message_add_term (notmuch_message_t *message,
+                          const char *prefix_name,
+                          const char *value);
+
+notmuch_private_status_t
+_notmuch_message_remove_term (notmuch_message_t *message,
+                             const char *prefix_name,
+                             const char *value);
+
 /* message-file.c */
 
 /* XXX: I haven't decided yet whether these will actually get exported
index 5dfc8ce2a71d431a920bd3fb7503ce1fe1b7d9f2..02c743aa60b192ffd398d94a0b027006957c3910 100644 (file)
--- a/notmuch.h
+++ b/notmuch.h
@@ -53,11 +53,23 @@ typedef int notmuch_bool_t;
  *
  * NOTMUCH_STATUS_FILE_NOT_EMAIL: A file was presented that doesn't
  *     appear to be an email message.
+ *
+ * NOTMUCH_STATUS_NULL_POINTER: The user erroneously passed a NULL
+ *     pointer to a notmuch function.
+ *
+ * NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long.
+ *
+ * NOTMUCH_STATUS_LAST_STATUS: Not an actual status value. Just a way
+ *     to find out how many valid status values there are.
  */
 typedef enum _notmuch_status {
     NOTMUCH_STATUS_SUCCESS = 0,
     NOTMUCH_STATUS_XAPIAN_EXCEPTION,
-    NOTMUCH_STATUS_FILE_NOT_EMAIL
+    NOTMUCH_STATUS_FILE_NOT_EMAIL,
+    NOTMUCH_STATUS_NULL_POINTER,
+    NOTMUCH_STATUS_TAG_TOO_LONG,
+
+    NOTMUCH_STATUS_LAST_STATUS
 } notmuch_status_t;
 
 /* Various opaque data types. For each notmuch_<foo>_t see the various
@@ -376,6 +388,37 @@ notmuch_message_get_tags (notmuch_message_t *message);
 notmuch_thread_ids_t *
 notmuch_message_get_thread_ids (notmuch_message_t *message);
 
+/* The longest possible tag value. */
+#define NOTMUCH_TAG_MAX 200
+
+/* Add a tag to the given message.
+ *
+ * Return value:
+ *
+ * NOTMUCH_STATUS_SUCCESS: Tag successfully added to message
+ *
+ * NOTMUCH_STATUS_NULL_POINTER: The 'tag' argument is NULL
+ *
+ * NOTMUCH_STATUS_TAG_TOO_LONG: The length of 'tag' is longer than
+ *     too long (exceeds NOTMUCH_TAG_MAX)
+ */
+notmuch_status_t
+notmuch_message_add_tag (notmuch_message_t *message, const char *tag);
+
+/* Remove a tag from the given message.
+ *
+ * Return value:
+ *
+ * NOTMUCH_STATUS_SUCCESS: Tag successfully added to message
+ *
+ * NOTMUCH_STATUS_NULL_POINTER: The 'tag' argument is NULL
+ *
+ * NOTMUCH_STATUS_TAG_TOO_LONG: The length of 'tag' is longer than
+ *     too long (exceeds NOTMUCH_TAG_MAX)
+ */
+notmuch_status_t
+notmuch_message_remove_tag (notmuch_message_t *message, const char *tag);
+
 /* Destroy a notmuch_message_t object.
  *
  * It can be useful to call this function in the case of a single