[PATCH 2/2] lib: introduce notmuch_database_new for initializing a database handle
Jani Nikula
jani at nikula.org
Thu Dec 5 10:17:58 PST 2013
On Thu, 05 Dec 2013, Austin Clements <amdragon at MIT.EDU> wrote:
> Quoth Jani Nikula on Dec 01 at 3:14 pm:
>> There is a need for setting options before opening a database, such as
>> setting a logging function to use instead of writing to stdout or
>> stderr. It would be possible to do this by adding new parameters to
>> notmuch_database_create and notmuch_database_open, but maintaining a
>> backwards compatible API and ABI when new options are added becomes
>> burdensome.
>>
>> Instead, split the opaque database object creation from
>> notmuch_database_create and notmuch_database_open into a new
>> notmuch_database_new call, to allow operations on the handle before
>> create and open. This creates API and ABI breakage now, but allows
>> easier future extensions.
>>
>> The notmuch_database_new call becomes a natural pair to the already
>> existing notmuch_database_destroy, and it should be possible to call
>> open/close multiple times using an initialized handle.
>
> A high-level comment about the API: Currently, an allocated
> notmuch_database_t has two "memory states", if you will: open and
> closed. (I wish it didn't have any memory states, and was on the
> fence about this API for a while until I realized that the ship had
> already sailed.)
Just to confirm, are you referring to the state between close and
destroy/open?
Btw what is the use case we have separate close and destroy for? To be
able to access the data cached in memory after the db has been closed?
> It's pretty clear how all of the notmuch APIs will
> behave in both states (modulo some bounded non-determinism in the
> closed state). I think this patch introduces a new "pre-open" state,
> and I don't know how most of the notmuch APIs behave in that state.
> My guess is poorly. If it's feasible, I'd much rather a fresh baked
> notmuch_database_t act like it's in the closed state, including that
> notmuch_database_{create,open} are well-defined as transitions from
> closed state to open state (even if the closed state was reached by
> calling notmuch_database_close). Or, if we do have a "pre-open"
> state, it should at least be well-specified what that means
> (preferably the specification is *not* "most APIs segfault").
Agreed.
> Orthogonally -- and this may be a complete pipe dream of mine -- if we
> just had a way to return more detailed error information than a simple
> error code from notmuch_database_{create,open}, I think we wouldn't
> need any of this. Everything that these functions currently log
> (modulo one warning) is error details, so if we could return the error
> details *with the error* or somehow make them accessible, we wouldn't
> need a logger at this point (or at several other points in the
> library).
Agreed. I tried to look into this earlier, but was hitting dead ends
*if* we want to keep reporting user friendly error status in
open/create. Obviously any concrete suggestions would be most welcome!
>> ---
>> lib/database.cc | 64 ++++++++++++++++++++++++++++------------------------
>> lib/notmuch.h | 52 ++++++++++++++++++++++++++++++++----------
>> notmuch-compact.c | 11 ++++++++-
>> notmuch-count.c | 10 ++++++--
>> notmuch-dump.c | 10 ++++++--
>> notmuch-insert.c | 10 ++++++--
>> notmuch-new.c | 14 +++++++-----
>> notmuch-reply.c | 10 ++++++--
>> notmuch-restore.c | 10 ++++++--
>> notmuch-search.c | 10 ++++++--
>> notmuch-show.c | 10 ++++++--
>> notmuch-tag.c | 10 ++++++--
>> test/random-corpus.c | 10 ++++++--
>> test/symbol-test.cc | 3 ++-
>> 14 files changed, 166 insertions(+), 68 deletions(-)
>>
>> diff --git a/lib/database.cc b/lib/database.cc
>> index 98e2c31..386b93a 100644
>> --- a/lib/database.cc
>> +++ b/lib/database.cc
>> @@ -539,10 +539,21 @@ parse_references (void *ctx,
>> }
>>
>> notmuch_status_t
>> -notmuch_database_create (const char *path, notmuch_database_t **database)
>> +notmuch_database_new (notmuch_database_t **notmuch)
>
> The naming of this is unfortunate... Other APIs use x_create to
> allocate objects (e.g., notmuch_query_create, several internal APIs).
> I would lean towards calling this function notmuch_database_create,
> but that leaves the question of what to call the other. While we're
> breaking APIs, would it be completely crazy to merge open and create
> into one API with an extra mode to indicate creation (it can be its
> own mode because creation implies read/write)? (Or, in UNIX
> tradition, we could call this function notmuch_database_create and the
> other notmuch_database_creat.) notmuch_database_create is already
> just a shell around notmuch_database_open (we could keep it as a
> separate function, but just make it internal).
Agreed on the naming being unfortunate, though I'll dodge further
bikeshedding. ;) Merging open and create sounds all right, though it's a
minor detail in the bigger picture of this patch.
The comments below seemed valid too, thanks.
BR,
Jani.
>
>> +{
>> + /* Note: try to avoid error conditions! No error printing! */
>> +
>> + *notmuch = talloc_zero (NULL, notmuch_database_t);
>> + if (! *notmuch)
>> + return NOTMUCH_STATUS_OUT_OF_MEMORY;
>> +
>> + return NOTMUCH_STATUS_SUCCESS;
>> +}
>> +
>> +notmuch_status_t
>> +notmuch_database_create (notmuch_database_t *notmuch, const char *path)
>> {
>
> This should fail if passed a database that is already open.
>
>> notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
>> - notmuch_database_t *notmuch = NULL;
>> char *notmuch_path = NULL;
>> struct stat st;
>> int err;
>> @@ -579,25 +590,18 @@ notmuch_database_create (const char *path, notmuch_database_t **database)
>> goto DONE;
>> }
>>
>> - status = notmuch_database_open (path,
>> - NOTMUCH_DATABASE_MODE_READ_WRITE,
>> - ¬much);
>> + status = notmuch_database_open (notmuch, path,
>> + NOTMUCH_DATABASE_MODE_READ_WRITE);
>> if (status)
>> goto DONE;
>> status = notmuch_database_upgrade (notmuch, NULL, NULL);
>> - if (status) {
>> + if (status)
>> notmuch_database_close(notmuch);
>> - notmuch = NULL;
>> - }
>>
>> DONE:
>> if (notmuch_path)
>> talloc_free (notmuch_path);
>>
>> - if (database)
>> - *database = notmuch;
>> - else
>> - talloc_free (notmuch);
>> return status;
>> }
>>
>> @@ -612,14 +616,15 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
>> return NOTMUCH_STATUS_SUCCESS;
>> }
>>
>> +/*
>> + * XXX: error handling should clean up *all* state created!
>> + */
>
> I think the only thing that will currently leak from this in an error
> case is notmuch->path.
>
>> notmuch_status_t
>> -notmuch_database_open (const char *path,
>> - notmuch_database_mode_t mode,
>> - notmuch_database_t **database)
>> +notmuch_database_open (notmuch_database_t *notmuch, const char *path,
>> + notmuch_database_mode_t mode)
>> {
>
> This should also fail if passed a database that is already open.
>
>> notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
>> void *local = talloc_new (NULL);
>> - notmuch_database_t *notmuch = NULL;
>> char *notmuch_path, *xapian_path;
>> struct stat st;
>> int err;
>> @@ -663,7 +668,6 @@ notmuch_database_open (const char *path,
>> initialized = 1;
>> }
>>
>> - notmuch = talloc_zero (NULL, notmuch_database_t);
>> notmuch->exception_reported = FALSE;
>> notmuch->path = talloc_strdup (notmuch, path);
>>
>> @@ -689,8 +693,7 @@ notmuch_database_open (const char *path,
>> " read-write mode.\n",
>> notmuch_path, version, NOTMUCH_DATABASE_VERSION);
>> notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
>> - notmuch_database_destroy (notmuch);
>> - notmuch = NULL;
>> + notmuch_database_close (notmuch);
>> status = NOTMUCH_STATUS_FILE_ERROR;
>> goto DONE;
>> }
>> @@ -752,21 +755,19 @@ notmuch_database_open (const char *path,
>> } catch (const Xapian::Error &error) {
>> fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
>> error.get_msg().c_str());
>> - notmuch_database_destroy (notmuch);
>> - notmuch = NULL;
>> + notmuch_database_close (notmuch);
>> status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
>> }
>>
>> DONE:
>> talloc_free (local);
>>
>
> It might be simpler to call notmuch_database_close here if status !=
> NOTMUCH_STATUS_SUCCESS, rather than calling it at several places above
> (and not on all error paths).
>
>> - if (database)
>> - *database = notmuch;
>> - else
>> - talloc_free (notmuch);
>> return status;
>> }
>>
>> +/*
>> + * XXX: close should clean up *all* state created by open/create!
>> + */
>
> I believe the only thing it doesn't clean up is path. (Note that
> cleaning up path here doesn't currently negate the need to clean up
> path above, though if you float the close call to the DONE path, it
> would suffice.)
>
>> notmuch_status_t
>> notmuch_database_close (notmuch_database_t *notmuch)
>> {
>> @@ -869,7 +870,8 @@ public:
>> * compaction process to protect data integrity.
>> */
>> notmuch_status_t
>> -notmuch_database_compact (const char *path,
>> +notmuch_database_compact (notmuch_database_t *notmuch,
>> + const char *path,
>> const char *backup_path,
>> notmuch_compact_status_cb_t status_cb,
>> void *closure)
>> @@ -877,7 +879,6 @@ notmuch_database_compact (const char *path,
>> void *local;
>> char *notmuch_path, *xapian_path, *compact_xapian_path;
>> notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
>> - notmuch_database_t *notmuch = NULL;
>> struct stat statbuf;
>> notmuch_bool_t keep_backup;
>>
>> @@ -885,7 +886,8 @@ notmuch_database_compact (const char *path,
>> if (! local)
>> return NOTMUCH_STATUS_OUT_OF_MEMORY;
>>
>> - ret = notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much);
>> + ret = notmuch_database_open (notmuch, path,
>> + NOTMUCH_DATABASE_MODE_READ_WRITE);
>> if (ret) {
>> goto DONE;
>> }
>> @@ -971,8 +973,9 @@ notmuch_database_compact (const char *path,
>> }
>>
>> DONE:
>> + /* XXX: error handling */
>> if (notmuch)
>> - ret = notmuch_database_destroy (notmuch);
>> + ret = notmuch_database_close (notmuch);
>>
>> talloc_free (local);
>>
>> @@ -980,7 +983,8 @@ notmuch_database_compact (const char *path,
>> }
>> #else
>> notmuch_status_t
>> -notmuch_database_compact (unused (const char *path),
>> +notmuch_database_compact (unused (notmuch_database_t *notmuch),
>> + unused (const char *path),
>> unused (const char *backup_path),
>> unused (notmuch_compact_status_cb_t status_cb),
>> unused (void *closure))
>> diff --git a/lib/notmuch.h b/lib/notmuch.h
>> index dbdce86..cd58d15 100644
>> --- a/lib/notmuch.h
>> +++ b/lib/notmuch.h
>> @@ -149,6 +149,28 @@ typedef struct _notmuch_tags notmuch_tags_t;
>> typedef struct _notmuch_directory notmuch_directory_t;
>> typedef struct _notmuch_filenames notmuch_filenames_t;
>>
>> +/* Initialize a new, empty database handle.
>> + *
>> + * The database handle is required for creating, opening, and
>> + * compacting a database. For further database operations, the
>> + * database needs to be created or opened.
>> + *
>> + * After a successful call to notmuch_database_new, the returned
>> + * database handle will remain in memory, so the caller should call
>> + * notmuch_database_destroy when finished with the database handle.
>> + *
>> + * In case of any failure, this function returns an error status and
>> + * sets *notmuch to NULL.
>> + *
>> + * Return value:
>> + *
>> + * NOTMUCH_STATUS_SUCCESS: Successfully created the database object.
>> + *
>> + * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory.
>> + */
>> +notmuch_status_t
>> +notmuch_database_new (notmuch_database_t **notmuch);
>> +
>> /* Create a new, empty notmuch database located at 'path'.
>> *
>> * The path should be a top-level directory to a collection of
>> @@ -156,9 +178,9 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
>> * 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
>> - * notmuch_database_destroy when finished with it.
>> + * After a successful call to notmuch_database_create, the database
>> + * will be open so the caller should call notmuch_database_close (or
>> + * notmuch_database_destroy) when finished with the database.
>> *
>> * The database will not yet have any data in it
>> * (notmuch_database_create itself is a very cheap function). Messages
>> @@ -166,7 +188,8 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
>> * notmuch_database_add_message.
>> *
>> * In case of any failure, this function returns an error status and
>> - * sets *database to NULL (after printing an error message on stderr).
>> + * the database will be closed (after printing an error message on
>> + * stderr).
>> *
>> * Return value:
>> *
>> @@ -183,7 +206,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t;
>> * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred.
>> */
>> notmuch_status_t
>> -notmuch_database_create (const char *path, notmuch_database_t **database);
>> +notmuch_database_create (notmuch_database_t *notmuch, const char *path);
>>
>> typedef enum {
>> NOTMUCH_DATABASE_MODE_READ_ONLY = 0,
>> @@ -201,11 +224,13 @@ typedef enum {
>> * An existing notmuch database can be identified by the presence of a
>> * directory named ".notmuch" below 'path'.
>> *
>> - * The caller should call notmuch_database_destroy when finished with
>> - * this database.
>> + * After a successful call to notmuch_database_open, the database will
>> + * be open so the caller should call notmuch_database_close (or
>> + * notmuch_database_destroy) when finished with the database.
>> *
>> * In case of any failure, this function returns an error status and
>> - * sets *database to NULL (after printing an error message on stderr).
>> + * the database will be closed (after printing an error message on
>> + * stderr).
>> *
>> * Return value:
>> *
>> @@ -222,9 +247,8 @@ typedef enum {
>> * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred.
>> */
>> notmuch_status_t
>> -notmuch_database_open (const char *path,
>> - notmuch_database_mode_t mode,
>> - notmuch_database_t **database);
>> +notmuch_database_open (notmuch_database_t *notmuch, const char *path,
>> + notmuch_database_mode_t mode);
>>
>> /* Close the given notmuch database.
>> *
>> @@ -264,7 +288,8 @@ typedef void (*notmuch_compact_status_cb_t)(const char *message, void *closure);
>> * 'closure' is passed verbatim to any callback invoked.
>> */
>> notmuch_status_t
>> -notmuch_database_compact (const char* path,
>> +notmuch_database_compact (notmuch_database_t *notmuch,
>> + const char* path,
>> const char* backup_path,
>> notmuch_compact_status_cb_t status_cb,
>> void *closure);
>> @@ -272,6 +297,9 @@ notmuch_database_compact (const char* path,
>> /* Destroy the notmuch database, closing it if necessary and freeing
>> * all associated resources.
>> *
>> + * A database handle initialized with notmuch_database_new should be
>> + * destroyed by calling notmuch_database_destroy.
>> + *
>> * Return value as in notmuch_database_close if the database was open;
>> * notmuch_database_destroy itself has no failure modes.
>> */
>> diff --git a/notmuch-compact.c b/notmuch-compact.c
>> index 8b820c0..626685e 100644
>> --- a/notmuch-compact.c
>> +++ b/notmuch-compact.c
>> @@ -29,6 +29,7 @@ status_update_cb (const char *msg, unused (void *closure))
>> int
>> notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
>> {
>> + notmuch_database_t *notmuch = NULL;
>> const char *path = notmuch_config_get_database_path (config);
>> const char *backup_path = NULL;
>> notmuch_status_t ret;
>> @@ -46,7 +47,13 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
>>
>> if (! quiet)
>> printf ("Compacting database...\n");
>> - ret = notmuch_database_compact (path, backup_path,
>> +
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + ret = notmuch_database_compact (notmuch, path, backup_path,
>> quiet ? NULL : status_update_cb, NULL);
>> if (ret) {
>> fprintf (stderr, "Compaction failed: %s\n", notmuch_status_to_string (ret));
>> @@ -60,5 +67,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
>> printf ("Done.\n");
>> }
>>
>> + notmuch_database_destroy (notmuch);
>> +
>> return 0;
>> }
>> diff --git a/notmuch-count.c b/notmuch-count.c
>> index 01e4e30..15c95c7 100644
>> --- a/notmuch-count.c
>> +++ b/notmuch-count.c
>> @@ -170,8 +170,14 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])
>> return 1;
>> }
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_ONLY))
>
> Does this need to destroy the database? (Likewise for all the others.)
>
>> return 1;
>>
>> query_str = query_string_from_args (config, argc-opt_index, argv+opt_index);
>> diff --git a/notmuch-dump.c b/notmuch-dump.c
>> index 2024e30..73579bc 100644
>> --- a/notmuch-dump.c
>> +++ b/notmuch-dump.c
>> @@ -33,8 +33,14 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
>> notmuch_tags_t *tags;
>> const char *query_str = "";
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_ONLY))
>> return 1;
>>
>> char *output_file_name = NULL;
>> diff --git a/notmuch-insert.c b/notmuch-insert.c
>> index 2207b1e..4a8aad3 100644
>> --- a/notmuch-insert.c
>> +++ b/notmuch-insert.c
>> @@ -467,8 +467,14 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
>> action.sa_flags = 0;
>> sigaction (SIGINT, &action, NULL);
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_WRITE))
>> return 1;
>>
>> ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops);
>> diff --git a/notmuch-new.c b/notmuch-new.c
>> index ba05cb4..f72a4de 100644
>> --- a/notmuch-new.c
>> +++ b/notmuch-new.c
>> @@ -914,6 +914,11 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
>> return ret;
>> }
>>
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch");
>>
>> if (stat (dot_notmuch_path, &st)) {
>> @@ -925,12 +930,12 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
>> return 1;
>>
>> printf ("Found %d total files (that's not much mail).\n", count);
>> - if (notmuch_database_create (db_path, ¬much))
>> + if (notmuch_database_create (notmuch, db_path))
>> return 1;
>> add_files_state.total_files = count;
>> } else {
>> - if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
>> - ¬much))
>> + if (notmuch_database_open (notmuch, db_path,
>> + NOTMUCH_DATABASE_MODE_READ_WRITE))
>> return 1;
>>
>> if (notmuch_database_needs_upgrade (notmuch)) {
>> @@ -945,9 +950,6 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
>> add_files_state.total_files = 0;
>> }
>>
>> - if (notmuch == NULL)
>> - return 1;
>> -
>> /* Setup our handler for SIGINT. We do this after having
>> * potentially done a database upgrade we this interrupt handler
>> * won't support. */
>> diff --git a/notmuch-reply.c b/notmuch-reply.c
>> index 9d6f843..7b80841 100644
>> --- a/notmuch-reply.c
>> +++ b/notmuch-reply.c
>> @@ -769,8 +769,14 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
>> return 1;
>> }
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_ONLY))
>> return 1;
>>
>> query = notmuch_query_create (notmuch, query_string);
>> diff --git a/notmuch-restore.c b/notmuch-restore.c
>> index 1419621..fc37838 100644
>> --- a/notmuch-restore.c
>> +++ b/notmuch-restore.c
>> @@ -138,8 +138,14 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
>> int opt_index;
>> int input_format = DUMP_FORMAT_AUTO;
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_WRITE))
>> return 1;
>>
>> if (notmuch_config_get_maildir_synchronize_flags (config))
>> diff --git a/notmuch-search.c b/notmuch-search.c
>> index 7c973b3..50aace9 100644
>> --- a/notmuch-search.c
>> +++ b/notmuch-search.c
>> @@ -430,8 +430,14 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
>>
>> notmuch_exit_if_unsupported_format ();
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_ONLY))
>> return 1;
>>
>> query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index);
>> diff --git a/notmuch-show.c b/notmuch-show.c
>> index c07f887..bc44b2c 100644
>> --- a/notmuch-show.c
>> +++ b/notmuch-show.c
>> @@ -1201,8 +1201,14 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
>> return 1;
>> }
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_ONLY))
>> return 1;
>>
>> query = notmuch_query_create (notmuch, query_string);
>> diff --git a/notmuch-tag.c b/notmuch-tag.c
>> index 3b09df9..6e29799 100644
>> --- a/notmuch-tag.c
>> +++ b/notmuch-tag.c
>> @@ -254,8 +254,14 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
>> }
>> }
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_WRITE))
>> return 1;
>>
>> if (notmuch_config_get_maildir_synchronize_flags (config))
>> diff --git a/test/random-corpus.c b/test/random-corpus.c
>> index 790193d..2b205e5 100644
>> --- a/test/random-corpus.c
>> +++ b/test/random-corpus.c
>> @@ -164,8 +164,14 @@ main (int argc, char **argv)
>> if (config == NULL)
>> return 1;
>>
>> - if (notmuch_database_open (notmuch_config_get_database_path (config),
>> - NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
>> + if (notmuch_database_new (¬much)) {
>> + fprintf (stderr, "Out of memory\n");
>> + return 1;
>> + }
>> +
>> + if (notmuch_database_open (notmuch,
>> + notmuch_config_get_database_path (config),
>> + NOTMUCH_DATABASE_MODE_READ_WRITE))
>> return 1;
>>
>> srandom (seed);
>> diff --git a/test/symbol-test.cc b/test/symbol-test.cc
>> index 3e96c03..47c5351 100644
>> --- a/test/symbol-test.cc
>> +++ b/test/symbol-test.cc
>> @@ -5,7 +5,8 @@
>>
>> int main() {
>> notmuch_database_t *notmuch;
>> - notmuch_database_open("fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much);
>> + notmuch_database_new (¬much);
>> + notmuch_database_open (notmuch, "fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY);
>>
>> try {
>> (void) new Xapian::WritableDatabase("./nonexistant", Xapian::DB_OPEN);
More information about the notmuch
mailing list