]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database.cc
lib: Remove message document directly after removing the last file name.
[notmuch] / lib / database.cc
index 48abbe8e7c72bf01e0e46b00c36b89775b29b942..cf87d08d06c42cd0b41dfa1ba06d1c504b337ba7 100644 (file)
@@ -273,6 +273,8 @@ notmuch_status_to_string (notmuch_status_t status)
        return "Tag value is too long (exceeds NOTMUCH_TAG_MAX)";
     case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
        return "Unbalanced number of calls to notmuch_message_freeze/thaw";
+    case NOTMUCH_STATUS_UNBALANCED_ATOMIC:
+       return "Unbalanced number of calls to notmuch_database_begin_atomic/end_atomic";
     default:
     case NOTMUCH_STATUS_LAST_STATUS:
        return "Unknown error status value";
@@ -611,6 +613,7 @@ notmuch_database_open (const char *path,
 
     notmuch->needs_upgrade = FALSE;
     notmuch->mode = mode;
+    notmuch->atomic_nesting = 0;
     try {
        string last_thread_id;
 
@@ -977,8 +980,9 @@ 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)
-       return NOTMUCH_STATUS_SUCCESS;
+    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+       notmuch->atomic_nesting > 0)
+       goto DONE;
 
     try {
        (static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
@@ -988,6 +992,9 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch)
        notmuch->exception_reported = TRUE;
        return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
+
+DONE:
+    notmuch->atomic_nesting++;
     return NOTMUCH_STATUS_SUCCESS;
 }
 
@@ -996,8 +1003,12 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
 {
     Xapian::WritableDatabase *db;
 
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
-       return NOTMUCH_STATUS_SUCCESS;
+    if (notmuch->atomic_nesting == 0)
+       return NOTMUCH_STATUS_UNBALANCED_ATOMIC;
+
+    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+       notmuch->atomic_nesting > 1)
+       goto DONE;
 
     db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
     try {
@@ -1015,6 +1026,9 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
        notmuch->exception_reported = TRUE;
        return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
+
+DONE:
+    notmuch->atomic_nesting--;
     return NOTMUCH_STATUS_SUCCESS;
 }
 
@@ -1733,7 +1747,6 @@ notmuch_status_t
 notmuch_database_remove_message (notmuch_database_t *notmuch,
                                 const char *filename)
 {
-    Xapian::WritableDatabase *db;
     void *local;
     const char *prefix = _find_prefix ("file-direntry");
     char *direntry, *term;
@@ -1747,8 +1760,6 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,
 
     local = talloc_new (notmuch);
 
-    db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
-
     try {
 
        status = _notmuch_database_filename_to_direntry (local, notmuch,
@@ -1771,23 +1782,11 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,
                return COERCE_STATUS (private_status,
                                      "Inconsistent document ID in datbase.");
 
-           _notmuch_message_remove_filename (message, filename);
-           _notmuch_message_sync (message);
-
-           /* Take care to find document after sync'ing filename removal. */
-           document = find_document_for_doc_id (notmuch, *i);
-           j = document.termlist_begin ();
-           j.skip_to (prefix);
-
-           /* Was this the last file-direntry in the message? */
-           if (j == document.termlist_end () ||
-               strncmp ((*j).c_str (), prefix, strlen (prefix)))
-           {
-               db->delete_document (document.get_docid ());
-               status = NOTMUCH_STATUS_SUCCESS;
-           } else {
-               status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
-           }
+           status = _notmuch_message_remove_filename (message, filename);
+           if (status == NOTMUCH_STATUS_SUCCESS)
+               _notmuch_message_delete (message);
+           else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
+               _notmuch_message_sync (message);
        }
     } catch (const Xapian::Error &error) {
        fprintf (stderr, "Error: A Xapian exception occurred removing message: %s\n",