diff --git a/lib/database.cc b/lib/database.cc index 07f186ed..f8c4a7d1 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -955,8 +955,8 @@ notmuch_database_upgrade (notmuch_database_t *notmuch, mtime = Xapian::sortable_unserialise ( document.get_value (NOTMUCH_VALUE_TIMESTAMP)); - directory = notmuch_database_get_directory (notmuch, - term.c_str() + 10); + directory = _notmuch_directory_create (notmuch, term.c_str() + 10, + &status); notmuch_directory_set_mtime (directory, mtime); notmuch_directory_destroy (directory); } @@ -1304,20 +1304,30 @@ _notmuch_database_relative_path (notmuch_database_t *notmuch, return relative; } -notmuch_directory_t * +notmuch_status_t notmuch_database_get_directory (notmuch_database_t *notmuch, - const char *path) + const char *path, + notmuch_directory_t **directory) { notmuch_status_t status; + if (directory == NULL) + return NOTMUCH_STATUS_NULL_POINTER; + *directory = NULL; + + /* XXX Handle read-only databases properly */ + if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY) + return NOTMUCH_STATUS_READ_ONLY_DATABASE; + try { - return _notmuch_directory_create (notmuch, path, &status); + *directory = _notmuch_directory_create (notmuch, path, &status); } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred getting directory: %s.\n", error.get_msg().c_str()); notmuch->exception_reported = TRUE; - return NULL; + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; } + return status; } /* Allocate a document ID that satisfies the following criteria: diff --git a/lib/notmuch.h b/lib/notmuch.h index e6e5cc2e..bbb17e4a 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -300,11 +300,28 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); * (see notmuch_database_get_path), or else should be an absolute path * with initial components that match the path of 'database'. * - * Can return NULL if a Xapian exception occurs. + * Note: Currently this will create the directory object if it doesn't + * exist. In the future, when a directory object does not exist this + * will return NOTMUCH_STATUS_SUCCESS and set *directory to NULL. + * Callers should be prepared for this. + * + * Return value: + * + * NOTMUCH_STATUS_SUCCESS: Successfully retrieved directory. + * + * NOTMUCH_STATUS_NULL_POINTER: The given 'directory' argument is NULL. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred; + * directory not retrieved. + * + * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only + * mode so the directory cannot be created (this case will be + * removed in the future). */ -notmuch_directory_t * +notmuch_status_t notmuch_database_get_directory (notmuch_database_t *database, - const char *path); + const char *path, + notmuch_directory_t **directory); /* Add a new message to the given notmuch database or associate an * additional filename with an existing message. diff --git a/notmuch-new.c b/notmuch-new.c index cb720cc2..a3a8bece 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -250,7 +250,7 @@ add_files_recursive (notmuch_database_t *notmuch, notmuch_status_t status, ret = NOTMUCH_STATUS_SUCCESS; notmuch_message_t *message = NULL; struct dirent **fs_entries = NULL; - int i, num_fs_entries; + int i, num_fs_entries = 0; notmuch_directory_t *directory; notmuch_filenames_t *db_files = NULL; notmuch_filenames_t *db_subdirs = NULL; @@ -274,8 +274,12 @@ add_files_recursive (notmuch_database_t *notmuch, fs_mtime = st.st_mtime; - directory = notmuch_database_get_directory (notmuch, path); - db_mtime = notmuch_directory_get_mtime (directory); + status = notmuch_database_get_directory (notmuch, path, &directory); + if (status) { + ret = status; + goto DONE; + } + db_mtime = directory ? notmuch_directory_get_mtime (directory) : 0; new_directory = db_mtime ? FALSE : TRUE; @@ -295,7 +299,7 @@ add_files_recursive (notmuch_database_t *notmuch, * by a new out-argument, or by recording this information and * providing an accessor. */ - if (new_directory) + if (new_directory && directory) notmuch_directory_set_mtime (directory, -1); /* If the database knows about this directory, then we sort based @@ -810,7 +814,9 @@ _remove_directory (void *ctx, notmuch_filenames_t *files, *subdirs; char *absolute; - directory = notmuch_database_get_directory (notmuch, path); + status = notmuch_database_get_directory (notmuch, path, &directory); + if (status || !directory) + return status; for (files = notmuch_directory_get_child_files (directory); notmuch_filenames_valid (files); @@ -981,9 +987,10 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) } for (f = add_files_state.directory_mtimes->head; f && !interrupted; f = f->next) { + notmuch_status_t status; notmuch_directory_t *directory; - directory = notmuch_database_get_directory (notmuch, f->filename); - if (directory) { + status = notmuch_database_get_directory (notmuch, f->filename, &directory); + if (status == NOTMUCH_STATUS_SUCCESS && directory) { notmuch_directory_set_mtime (directory, f->mtime); notmuch_directory_destroy (directory); }