From: Austin Clements Date: Wed, 4 Dec 2013 23:11:13 +0000 (+1900) Subject: Re: [PATCH 2/2] lib: introduce notmuch_database_new for initializing a database handle X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a3ca60f4cd78c2ac9c76a8782fc8ba96b3cb1818;p=notmuch-archives.git Re: [PATCH 2/2] lib: introduce notmuch_database_new for initializing a database handle --- diff --git a/a4/6560f778037588e9b0da21e18106f3cfc7074d b/a4/6560f778037588e9b0da21e18106f3cfc7074d new file mode 100644 index 000000000..84013f8bd --- /dev/null +++ b/a4/6560f778037588e9b0da21e18106f3cfc7074d @@ -0,0 +1,744 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id 491BB431FD2 + for ; Wed, 4 Dec 2013 15:11:28 -0800 (PST) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: -0.7 +X-Spam-Level: +X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 + tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id OryFt9l6vpw4 for ; + Wed, 4 Dec 2013 15:11:23 -0800 (PST) +Received: from dmz-mailsec-scanner-8.mit.edu (dmz-mailsec-scanner-8.mit.edu + [18.7.68.37]) + (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) + (No client certificate requested) + by olra.theworths.org (Postfix) with ESMTPS id 7A010431FD0 + for ; Wed, 4 Dec 2013 15:11:22 -0800 (PST) +X-AuditID: 12074425-b7fd96d000000c39-7e-529fb698e984 +Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) + (using TLS with cipher AES256-SHA (256/256 bits)) + (Client did not present a certificate) + by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP + id 8F.AE.03129.896BF925; Wed, 4 Dec 2013 18:11:20 -0500 (EST) +Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) + by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id rB4NBJJ7032395; + Wed, 4 Dec 2013 18:11:20 -0500 +Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) + (authenticated bits=0) + (User authenticated as amdragon@ATHENA.MIT.EDU) + by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id rB4NBGGu022234 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT); + Wed, 4 Dec 2013 18:11:18 -0500 +Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80) + (envelope-from ) + id 1VoLb7-0002im-TJ; Wed, 04 Dec 2013 18:11:15 -0500 +Date: Wed, 4 Dec 2013 18:11:13 -0500 +From: Austin Clements +To: Jani Nikula +Subject: Re: [PATCH 2/2] lib: introduce notmuch_database_new for initializing + a database handle +Message-ID: <20131204231113.GD8854@mit.edu> +References: + +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +In-Reply-To: + +User-Agent: Mutt/1.5.21 (2010-09-15) +X-Brightmail-Tracker: + H4sIAAAAAAAAA+NgFmplleLIzCtJLcpLzFFi42IRYrdT152xbX6QwawPKhZN050trt+cyezA + 5HHr/mt2j2erbjEHMEVx2aSk5mSWpRbp2yVwZex5uImloPsIY8WEjuuMDYyPZzJ2MXJySAiY + SLy9fw3KFpO4cG89WxcjF4eQwGwmic7PW5ghnA2MEr+71rBCOKeYJC6tvcAI4SxhlNjw/T8z + SD+LgIpE/7ElbCA2m4CGxLb9y8HmiggoSmw+uR/MZhaQlvj2u5kJxBYWSJS4unkvWD2vgLbE + /fZ2VhBbSKBOYt66fqi4oMTJmU9YIHq1JG78ewnUywE2Z/k/DpAwp0CYxI2OxewgtijQCVNO + bmObwCg0C0n3LCTdsxC6FzAyr2KUTcmt0s1NzMwpTk3WLU5OzMtLLdK10MvNLNFLTSndxAgO + bRfVHYwTDikdYhTgYFTi4XVImR8kxJpYVlyZe4hRkoNJSZTXZiNQiC8pP6UyI7E4I76oNCe1 + +BCjBAezkgjvvxqgHG9KYmVValE+TEqag0VJnPcWh32QkEB6YklqdmpqQWoRTFaGg0NJgvfH + VqBGwaLU9NSKtMycEoQ0EwcnyHAeoOGXQWp4iwsSc4sz0yHypxgVpcR580ASAiCJjNI8uF5Y + 6nnFKA70ijDvbZAqHmDagut+BTSYCWhw84N5IINLEhFSUg2MzTu/Z7Zmthk8mjLZhFF+d7Pr + 1EPlktd5+ucGNt2qlssvWzbP8aWnQkbirMDm7k4PnTt35WO2aS4WLhDVvfZp3wHnD8EvDc8m + 54XaxLpKH93R5Pgn26Xsi1zNknMfroW0+lgt41plNiW+hC2O63Tlp/pnV4VW822vXsP7btuB + z1d6Txs8FStRYinOSDTUYi4qTgQAf5Qg3RgDAAA= +Cc: notmuch@notmuchmail.org +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Wed, 04 Dec 2013 23:11:28 -0000 + +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.) 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"). + +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). + +> --- +> 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). + +> +{ +> + /* 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);