summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
e4379c4)
Previously, notmuch_database_remove_message would remove the message
file name, sync the change to the message document, re-find the
message document, and then delete it if there were no more file names.
An interruption after sync'ing would result in a file-name-less,
permanently un-removable zombie message that would produce errors and
odd results in searches. We could wrap this in an atomic section, but
it's much simpler to eliminate the round-about approach and just
delete the message document instead of sync'ing it if we removed the
last filename.
notmuch_database_remove_message (notmuch_database_t *notmuch,
const char *filename)
{
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;
void *local;
const char *prefix = _find_prefix ("file-direntry");
char *direntry, *term;
local = talloc_new (notmuch);
local = talloc_new (notmuch);
- db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
-
try {
status = _notmuch_database_filename_to_direntry (local, notmuch,
try {
status = _notmuch_database_filename_to_direntry (local, notmuch,
return COERCE_STATUS (private_status,
"Inconsistent document ID in datbase.");
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",
}
} catch (const Xapian::Error &error) {
fprintf (stderr, "Error: A Xapian exception occurred removing message: %s\n",
db->replace_document (message->doc_id, message->doc);
}
db->replace_document (message->doc_id, message->doc);
}
+/* Delete a message document from the database. */
+notmuch_status_t
+_notmuch_message_delete (notmuch_message_t *message)
+{
+ notmuch_status_t status;
+ Xapian::WritableDatabase *db;
+
+ status = _notmuch_database_ensure_writable (message->notmuch);
+ if (status)
+ return status;
+
+ db = static_cast <Xapian::WritableDatabase *> (message->notmuch->xapian_db);
+ db->delete_document (message->doc_id);
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
/* Ensure that 'message' is not holding any file object open. Future
* calls to various functions will still automatically open the
* message file as needed.
/* Ensure that 'message' is not holding any file object open. Future
* calls to various functions will still automatically open the
* message file as needed.
void
_notmuch_message_sync (notmuch_message_t *message);
void
_notmuch_message_sync (notmuch_message_t *message);
+notmuch_status_t
+_notmuch_message_delete (notmuch_message_t *message);
+
void
_notmuch_message_close (notmuch_message_t *message);
void
_notmuch_message_close (notmuch_message_t *message);