[PATCH 1/4] Mailstore abstraction interface

Michal Sojka sojkam1 at fel.cvut.cz
Thu Apr 8 07:42:43 PDT 2010


The goal of mailstore abstraction is to allow notmuch to store tags
together with email messages. The abstract interface is needed because
people want to use different ways of storing their emails. Currently,
there exists implementation for two types of mailstore - plain files
and maildir. It is expected that additional git-based mailstore will
be developed later.

This patch contains only the interface changes. No functionality is
added, removed or changed.

A new configuration group [mailstore] is defined. Currently, there is
only one key called 'type' whose value determines the used mailstore.
The default value of this option (files) is the plain-file mailstore
currently implemented in notmuch.

This patch changes libnotmuch API (and ABI). The functions
notmuch_database_create() and notmuch_database_open() need additional
parameter to identify the type of mailstore, which is used to access
the messages.

If we want to preserve the API, it would be necessary to encode the
mailstore type into the 'path' parameter. For example the value
<path>#<type> (or <type>://<path>?) would mean use the mailstore of
given 'type' located at 'path'. If we cannot find the type we would
assuse the default mailstore.

Signed-off-by: Michal Sojka <sojkam1 at fel.cvut.cz>
---
 lib/Makefile.local      |    1 +
 lib/database-private.h  |    1 +
 lib/database.cc         |   15 ++++++--
 lib/mailstore-private.h |   59 ++++++++++++++++++++++++++++++++
 lib/mailstore.c         |   85 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/message.cc          |   13 +++++++
 lib/notmuch.h           |   82 ++++++++++++++++++++++++++++++++++++++++----
 notmuch-client.h        |    7 ++++
 notmuch-config.c        |   34 +++++++++++++++++++
 notmuch-count.c         |    3 +-
 notmuch-dump.c          |    3 +-
 notmuch-new.c           |    6 ++-
 notmuch-reply.c         |    3 +-
 notmuch-restore.c       |    3 +-
 notmuch-search-tags.c   |    3 +-
 notmuch-search.c        |    3 +-
 notmuch-show.c          |    6 ++-
 notmuch-tag.c           |    3 +-
 18 files changed, 307 insertions(+), 23 deletions(-)
 create mode 100644 lib/mailstore-private.h
 create mode 100644 lib/mailstore.c

diff --git a/lib/Makefile.local b/lib/Makefile.local
index 0e3a4d1..6243af1 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -31,6 +31,7 @@ extra_cflags += -I$(dir) -fPIC
 
 libnotmuch_c_srcs =		\
 	$(dir)/libsha1.c	\
+	$(dir)/mailstore.c	\
 	$(dir)/message-file.c	\
 	$(dir)/messages.c	\
 	$(dir)/sha1.c		\
diff --git a/lib/database-private.h b/lib/database-private.h
index 41918d7..4499b1a 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -49,6 +49,7 @@ struct _notmuch_database {
     Xapian::TermGenerator *term_gen;
     Xapian::ValueRangeProcessor *value_range_processor;
 
+    notmuch_mailstore_t *mailstore;
 };
 
 /* Convert tags from Xapian internal format to notmuch format.
diff --git a/lib/database.cc b/lib/database.cc
index c91e97c..93c8d0f 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -19,6 +19,7 @@
  */
 
 #include "database-private.h"
+#include "mailstore-private.h"
 
 #include <iostream>
 
@@ -438,7 +439,7 @@ parse_references (void *ctx,
 }
 
 notmuch_database_t *
-notmuch_database_create (const char *path)
+notmuch_database_create (const char *path, notmuch_mailstore_t *mailstore)
 {
     notmuch_database_t *notmuch = NULL;
     char *notmuch_path = NULL;
@@ -474,7 +475,8 @@ notmuch_database_create (const char *path)
     }
 
     notmuch = notmuch_database_open (path,
-				     NOTMUCH_DATABASE_MODE_READ_WRITE);
+				     NOTMUCH_DATABASE_MODE_READ_WRITE,
+				     mailstore);
     notmuch_database_upgrade (notmuch, NULL, NULL);
 
   DONE:
@@ -497,7 +499,8 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
 
 notmuch_database_t *
 notmuch_database_open (const char *path,
-		       notmuch_database_mode_t mode)
+		       notmuch_database_mode_t mode,
+		       notmuch_mailstore_t *mailstore)
 {
     notmuch_database_t *notmuch = NULL;
     char *notmuch_path = NULL, *xapian_path = NULL;
@@ -605,6 +608,9 @@ notmuch_database_open (const char *path,
 	    prefix_t *prefix = &PROBABILISTIC_PREFIX[i];
 	    notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
 	}
+
+	notmuch->mailstore = mailstore;
+	mailstore->notmuch = notmuch;
     } catch (const Xapian::Error &error) {
 	fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
 		 error.get_msg().c_str());
@@ -1493,7 +1499,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 
   DONE:
     if (message) {
-	if (ret == NOTMUCH_STATUS_SUCCESS && message_ret)
+	if ((ret == NOTMUCH_STATUS_SUCCESS ||
+	     ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) && message_ret)
 	    *message_ret = message;
 	else
 	    notmuch_message_destroy (message);
diff --git a/lib/mailstore-private.h b/lib/mailstore-private.h
new file mode 100644
index 0000000..f606e3f
--- /dev/null
+++ b/lib/mailstore-private.h
@@ -0,0 +1,59 @@
+/* mailstore-private.h - Mailstore abstraction
+ *
+ * Copyright © 2010 Michal Sojka
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ *
+ * Author: Michal Sojka <sojkam1 at fel.cvut.cz>
+ */
+
+#ifndef MAILSTORE_PRIVATE_H
+#define MAILSTORE_PRIVATE_H
+
+#include "notmuch-private.h"
+
+struct _notmuch_mailstore {
+    /* Constant fields */
+    const char *type;      /* identification in .notmuch-config */
+    void *priv;
+
+    /* Count files in mailstore so that initial invocation of notmuch
+     * new can report remaining time */
+    void (*count_files)(notmuch_mailstore_t *mailstore,
+			const char *path, int *count,
+			volatile sig_atomic_t *interrupted);
+    /* Scan for new messages and add them to the database. */
+    notmuch_private_status_t (*index_new)(notmuch_mailstore_t *mailstore,
+					  const char* path,
+					  notmuch_indexing_context_t *ctx);
+    /* Store the tags assigned to the 'messages' to the
+     * 'mailstore'. */
+    notmuch_private_status_t (*sync_tags)(notmuch_mailstore_t *mailstore,
+					  notmuch_message_t *message);
+    /* Return file handle from which the message can be read.
+     *
+     * Currently, this is not used and all message access is hardcoded
+     * to notmuch. We will need this operation for git-based and other
+     * non-filesystem mailstores. */
+    FILE * (*open_file)(notmuch_mailstore_t *mailstore,
+			const char *filename);
+
+    /* Run-time fields */
+    notmuch_database_t *notmuch;
+};
+
+extern struct _notmuch_mailstore mailstore_files;
+extern struct _notmuch_mailstore mailstore_maildir;
+
+#endif /* MAILSTORE_PRIVATE_H */
diff --git a/lib/mailstore.c b/lib/mailstore.c
new file mode 100644
index 0000000..eb27952
--- /dev/null
+++ b/lib/mailstore.c
@@ -0,0 +1,85 @@
+/* mailstore.c - Mailstore abstraction
+ *
+ * Copyright © 2010 Michal Sojka
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ *
+ * Author: Michal Sojka <sojkam1 at fel.cvut.cz>
+ */
+
+#include <notmuch.h>
+#include "mailstore-private.h"
+
+#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+
+/* Original notmuch mail store */
+struct _notmuch_mailstore mailstore_files = {
+    .type = "files",
+};
+
+static notmuch_mailstore_t *available[] = {
+    &mailstore_files,
+};
+
+notmuch_mailstore_t *
+notmuch_mailstore_get_by_type (const char *type)
+{
+    unsigned i;
+
+    if (type == NULL)
+	return available[0];
+
+    for (i = 0; i < ARRAY_SIZE(available); i++) {
+	if (strcasecmp (type, available[i]->type) == 0)
+	    return available[i];
+    }
+    return NULL;
+}
+
+const char *
+notmuch_mailstore_get_type (notmuch_mailstore_t *mailstore)
+{
+    if (!mailstore)
+	return NULL;
+
+    return mailstore->type;
+}
+
+void
+notmuch_mailstore_count_files (notmuch_mailstore_t *mailstore,
+			      const char *path, int *count,
+			      volatile sig_atomic_t *interrupted)
+{
+    mailstore->count_files (mailstore, path, count, interrupted);
+}
+
+notmuch_status_t
+notmuch_mailstore_index_new (notmuch_mailstore_t *mailstore,
+			    const char *path,
+			    notmuch_indexing_context_t *ctx)
+{
+    notmuch_private_status_t status;
+    status = mailstore->index_new (mailstore, path, ctx);
+    return COERCE_STATUS (status, "Index new");
+}
+
+FILE *
+notmuch_mailstore_open_file (notmuch_mailstore_t *mailstore,
+			     const char *filename)
+{
+    if (mailstore->open_file)
+	return mailstore->open_file (mailstore, filename);
+    else
+	return NULL;
+}
diff --git a/lib/message.cc b/lib/message.cc
index 721c9a6..c32ee7d 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -20,6 +20,7 @@
 
 #include "notmuch-private.h"
 #include "database-private.h"
+#include "mailstore-private.h"
 
 #include <stdint.h>
 
@@ -555,10 +556,22 @@ void
 _notmuch_message_sync (notmuch_message_t *message)
 {
     Xapian::WritableDatabase *db;
+    notmuch_private_status_t status;
 
     if (message->notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
 	return;
 
+    if (message->notmuch->mailstore->sync_tags) {
+	status = message->notmuch->mailstore->sync_tags (message->notmuch->mailstore,
+							 message);
+	if (status != NOTMUCH_PRIVATE_STATUS_SUCCESS) {
+	    fprintf (stderr, "Error: Cannot sync tags to mailstore (%s)\n",
+		     notmuch_status_to_string ((notmuch_status_t)status));
+	    /* Exit to avoid unsynchronized mailstore. */
+	    exit(1);
+	}
+    }
+
     db = static_cast <Xapian::WritableDatabase *> (message->notmuch->xapian_db);
     db->replace_document (message->doc_id, message->doc);
 }
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 88da078..31e47a4 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -32,6 +32,8 @@
 NOTMUCH_BEGIN_DECLS
 
 #include <time.h>
+#include <signal.h>		/* For sig_atomic_t */
+#include <stdio.h>		/* For FILE */
 
 #ifndef FALSE
 #define FALSE 0
@@ -119,13 +121,15 @@ typedef struct _notmuch_message notmuch_message_t;
 typedef struct _notmuch_tags notmuch_tags_t;
 typedef struct _notmuch_directory notmuch_directory_t;
 typedef struct _notmuch_filenames notmuch_filenames_t;
+typedef struct _notmuch_mailstore notmuch_mailstore_t;
+
 
 /* Create a new, empty notmuch database located at 'path'.
  *
- * The path should be a top-level directory to a collection of
- * plain-text email messages (one message per file). This call will
- * create a new ".notmuch" directory within 'path' where notmuch will
- * store its data.
+ * The path should be a top-level directory to a mail store e.g. to a
+ * collection of plain-text email messages (one message per file).
+ * This call will create a new ".notmuch" directory within 'path'
+ * where notmuch will store its data.
  *
  * After a successful call to notmuch_database_create, the returned
  * database will be open so the caller should call
@@ -140,7 +144,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
  * an error message on stderr).
  */
 notmuch_database_t *
-notmuch_database_create (const char *path);
+notmuch_database_create (const char *path, notmuch_mailstore_t *mailstore);
 
 typedef enum {
     NOTMUCH_DATABASE_MODE_READ_ONLY = 0,
@@ -169,7 +173,8 @@ typedef enum {
  */
 notmuch_database_t *
 notmuch_database_open (const char *path,
-		       notmuch_database_mode_t mode);
+		       notmuch_database_mode_t mode,
+		       notmuch_mailstore_t *mailstore);
 
 /* Close the given notmuch database, freeing all associated
  * resources. See notmuch_database_open. */
@@ -236,7 +241,8 @@ notmuch_database_get_directory (notmuch_database_t *database,
  * notmuch database will reference the filename, and will not copy the
  * entire contents of the file.
  *
- * If 'message' is not NULL, then, on successful return '*message'
+ * If 'message' is not NULL, then, on successful return
+ * (NOTMUCH_STATUS_SUCCESS or NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) '*message'
  * will be initialized to a message object that can be used for things
  * such as adding tags to the just-added message. The user should call
  * notmuch_message_destroy when done with the message. On any failure
@@ -496,7 +502,7 @@ notmuch_threads_destroy (notmuch_threads_t *threads);
  */
 unsigned
 notmuch_query_count_messages (notmuch_query_t *query);
- 
+
 /* Get the thread ID of 'thread'.
  *
  * The returned string belongs to 'thread' and as such, should not be
@@ -1105,6 +1111,66 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);
 void
 notmuch_filenames_destroy (notmuch_filenames_t *filenames);
 
+/* Returns notmuch_mailstore_t object of a given 'type'.
+ *
+ * The 'type' is case insensitive. If 'type' is NULL, a default
+ * mailstore is returned.
+ *
+ * When no available mailstore matches 'type', NULL is returned.
+ */
+notmuch_mailstore_t *
+notmuch_mailstore_get_by_type (const char *type);
+
+/* Returns the type of a mailstore.
+ *
+ * The returned string is owned by mailstore so should not be modified
+ * nor freed by the caller.
+ */
+const char *
+notmuch_mailstore_get_type (notmuch_mailstore_t *mailstore);
+
+/* Count emails in mailstore.
+ *
+ * This function returns when interrupted is set to non-zero value.
+ */
+void
+notmuch_mailstore_count_files (notmuch_mailstore_t *mailstore,
+			       const char *path, int *count,
+			       volatile sig_atomic_t *interrupted);
+
+typedef struct notmuch_indexing_context {
+    int processed_files;
+    int added_messages;
+    int renamed_files;
+    int removed_files;
+
+    void *priv;		     /* Private field for indexing function */
+
+    int verbose;
+    volatile sig_atomic_t interrupted;
+    volatile sig_atomic_t print_progress;
+    void (*print_progress_cb)(struct notmuch_indexing_context *ctx);
+    void (*print_verbose_cb)(struct notmuch_indexing_context *ctx, const char *filename);
+    void *print_ctx;	    /* Private field for printing functions */
+} notmuch_indexing_context_t;
+
+
+/* Index new mails in the mailstore.
+ *
+ * Mailstore is responsible for detecting new emails, adding them to
+ * the database and tagging them with tags stored in the mailstore.
+ */
+notmuch_status_t
+notmuch_mailstore_index_new (notmuch_mailstore_t *mailstore,
+			     const char *path,
+			     notmuch_indexing_context_t *ctx);
+
+/* Returns file handle to the file in the mailstore.
+ */
+FILE *
+notmuch_mailstore_open_file (notmuch_mailstore_t *mailstore,
+			     const char *filename);
+
 NOTMUCH_END_DECLS
 
 #endif
diff --git a/notmuch-client.h b/notmuch-client.h
index d36b9ec..d8c8df4 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -183,6 +183,13 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,
 				     const char *other_email[],
 				     size_t length);
 
+notmuch_mailstore_t *
+notmuch_config_get_mailstore(notmuch_config_t *config);
+
+void
+notmuch_config_set_mailstore(notmuch_config_t *config,
+			     notmuch_mailstore_t *mailstore);
+
 notmuch_bool_t
 debugger_is_active (void);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index 95430db..299423a 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -62,6 +62,7 @@ struct _notmuch_config {
     char *user_primary_email;
     char **user_other_email;
     size_t user_other_email_length;
+    notmuch_mailstore_t *mailstore;
 };
 
 static int
@@ -199,6 +200,7 @@ notmuch_config_open (void *ctx,
     config->user_primary_email = NULL;
     config->user_other_email = NULL;
     config->user_other_email_length = 0;
+    config->mailstore = NULL;
 
     if (! g_key_file_load_from_file (config->key_file,
 				     config->filename,
@@ -264,6 +266,10 @@ notmuch_config_open (void *ctx,
 	}
     }
 
+    if (notmuch_config_get_mailstore (config) == NULL) {
+	notmuch_config_set_mailstore(config, notmuch_mailstore_get_by_type(NULL));
+    }
+
     /* When we create a new configuration file here, we  add some
      * comments to help the user understand what can be done. */
     if (is_new) {
@@ -452,3 +458,31 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,
     talloc_free (config->user_other_email);
     config->user_other_email = NULL;
 }
+
+notmuch_mailstore_t *
+notmuch_config_get_mailstore(notmuch_config_t *config)
+{
+    char *type;
+
+    if (config->mailstore == NULL) {
+	type = g_key_file_get_string (config->key_file,
+				      "mailstore", "type", NULL);
+	if (type) {
+	    config->mailstore = notmuch_mailstore_get_by_type(type);
+	    free (type);
+	}
+    }
+
+    return config->mailstore;
+}
+
+void
+notmuch_config_set_mailstore(notmuch_config_t *config,
+			     notmuch_mailstore_t *mailstore)
+{
+    g_key_file_set_string (config->key_file,
+			   "mailstore", "type",
+			   notmuch_mailstore_get_type(mailstore));
+
+    config->mailstore = NULL;
+}
diff --git a/notmuch-count.c b/notmuch-count.c
index 77aa433..631b8f8 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -81,7 +81,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])
 	return 1;
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+				     NOTMUCH_DATABASE_MODE_READ_ONLY,
+				     notmuch_config_get_mailstore(config));
     if (notmuch == NULL)
 	return 1;
 
diff --git a/notmuch-dump.c b/notmuch-dump.c
index 7e7bc17..e74dfcb 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -36,7 +36,8 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])
 	return 1;
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+				     NOTMUCH_DATABASE_MODE_READ_ONLY,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
diff --git a/notmuch-new.c b/notmuch-new.c
index 44b50aa..2d0ba6c 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -749,11 +749,13 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
 	    return 1;
 
 	printf ("Found %d total files (that's not much mail).\n", count);
-	notmuch = notmuch_database_create (db_path);
+	notmuch = notmuch_database_create (db_path,
+					   notmuch_config_get_mailstore (config));
 	add_files_state.total_files = count;
     } else {
 	notmuch = notmuch_database_open (db_path,
-					 NOTMUCH_DATABASE_MODE_READ_WRITE);
+					 NOTMUCH_DATABASE_MODE_READ_WRITE,
+					 notmuch_config_get_mailstore (config));
 	if (notmuch == NULL)
 	    return 1;
 
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 39377e1..1ec28cd 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -533,7 +533,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     }
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+				     NOTMUCH_DATABASE_MODE_READ_ONLY,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
diff --git a/notmuch-restore.c b/notmuch-restore.c
index b0a4e1c..97d817b 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -37,7 +37,8 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
 	return 1;
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_WRITE);
+				     NOTMUCH_DATABASE_MODE_READ_WRITE,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
diff --git a/notmuch-search-tags.c b/notmuch-search-tags.c
index 6f3cfcc..323f416 100644
--- a/notmuch-search-tags.c
+++ b/notmuch-search-tags.c
@@ -52,7 +52,8 @@ notmuch_search_tags_command (void *ctx, int argc, char *argv[])
     }
 
     db = notmuch_database_open (notmuch_config_get_database_path (config),
-				NOTMUCH_DATABASE_MODE_READ_ONLY);
+				NOTMUCH_DATABASE_MODE_READ_ONLY,
+				notmuch_config_get_mailstore (config));
     if (db == NULL) {
 	goto error;
     }
diff --git a/notmuch-search.c b/notmuch-search.c
index 4e3514b..d57479d 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -245,7 +245,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 	return 1;
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+				     NOTMUCH_DATABASE_MODE_READ_ONLY,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
diff --git a/notmuch-show.c b/notmuch-show.c
index 76873a1..6dca672 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -461,7 +461,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
     }
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+				     NOTMUCH_DATABASE_MODE_READ_ONLY,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
@@ -547,7 +548,8 @@ notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[]))
 	}
 
 	notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-					 NOTMUCH_DATABASE_MODE_READ_ONLY);
+					 NOTMUCH_DATABASE_MODE_READ_ONLY,
+					 notmuch_config_get_mailstore(config));
 	if (notmuch == NULL)
 		return 1;
 
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 8b6f7dc..5e1a5c3 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -97,7 +97,8 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))
 	return 1;
 
     notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
-				     NOTMUCH_DATABASE_MODE_READ_WRITE);
+				     NOTMUCH_DATABASE_MODE_READ_WRITE,
+				     notmuch_config_get_mailstore (config));
     if (notmuch == NULL)
 	return 1;
 
-- 
1.7.0.2



More information about the notmuch mailing list