]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database.cc
lib: encapsulate the use of notmuch_database_t field 'mode'
[notmuch] / lib / database.cc
index cfb19ccb22c3752f270cd75e08b1b3d8ce97d93f..082782356d851eca7472c68a6c33930594f0d658 100644 (file)
@@ -58,6 +58,23 @@ typedef struct {
 #define DB_ACTION Xapian::DB_CREATE_OR_OPEN
 #endif
 
+#define LOG_XAPIAN_EXCEPTION(message, error) _log_xapian_exception (__location__, message, error)
+
+static void
+_log_xapian_exception (const char *where, notmuch_database_t *notmuch,  const Xapian::Error error) {
+    _notmuch_database_log (notmuch,
+                          "A Xapian exception occurred at %s: %s\n",
+                          where,
+                          error.get_msg ().c_str ());
+    notmuch->exception_reported = true;
+}
+
+notmuch_database_mode_t
+_notmuch_database_mode (notmuch_database_t *notmuch)
+{
+    return notmuch->mode;
+}
+
 /* Here's the current schema for our database (for NOTMUCH_DATABASE_VERSION):
  *
  * We currently have three different types of documents (mail, ghost,
@@ -772,7 +789,7 @@ notmuch_database_create_verbose (const char *path,
 notmuch_status_t
 _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
 {
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY) {
+    if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_ONLY) {
        _notmuch_database_log (notmuch, "Cannot write to a read-only database.\n");
        return NOTMUCH_STATUS_READ_ONLY_DATABASE;
     }
@@ -983,7 +1000,6 @@ notmuch_database_open_verbose (const char *path,
                                     "       has a newer database format version (%u) than supported by this\n"
                                     "       version of notmuch (%u).\n",
                                     notmuch_path, version, NOTMUCH_DATABASE_VERSION));
-           notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
            notmuch_database_destroy (notmuch);
            notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
@@ -1002,7 +1018,6 @@ notmuch_database_open_verbose (const char *path,
                                     "       requires features (%s)\n"
                                     "       not supported by this version of notmuch.\n",
                                     notmuch_path, incompat_features));
-           notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
            notmuch_database_destroy (notmuch);
            notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
@@ -1098,7 +1113,7 @@ notmuch_database_close (notmuch_database_t *notmuch)
             * that transaction, or may discard committed (but
             * unflushed) transactions.  To be certain, explicitly
             * cancel any outstanding transaction before closing. */
-           if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
+           if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_WRITE &&
                notmuch->atomic_nesting)
                (static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))
                ->cancel_transaction ();
@@ -1121,7 +1136,7 @@ notmuch_database_close (notmuch_database_t *notmuch)
 notmuch_status_t
 _notmuch_database_reopen (notmuch_database_t *notmuch)
 {
-    if (notmuch->mode != NOTMUCH_DATABASE_MODE_READ_ONLY)
+    if (_notmuch_database_mode (notmuch) != NOTMUCH_DATABASE_MODE_READ_ONLY)
        return NOTMUCH_STATUS_UNSUPPORTED_OPERATION;
 
     try {
@@ -1360,7 +1375,13 @@ notmuch_database_get_version (notmuch_database_t *notmuch)
     const char *str;
     char *end;
 
-    version_string = notmuch->xapian_db->get_metadata ("version");
+    try {
+       version_string = notmuch->xapian_db->get_metadata ("version");
+    } catch (const Xapian::Error &error) {
+       LOG_XAPIAN_EXCEPTION (notmuch, error);
+       return 0;
+    }
+
     if (version_string.empty ())
        return 0;
 
@@ -1378,9 +1399,17 @@ notmuch_database_get_version (notmuch_database_t *notmuch)
 notmuch_bool_t
 notmuch_database_needs_upgrade (notmuch_database_t *notmuch)
 {
-    return notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
-          ((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||
-           (notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));
+    unsigned int version;
+
+    if (_notmuch_database_mode (notmuch) != NOTMUCH_DATABASE_MODE_READ_WRITE)
+       return FALSE;
+
+    if (NOTMUCH_FEATURES_CURRENT & ~notmuch->features)
+       return TRUE;
+
+    version = notmuch_database_get_version (notmuch);
+
+    return (version > 0 && version < NOTMUCH_DATABASE_VERSION);
 }
 
 static volatile sig_atomic_t do_progress_notify = 0;
@@ -1580,8 +1609,8 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
                mtime = Xapian::sortable_unserialise (
                    document.get_value (NOTMUCH_VALUE_TIMESTAMP));
 
-               directory = _notmuch_directory_create (notmuch, term.c_str () + 10,
-                                                      NOTMUCH_FIND_CREATE, &status);
+               directory = _notmuch_directory_find_or_create (notmuch, term.c_str () + 10,
+                                                              NOTMUCH_FIND_CREATE, &status);
                notmuch_directory_set_mtime (directory, mtime);
                notmuch_directory_destroy (directory);
 
@@ -1674,7 +1703,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
 notmuch_status_t
 notmuch_database_begin_atomic (notmuch_database_t *notmuch)
 {
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+    if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_ONLY ||
        notmuch->atomic_nesting > 0)
        goto DONE;
 
@@ -1703,7 +1732,7 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
     if (notmuch->atomic_nesting == 0)
        return NOTMUCH_STATUS_UNBALANCED_ATOMIC;
 
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+    if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_ONLY ||
        notmuch->atomic_nesting > 1)
        goto DONE;
 
@@ -1853,7 +1882,7 @@ _notmuch_database_find_directory_id (notmuch_database_t *notmuch,
        return NOTMUCH_STATUS_SUCCESS;
     }
 
-    directory = _notmuch_directory_create (notmuch, path, flags, &status);
+    directory = _notmuch_directory_find_or_create (notmuch, path, flags, &status);
     if (status || ! directory) {
        *directory_id = -1;
        return status;
@@ -1963,8 +1992,8 @@ notmuch_database_get_directory (notmuch_database_t *notmuch,
     *directory = NULL;
 
     try {
-       *directory = _notmuch_directory_create (notmuch, path,
-                                               NOTMUCH_FIND_LOOKUP, &status);
+       *directory = _notmuch_directory_find_or_create (notmuch, path,
+                                                       NOTMUCH_FIND_LOOKUP, &status);
     } catch (const Xapian::Error &error) {
        _notmuch_database_log (notmuch, "A Xapian exception occurred getting directory: %s.\n",
                               error.get_msg ().c_str ());