]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database.cc
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / lib / database.cc
index 0052cb659e896841e8c54e1850864fcd0ef1e8ad..737a3f3060677b4e7fd5a55fbe5268082f0867f2 100644 (file)
@@ -309,6 +309,10 @@ notmuch_status_to_string (notmuch_status_t status)
        return "No database found";
     case NOTMUCH_STATUS_DATABASE_EXISTS:
        return "Database exists, not recreated";
+    case NOTMUCH_STATUS_BAD_QUERY_SYNTAX:
+       return "Syntax error in query";
+    case NOTMUCH_STATUS_NO_MAIL_ROOT:
+       return "No mail root found";
     default:
     case NOTMUCH_STATUS_LAST_STATUS:
        return "Unknown error status value";
@@ -472,6 +476,11 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
        return NOTMUCH_STATUS_READ_ONLY_DATABASE;
     }
 
+    if (! notmuch->open) {
+       _notmuch_database_log (notmuch, "Cannot write to a closed database.\n");
+       return NOTMUCH_STATUS_CLOSED_DATABASE;
+    }
+
     return NOTMUCH_STATUS_SUCCESS;
 }
 
@@ -502,17 +511,9 @@ notmuch_database_close (notmuch_database_t *notmuch)
      * close it.  Thus, we explicitly close it here. */
     if (notmuch->open) {
        try {
-           /* If there's an outstanding transaction, it's unclear if
-            * closing the Xapian database commits everything up to
-            * that transaction, or may discard committed (but
-            * unflushed) transactions.  To be certain, explicitly
-            * cancel any outstanding transaction before closing. */
-           if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_WRITE &&
-               notmuch->atomic_nesting)
-               notmuch->writable_xapian_db->cancel_transaction ();
-
            /* Close the database.  This implicitly flushes
-            * outstanding changes. */
+            * outstanding changes. If there is an open (non-flushed)
+            * transaction, ALL pending changes will be discarded */
            notmuch->xapian_db->close ();
        } catch (const Xapian::Error &error) {
            status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
@@ -596,10 +597,12 @@ notmuch_database_compact (const char *path,
     notmuch_database_t *notmuch = NULL;
     char *message = NULL;
 
-    ret = notmuch_database_open_verbose (path,
-                                        NOTMUCH_DATABASE_MODE_READ_WRITE,
-                                        &notmuch,
-                                        &message);
+    ret = notmuch_database_open_with_config (path,
+                                            NOTMUCH_DATABASE_MODE_READ_WRITE,
+                                            "",
+                                            NULL,
+                                            &notmuch,
+                                            &message);
     if (ret) {
        if (status_cb) status_cb (message, closure);
        return ret;
@@ -733,7 +736,7 @@ notmuch_status_t
 notmuch_database_destroy (notmuch_database_t *notmuch)
 {
     notmuch_status_t status;
-    const chartalloc_report;
+    const char *talloc_report;
 
     talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");
     if (talloc_report && strcmp (talloc_report, "") != 0) {
@@ -757,6 +760,8 @@ notmuch_database_destroy (notmuch_database_t *notmuch)
     notmuch->date_range_processor = NULL;
     delete notmuch->last_mod_range_processor;
     notmuch->last_mod_range_processor = NULL;
+    delete notmuch->stemmer;
+    notmuch->stemmer = NULL;
 
     talloc_free (notmuch);
 
@@ -852,9 +857,8 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
     notmuch_query_t *query = NULL;
     unsigned int count = 0, total = 0;
 
-    status = _notmuch_database_ensure_writable (notmuch);
-    if (status)
-       return status;
+    if (_notmuch_database_mode (notmuch) != NOTMUCH_DATABASE_MODE_READ_WRITE)
+       return NOTMUCH_STATUS_READ_ONLY_DATABASE;
 
     db = notmuch->writable_xapian_db;
 
@@ -1142,13 +1146,21 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
     db = notmuch->writable_xapian_db;
     try {
        db->commit_transaction ();
-
-       /* This is a hack for testing.  Xapian never flushes on a
-        * non-flushed commit, even if the flush threshold is 1.
-        * However, we rely on flushing to test atomicity. */
+       notmuch->transaction_count++;
+
+       /* Xapian never flushes on a non-flushed commit, even if the
+        * flush threshold is 1.  However, we rely on flushing to test
+        * atomicity. On the other hand, we can't straight replace
+        * XAPIAN_FLUSH_THRESHOLD with our autocommit counter, because
+        * the former also applies outside notmuch atomic
+        * commits. Hence the follow complicated  test */
        const char *thresh = getenv ("XAPIAN_FLUSH_THRESHOLD");
-       if (thresh && atoi (thresh) == 1)
+       if ((notmuch->transaction_threshold > 0 &&
+            notmuch->transaction_count >= notmuch->transaction_threshold) ||
+           (thresh && atoi (thresh) == 1)) {
            db->commit ();
+           notmuch->transaction_count = 0;
+       }
     } catch (const Xapian::Error &error) {
        _notmuch_database_log (notmuch, "A Xapian exception occurred committing transaction: %s.\n",
                               error.get_msg ().c_str ());
@@ -1442,9 +1454,11 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,
                                                        &message);
 
     if (status == NOTMUCH_STATUS_SUCCESS && message) {
-       status = _notmuch_message_remove_filename (message, filename);
+       if (notmuch_message_count_files (message) > 1) {
+           status = _notmuch_message_remove_filename (message, filename);
+       }
        if (status == NOTMUCH_STATUS_SUCCESS)
-           _notmuch_message_delete (message);
+           status = _notmuch_message_delete (message);
        else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
            _notmuch_message_sync (message);
 
@@ -1561,3 +1575,15 @@ notmuch_database_status_string (const notmuch_database_t *notmuch)
 {
     return notmuch->status_string;
 }
+
+bool
+_notmuch_database_indexable_as_text (notmuch_database_t *notmuch, const char *mime_string)
+{
+    for (size_t i = 0; i < notmuch->index_as_text_length; i++) {
+       if (regexec (&notmuch->index_as_text[i], mime_string, 0, NULL, 0) == 0) {
+           return true;
+       }
+    }
+
+    return false;
+}