aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAustin Clements <amdragon@MIT.EDU>2012-05-18 00:13:34 -0400
committerDavid Bremner <bremner@debian.org>2012-05-23 22:30:20 -0300
commitf69314fbd37f403a395b7c1c44595c8f696b05b7 (patch)
tree1d533e466d14fd0c886fff2622e3ffd4895f2a4e /lib
parent70ca3444c75beaa693fcac411dd6a2819bd4341e (diff)
lib: Make directory document creation optional for _notmuch_directory_create
Previously this function would create directory documents if they didn't exist. As a result, it could only be used on writable databases. This adds an argument to make creation optional and to make this function work on read-only databases. We use a flag argument to avoid a bare boolean and to permit future expansion. Both callers have been updated, but currently retain the old behavior. We'll take advantage of the new argument in the following patches.
Diffstat (limited to 'lib')
-rw-r--r--lib/database.cc6
-rw-r--r--lib/directory.cc33
-rw-r--r--lib/notmuch-private.h8
3 files changed, 39 insertions, 8 deletions
diff --git a/lib/database.cc b/lib/database.cc
index f8c4a7d..df996a9 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -956,7 +956,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
document.get_value (NOTMUCH_VALUE_TIMESTAMP));
directory = _notmuch_directory_create (notmuch, term.c_str() + 10,
- &status);
+ NOTMUCH_FIND_CREATE, &status);
notmuch_directory_set_mtime (directory, mtime);
notmuch_directory_destroy (directory);
}
@@ -1210,7 +1210,7 @@ _notmuch_database_find_directory_id (notmuch_database_t *notmuch,
return NOTMUCH_STATUS_SUCCESS;
}
- directory = _notmuch_directory_create (notmuch, path, &status);
+ directory = _notmuch_directory_create (notmuch, path, NOTMUCH_FIND_CREATE, &status);
if (status) {
*directory_id = -1;
return status;
@@ -1320,7 +1320,7 @@ notmuch_database_get_directory (notmuch_database_t *notmuch,
return NOTMUCH_STATUS_READ_ONLY_DATABASE;
try {
- *directory = _notmuch_directory_create (notmuch, path, &status);
+ *directory = _notmuch_directory_create (notmuch, path, NOTMUCH_FIND_CREATE, &status);
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred getting directory: %s.\n",
error.get_msg().c_str());
diff --git a/lib/directory.cc b/lib/directory.cc
index 70e1693..83bb19b 100644
--- a/lib/directory.cc
+++ b/lib/directory.cc
@@ -82,28 +82,41 @@ find_directory_document (notmuch_database_t *notmuch,
return NOTMUCH_PRIVATE_STATUS_SUCCESS;
}
+/* Find or create a directory document.
+ *
+ * 'path' should be a path relative to the path of 'database', or else
+ * should be an absolute path with initial components that match the
+ * path of 'database'.
+ *
+ * If (flags & NOTMUCH_FIND_CREATE), then the directory document will
+ * be created if it does not exist. Otherwise, if the directory
+ * document does not exist, *status_ret is set to
+ * NOTMUCH_STATUS_SUCCESS and this returns NULL.
+ */
notmuch_directory_t *
_notmuch_directory_create (notmuch_database_t *notmuch,
const char *path,
+ notmuch_find_flags_t flags,
notmuch_status_t *status_ret)
{
Xapian::WritableDatabase *db;
notmuch_directory_t *directory;
notmuch_private_status_t private_status;
const char *db_path;
+ notmuch_bool_t create = (flags & NOTMUCH_FIND_CREATE);
*status_ret = NOTMUCH_STATUS_SUCCESS;
path = _notmuch_database_relative_path (notmuch, path);
- if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
+ if (create && notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
INTERNAL_ERROR ("Failure to ensure database is writable");
- db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
-
directory = talloc (notmuch, notmuch_directory_t);
- if (unlikely (directory == NULL))
+ if (unlikely (directory == NULL)) {
+ *status_ret = NOTMUCH_STATUS_OUT_OF_MEMORY;
return NULL;
+ }
directory->notmuch = notmuch;
@@ -122,6 +135,13 @@ _notmuch_directory_create (notmuch_database_t *notmuch,
directory->document_id = directory->doc.get_docid ();
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
+ if (!create) {
+ notmuch_directory_destroy (directory);
+ directory = NULL;
+ *status_ret = NOTMUCH_STATUS_SUCCESS;
+ goto DONE;
+ }
+
void *local = talloc_new (directory);
const char *parent, *basename;
Xapian::docid parent_id;
@@ -145,6 +165,8 @@ _notmuch_directory_create (notmuch_database_t *notmuch,
directory->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
Xapian::sortable_serialise (0));
+ db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
+
directory->document_id = _notmuch_database_generate_doc_id (notmuch);
db->replace_document (directory->document_id, directory->doc);
talloc_free (local);
@@ -158,10 +180,11 @@ _notmuch_directory_create (notmuch_database_t *notmuch,
error.get_msg().c_str());
notmuch->exception_reported = TRUE;
notmuch_directory_destroy (directory);
+ directory = NULL;
*status_ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
- return NULL;
}
+ DONE:
if (db_path != path)
free ((char *) db_path);
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 3886e0c..538274f 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -146,6 +146,13 @@ typedef enum _notmuch_private_status {
: \
(notmuch_status_t) private_status)
+/* Flags shared by various lookup functions. */
+typedef enum _notmuch_find_flags {
+ /* If set, create the necessary document (or documents) if they
+ * are missing. Requires a read/write database. */
+ NOTMUCH_FIND_CREATE = 1<<0,
+} notmuch_find_flags_t;
+
typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
typedef struct _notmuch_string_list notmuch_string_list_t;
@@ -206,6 +213,7 @@ _notmuch_database_filename_to_direntry (void *ctx,
notmuch_directory_t *
_notmuch_directory_create (notmuch_database_t *notmuch,
const char *path,
+ notmuch_find_flags_t flags,
notmuch_status_t *status_ret);
unsigned int