[PATCH v1 1/1] lib: make find_message{,by_filename) report errors
authorAli Polatel <polatel@gmail.com>
Mon, 3 Oct 2011 16:49:20 +0000 (19:49 +0300)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:39:34 +0000 (09:39 -0800)
b2/0a2f22fa1d81ff10e68db5eb5b5db0fc0c2e88 [new file with mode: 0644]

diff --git a/b2/0a2f22fa1d81ff10e68db5eb5b5db0fc0c2e88 b/b2/0a2f22fa1d81ff10e68db5eb5b5db0fc0c2e88
new file mode 100644 (file)
index 0000000..e0bf7d5
--- /dev/null
@@ -0,0 +1,439 @@
+Return-Path: <polatel@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 44D6F429E21\r
+       for <notmuch@notmuchmail.org>; Mon,  3 Oct 2011 09:49:37 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 1.7\r
+X-Spam-Level: *\r
+X-Spam-Status: No, score=1.7 tagged_above=-999 required=5\r
+       tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+       FREEMAIL_FROM=0.001, FREEMAIL_REPLY=2.499, RCVD_IN_DNSWL_LOW=-0.7]\r
+       autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id msIDsCPIiafs for <notmuch@notmuchmail.org>;\r
+       Mon,  3 Oct 2011 09:49:36 -0700 (PDT)\r
+Received: from mail-dy0-f53.google.com (mail-dy0-f53.google.com\r
+       [209.85.220.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id CB7ED431FB6\r
+       for <notmuch@notmuchmail.org>; Mon,  3 Oct 2011 09:49:35 -0700 (PDT)\r
+Received: by dye4 with SMTP id 4so176309dye.26\r
+       for <notmuch@notmuchmail.org>; Mon, 03 Oct 2011 09:49:33 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
+       h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references\r
+       :in-reply-to:references:organization;\r
+       bh=kSMXOME/xCGF22PVGo39cM0DkSIcWxa3XO+80rKctws=;\r
+       b=r6walyAMkxFAXucLOejWOUrvpeSdc2uF/XLiL8H7088XXgGQp0BB6R9orZCntoBO40\r
+       kZNGebetHzl3czpi1HDHu9A+bsEUFwFaoRJeaqtq9IVnycn9hmXRlf7I4yVP1ypPiMz3\r
+       BagPDt9n97bKy1X7wfIZ/inTt3STWI5OM4T2g=\r
+Received: by 10.223.45.85 with SMTP id d21mr180774faf.63.1317660572942;\r
+       Mon, 03 Oct 2011 09:49:32 -0700 (PDT)\r
+Received: from localhost ([88.236.39.101])\r
+       by mx.google.com with ESMTPS id n1sm21888425fad.20.2011.10.03.09.49.31\r
+       (version=TLSv1/SSLv3 cipher=OTHER);\r
+       Mon, 03 Oct 2011 09:49:32 -0700 (PDT)\r
+From: Ali Polatel <polatel@gmail.com>\r
+To: Notmuch Mailing List <notmuch@notmuchmail.org>\r
+Subject: [PATCH v1 1/1] lib: make find_message{,by_filename) report errors\r
+Date: Mon,  3 Oct 2011 19:49:20 +0300\r
+Message-Id:\r
+ <1218582065f35bfcc5b84dfc1fbce21fc05034a6.1317660324.git.alip@exherbo.org>\r
+X-Mailer: git-send-email 1.7.6.1\r
+In-Reply-To: <cover.1317660324.git.alip@exherbo.org>\r
+References: <cover.1317456435.git.alip@exherbo.org>\r
+       <cover.1317660324.git.alip@exherbo.org>\r
+In-Reply-To: <cover.1317660324.git.alip@exherbo.org>\r
+References: <cover.1317660324.git.alip@exherbo.org>\r
+Organization: Pink Floyd\r
+Cc: Austin Clements <amdragon@MIT.EDU>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Mon, 03 Oct 2011 16:49:37 -0000\r
+\r
+Previously, the functions notmuch_database_find_message() and\r
+notmuch_database_find_message_by_filename() functions did not properly\r
+report error condition to the library user.\r
+\r
+For more information, read the thread on the notmuch mailing list\r
+starting with my mail "id:871uv2unfd.fsf@gmail.com"\r
+\r
+Make these functions accept a pointer to 'notmuch_message_t' as argument\r
+and return notmuch_status_t which may be used to check for any error\r
+condition.\r
+\r
+restore: Modify for the new notmuch_database_find_message()\r
+new: Modify for the new notmuch_database_find_message_by_filename()\r
+---\r
+ lib/database.cc   |   90 ++++++++++++++++++++++++++++++++++------------------\r
+ lib/message.cc    |    6 ++--\r
+ lib/notmuch.h     |   61 +++++++++++++++++++++++++----------\r
+ notmuch-new.c     |    4 ++-\r
+ notmuch-restore.c |   11 ++++--\r
+ 5 files changed, 115 insertions(+), 57 deletions(-)\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index 9299c8d..1705232 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -360,13 +360,17 @@ _message_id_compressed (void *ctx, const char *message_id)\r
+     return compressed;\r
+ }\r
\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message (notmuch_database_t *notmuch,\r
+-                             const char *message_id)\r
++                             const char *message_id,\r
++                             notmuch_message_t **message)\r
+ {\r
+     notmuch_private_status_t status;\r
+     unsigned int doc_id;\r
\r
++    if (message == NULL)\r
++      return NOTMUCH_STATUS_NULL_POINTER;\r
++\r
+     if (strlen (message_id) > NOTMUCH_MESSAGE_ID_MAX)\r
+       message_id = _message_id_compressed (notmuch, message_id);\r
\r
+@@ -375,14 +379,21 @@ notmuch_database_find_message (notmuch_database_t *notmuch,\r
+                                                      message_id, &doc_id);\r
\r
+       if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)\r
+-          return NULL;\r
++          *message = NULL;\r
++      else {\r
++          *message = _notmuch_message_create (notmuch, notmuch, doc_id,\r
++                                              NULL);\r
++          if (*message == NULL)\r
++              return NOTMUCH_STATUS_OUT_OF_MEMORY;\r
++      }\r
\r
+-      return _notmuch_message_create (notmuch, notmuch, doc_id, NULL);\r
++      return NOTMUCH_STATUS_SUCCESS;\r
+     } catch (const Xapian::Error &error) {\r
+       fprintf (stderr, "A Xapian exception occurred finding message: %s.\n",\r
+                error.get_msg().c_str());\r
+       notmuch->exception_reported = TRUE;\r
+-      return NULL;\r
++      *message = NULL;\r
++      return NOTMUCH_STATUS_XAPIAN_EXCEPTION;\r
+     }\r
+ }\r
\r
+@@ -1311,7 +1322,8 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)\r
\r
+ /* Find the thread ID to which the message with 'message_id' belongs.\r
+  *\r
+- * Always returns a newly talloced string belonging to 'ctx'.\r
++ * Note: 'thread_id' must not be NULL!\r
++ * On success '*thread_id' is set to a newly talloced string belonging to 'ctx'.\r
+  *\r
+  * Note: If there is no message in the database with the given\r
+  * 'message_id' then a new thread_id will be allocated for this\r
+@@ -1319,25 +1331,29 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)\r
+  * thread ID can be looked up if the message is added to the database\r
+  * later).\r
+  */\r
+-static const char *\r
++static notmuch_status_t\r
+ _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,\r
+                                 void *ctx,\r
+-                                const char *message_id)\r
++                                const char *message_id,\r
++                                const char **thread_id)\r
+ {\r
++    notmuch_status_t status;\r
+     notmuch_message_t *message;\r
+     string thread_id_string;\r
+-    const char *thread_id;\r
+     char *metadata_key;\r
+     Xapian::WritableDatabase *db;\r
\r
+-    message = notmuch_database_find_message (notmuch, message_id);\r
++    status = notmuch_database_find_message (notmuch, message_id, &message);\r
++\r
++    if (status)\r
++      return status;\r
\r
+     if (message) {\r
+-      thread_id = talloc_steal (ctx, notmuch_message_get_thread_id (message));\r
++      *thread_id = talloc_steal (ctx, notmuch_message_get_thread_id (message));\r
\r
+       notmuch_message_destroy (message);\r
\r
+-      return thread_id;\r
++      return NOTMUCH_STATUS_SUCCESS;\r
+     }\r
\r
+     /* Message has not been seen yet.\r
+@@ -1351,15 +1367,15 @@ _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,\r
+     thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);\r
\r
+     if (thread_id_string.empty()) {\r
+-      thread_id = _notmuch_database_generate_thread_id (notmuch);\r
+-      db->set_metadata (metadata_key, thread_id);\r
++      *thread_id = talloc_strdup (ctx, _notmuch_database_generate_thread_id (notmuch));\r
++      db->set_metadata (metadata_key, *thread_id);\r
+     } else {\r
+-      thread_id = thread_id_string.c_str();\r
++      *thread_id = talloc_strdup(ctx, thread_id_string.c_str());\r
+     }\r
\r
+     talloc_free (metadata_key);\r
\r
+-    return talloc_strdup (ctx, thread_id);\r
++    return NOTMUCH_STATUS_SUCCESS;\r
+ }\r
\r
+ static notmuch_status_t\r
+@@ -1446,9 +1462,12 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,\r
+       _notmuch_message_add_term (message, "reference",\r
+                                  parent_message_id);\r
\r
+-      parent_thread_id = _resolve_message_id_to_thread_id (notmuch,\r
+-                                                           message,\r
+-                                                           parent_message_id);\r
++      ret = _resolve_message_id_to_thread_id (notmuch,\r
++                                              message,\r
++                                              parent_message_id,\r
++                                              &parent_thread_id);\r
++      if (ret)\r
++          goto DONE;\r
\r
+       if (*thread_id == NULL) {\r
+           *thread_id = talloc_strdup (message, parent_thread_id);\r
+@@ -1759,11 +1778,12 @@ notmuch_status_t\r
+ notmuch_database_remove_message (notmuch_database_t *notmuch,\r
+                                const char *filename)\r
+ {\r
+-    notmuch_message_t *message =\r
+-      notmuch_database_find_message_by_filename (notmuch, filename);\r
+-    notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;\r
++    notmuch_status_t status;\r
++    notmuch_message_t *message;\r
\r
+-    if (message) {\r
++    status = notmuch_database_find_message_by_filename (notmuch, filename, &message);\r
++\r
++    if (status == NOTMUCH_STATUS_SUCCESS && message) {\r
+           status = _notmuch_message_remove_filename (message, filename);\r
+           if (status == NOTMUCH_STATUS_SUCCESS)\r
+               _notmuch_message_delete (message);\r
+@@ -1774,24 +1794,27 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,\r
+     return status;\r
+ }\r
\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+-                                         const char *filename)\r
++                                         const char *filename,\r
++                                         notmuch_message_t **message)\r
+ {\r
+     void *local;\r
+     const char *prefix = _find_prefix ("file-direntry");\r
+     char *direntry, *term;\r
+     Xapian::PostingIterator i, end;\r
+-    notmuch_message_t *message = NULL;\r
+     notmuch_status_t status;\r
\r
++    if (message == NULL)\r
++      return NOTMUCH_STATUS_NULL_POINTER;\r
++\r
+     local = talloc_new (notmuch);\r
\r
+     try {\r
+       status = _notmuch_database_filename_to_direntry (local, notmuch,\r
+                                                        filename, &direntry);\r
+       if (status)\r
+-          return NULL;\r
++          goto DONE;\r
\r
+       term = talloc_asprintf (local, "%s%s", prefix, direntry);\r
\r
+@@ -1800,19 +1823,24 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+       if (i != end) {\r
+           notmuch_private_status_t private_status;\r
\r
+-          message = _notmuch_message_create (notmuch, notmuch,\r
+-                                             *i, &private_status);\r
++          *message = _notmuch_message_create (notmuch, notmuch,\r
++                                              *i, &private_status);\r
++          if (*message == NULL)\r
++              status = NOTMUCH_STATUS_OUT_OF_MEMORY;\r
+       }\r
+     } catch (const Xapian::Error &error) {\r
+       fprintf (stderr, "Error: A Xapian exception occurred finding message by filename: %s\n",\r
+                error.get_msg().c_str());\r
+       notmuch->exception_reported = TRUE;\r
+-      message = NULL;\r
++      status = NOTMUCH_STATUS_OUT_OF_MEMORY;\r
+     }\r
\r
++  DONE:\r
+     talloc_free (local);\r
\r
+-    return message;\r
++    if (status)\r
++      *message = NULL;\r
++    return status;\r
+ }\r
\r
+ notmuch_string_list_t *\r
+diff --git a/lib/message.cc b/lib/message.cc\r
+index 531d304..2a85744 100644\r
+--- a/lib/message.cc\r
++++ b/lib/message.cc\r
+@@ -216,11 +216,11 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch,\r
+     unsigned int doc_id;\r
+     char *term;\r
\r
+-    *status_ret = NOTMUCH_PRIVATE_STATUS_SUCCESS;\r
+-\r
+-    message = notmuch_database_find_message (notmuch, message_id);\r
++    *status_ret = (notmuch_private_status_t) notmuch_database_find_message (notmuch, message_id, &message);\r
+     if (message)\r
+       return talloc_steal (notmuch, message);\r
++    else if (*status_ret)\r
++      return NULL;\r
\r
+     term = talloc_asprintf (NULL, "%s%s",\r
+                           _find_prefix ("id"), message_id);\r
+diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+index 6d7a99f..08b4ce2 100644\r
+--- a/lib/notmuch.h\r
++++ b/lib/notmuch.h\r
+@@ -347,35 +347,60 @@ notmuch_database_remove_message (notmuch_database_t *database,\r
\r
+ /* Find a message with the given message_id.\r
+  *\r
+- * If the database contains a message with the given message_id, then\r
+- * a new notmuch_message_t object is returned. The caller should call\r
+- * notmuch_message_destroy when done with the message.\r
++ * If message with the given message_id is found then, on successful return\r
++ * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message object.\r
++ * The user should call notmuch_message_destroy when done with the message.\r
+  *\r
+- * This function returns NULL in the following situations:\r
++ * On any failure or when the message is not found, this function initializes\r
++ * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the\r
++ * user is supposed to check '*message' for NULL to find out whether the\r
++ * message with the given message_id was found.\r
+  *\r
+- *    * No message is found with the given message_id\r
+- *    * An out-of-memory situation occurs\r
+- *    * A Xapian exception occurs\r
++ * Note: The argument 'message' must not be NULL!\r
++ *\r
++ * Return value:\r
++ *\r
++ * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'.\r
++ *\r
++ * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL\r
++ *\r
++ * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating message object\r
++ *\r
++ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred\r
+  */\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message (notmuch_database_t *database,\r
+-                             const char *message_id);\r
++                             const char *message_id,\r
++                             notmuch_message_t **message);\r
\r
+ /* Find a message with the given filename.\r
+  *\r
+- * If the database contains a message with the given filename, then a\r
+- * new notmuch_message_t object is returned.  The caller should call \r
+- * notmuch_message_destroy when done with the message.\r
++ * If the database contains a message with the given filename then, on\r
++ * successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to\r
++ * a message object. The user should call notmuch_message_destroy when done\r
++ * with the message.\r
+  *\r
+- * This function returns NULL in the following situations:\r
++ * On any failure or when the message is not found, this function initializes\r
++ * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the\r
++ * user is supposed to check '*message' for NULL to find out whether the\r
++ * message with the given filename is found.\r
+  *\r
+- *    * No message is found with the given filename\r
+- *    * An out-of-memory situation occurs\r
+- *    * A Xapian exception occurs\r
++ * Note: The argument 'message' must not be NULL!\r
++ *\r
++ * Return value:\r
++ *\r
++ * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'\r
++ *\r
++ * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL\r
++ *\r
++ * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object\r
++ *\r
++ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred\r
+  */\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+-                                         const char *filename);\r
++                                         const char *filename,\r
++                                         notmuch_message_t **message);\r
\r
+ /* Return a list of all tags found in the database.\r
+  *\r
+diff --git a/notmuch-new.c b/notmuch-new.c\r
+index e79593c..96a1e31 100644\r
+--- a/notmuch-new.c\r
++++ b/notmuch-new.c\r
+@@ -743,7 +743,9 @@ remove_filename (notmuch_database_t *notmuch,\r
+     status = notmuch_database_begin_atomic (notmuch);\r
+     if (status)\r
+       return status;\r
+-    message = notmuch_database_find_message_by_filename (notmuch, path);\r
++    status = notmuch_database_find_message_by_filename (notmuch, path, &message);\r
++    if (status || message == NULL)\r
++      return status;\r
+     status = notmuch_database_remove_message (notmuch, path);\r
+     if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {\r
+       add_files_state->renamed_messages++;\r
+diff --git a/notmuch-restore.c b/notmuch-restore.c\r
+index f095f64..e4a5355 100644\r
+--- a/notmuch-restore.c\r
++++ b/notmuch-restore.c\r
+@@ -87,10 +87,13 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+       file_tags = xstrndup (line + match[2].rm_so,\r
+                             match[2].rm_eo - match[2].rm_so);\r
\r
+-      message = notmuch_database_find_message (notmuch, message_id);\r
+-      if (message == NULL) {\r
+-          fprintf (stderr, "Warning: Cannot apply tags to missing message: %s\n",\r
+-                   message_id);\r
++      status = notmuch_database_find_message (notmuch, message_id, &message);\r
++      if (status || message == NULL) {\r
++          fprintf (stderr, "Warning: Cannot apply tags to %smessage: %s\n",\r
++                   message ? "" : "missing ", message_id);\r
++          if (status)\r
++              fprintf (stderr, "%s\n",\r
++                       notmuch_status_to_string(status));\r
+           goto NEXT_LINE;\r
+       }\r
\r
+-- \r
+1.7.6.1\r
+\r