return "Unknown crypto protocol";
case NOTMUCH_STATUS_NO_CONFIG:
return "No configuration file found";
+ case NOTMUCH_STATUS_NO_DATABASE:
+ 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";
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;
}
* 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;
notmuch_database_t *notmuch = NULL;
char *message = NULL;
- ret = notmuch_database_open_verbose (path,
- NOTMUCH_DATABASE_MODE_READ_WRITE,
- ¬much,
- &message);
+ ret = notmuch_database_open_with_config (path,
+ NOTMUCH_DATABASE_MODE_READ_WRITE,
+ "",
+ NULL,
+ ¬much,
+ &message);
if (ret) {
if (status_cb) status_cb (message, closure);
return ret;
notmuch_database_destroy (notmuch_database_t *notmuch)
{
notmuch_status_t status;
+ const char *talloc_report;
+
+ talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");
+ if (talloc_report && strcmp (talloc_report, "") != 0) {
+ FILE *report = fopen (talloc_report, "a");
+ if (report) {
+ talloc_report_full (notmuch, report);
+ }
+ }
status = notmuch_database_close (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);
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;
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 ());
if (status == NOTMUCH_STATUS_SUCCESS && message) {
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);
{
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 (¬much->index_as_text[i], mime_string, 0, NULL, 0) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}