database: Add new, public notmuch_database_remove_message
authorCarl Worth <cworth@cworth.org>
Mon, 21 Dec 2009 23:14:32 +0000 (15:14 -0800)
committerCarl Worth <cworth@cworth.org>
Wed, 6 Jan 2010 18:32:06 +0000 (10:32 -0800)
This will allow applications to support the removal of messages, (such
as when a file is deleted from the mail store). No removal support is
provided yet in commands such as "notmuch new".

lib/database.cc
lib/notmuch.h

index cd3346fd54ee140bd9de4fb077538533a39d8d4d..a3824956fc2fdbcedea927a4cd60a49a613b1f29 100644 (file)
@@ -1278,6 +1278,59 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     return ret;
 }
 
+notmuch_status_t
+notmuch_database_remove_message (notmuch_database_t *notmuch,
+                                const char *filename)
+{
+    Xapian::WritableDatabase *db;
+    void *local = talloc_new (notmuch);
+    const char *direntry_prefix = _find_prefix ("direntry");
+    char *direntry, *term;
+    Xapian::PostingIterator i, end;
+    Xapian::Document document;
+    notmuch_status_t status;
+
+    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY) {
+       fprintf (stderr, "Attempted to update a read-only database.\n");
+       return NOTMUCH_STATUS_READONLY_DATABASE;
+    }
+
+    db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
+
+    status = _notmuch_database_filename_to_direntry (local, notmuch,
+                                                    filename, &direntry);
+    if (status)
+       return status;
+
+    term = talloc_asprintf (notmuch, "%s%s", direntry_prefix, direntry);
+
+    find_doc_ids_for_term (notmuch, term, &i, &end);
+
+    for ( ; i != end; i++) {
+       Xapian::TermIterator j;
+
+       document = find_document_for_doc_id (notmuch, *i);
+
+       document.remove_term (term);
+
+       j = document.termlist_begin ();
+       j.skip_to (direntry_prefix);
+
+       /* Was this the last direntry in the message? */
+       if (j == document.termlist_end () ||
+           strncmp ((*j).c_str (), direntry_prefix, strlen (direntry_prefix)))
+       {
+           db->delete_document (document.get_docid ());
+       } else {
+           db->replace_document (document.get_docid (), document);
+       }
+    }
+
+    talloc_free (local);
+
+    return NOTMUCH_STATUS_SUCCESS;
+}
+
 notmuch_tags_t *
 _notmuch_convert_tags (void *ctx, Xapian::TermIterator &i,
                       Xapian::TermIterator &end)
index e96474f65861b94b30d538f5e3baebb5da4bf0c9..2e59865633ffa6ce7b8206ec7d14ac1202b618e9 100644 (file)
@@ -267,6 +267,19 @@ notmuch_database_add_message (notmuch_database_t *database,
                              const char *filename,
                              notmuch_message_t **message);
 
+/* Remove a message from the given notmuch database.
+ *
+ * Note that the only this particular filename association is removed
+ * from the database. If the same message (as determined by the
+ * message ID) is still available via other filenames, then the
+ * message will persist in the database for those filenames. When the
+ * last filename is removed for a particular message, the database
+ * content for that message will be entirely removed.
+ */
+notmuch_status_t
+notmuch_database_remove_message (notmuch_database_t *database,
+                                const char *filename);
+
 /* Find a message with the given message_id.
  *
  * If the database contains a message with the given message_id, then