diff --git a/NEWS b/NEWS index 081c6089..13eff6e0 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ Restore handling of relative values for `database.path` that was broken by 0.32. Extend this handling to `database.mail_root`, `database.backup_dir`, and `database.hook_dir`. +Reload certain metadata from Xapian database in +notmuch_database_reopen. This fixes a bug when adding messages to the +database in a pre-new hook. + Notmuch 0.32 (2021-05-02) ========================= diff --git a/lib/open.cc b/lib/open.cc index bdb695fe..1e9c86fe 100644 --- a/lib/open.cc +++ b/lib/open.cc @@ -325,6 +325,37 @@ _init_libs () } } +static void +_load_database_state (notmuch_database_t *notmuch) +{ + std::string last_thread_id; + std::string last_mod; + + notmuch->last_doc_id = notmuch->xapian_db->get_lastdocid (); + last_thread_id = notmuch->xapian_db->get_metadata ("last_thread_id"); + if (last_thread_id.empty ()) { + notmuch->last_thread_id = 0; + } else { + const char *str; + char *end; + + str = last_thread_id.c_str (); + notmuch->last_thread_id = strtoull (str, &end, 16); + if (*end != '\0') + INTERNAL_ERROR ("Malformed database last_thread_id: %s", str); + } + + /* Get current highest revision number. */ + last_mod = notmuch->xapian_db->get_value_upper_bound ( + NOTMUCH_VALUE_LAST_MOD); + if (last_mod.empty ()) + notmuch->revision = 0; + else + notmuch->revision = Xapian::sortable_unserialise (last_mod); + notmuch->uuid = talloc_strdup ( + notmuch, notmuch->xapian_db->get_uuid ().c_str ()); +} + static notmuch_status_t _finish_open (notmuch_database_t *notmuch, const char *profile, @@ -339,8 +370,6 @@ _finish_open (notmuch_database_t *notmuch, const char *database_path = notmuch_database_get_path (notmuch); try { - std::string last_thread_id; - std::string last_mod; if (mode == NOTMUCH_DATABASE_MODE_READ_WRITE) { notmuch->writable_xapian_db = new Xapian::WritableDatabase (notmuch->xapian_path, @@ -384,29 +413,7 @@ _finish_open (notmuch_database_t *notmuch, goto DONE; } - notmuch->last_doc_id = notmuch->xapian_db->get_lastdocid (); - last_thread_id = notmuch->xapian_db->get_metadata ("last_thread_id"); - if (last_thread_id.empty ()) { - notmuch->last_thread_id = 0; - } else { - const char *str; - char *end; - - str = last_thread_id.c_str (); - notmuch->last_thread_id = strtoull (str, &end, 16); - if (*end != '\0') - INTERNAL_ERROR ("Malformed database last_thread_id: %s", str); - } - - /* Get current highest revision number. */ - last_mod = notmuch->xapian_db->get_value_upper_bound ( - NOTMUCH_VALUE_LAST_MOD); - if (last_mod.empty ()) - notmuch->revision = 0; - else - notmuch->revision = Xapian::sortable_unserialise (last_mod); - notmuch->uuid = talloc_strdup ( - notmuch, notmuch->xapian_db->get_uuid ().c_str ()); + _load_database_state (notmuch); notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; @@ -733,6 +740,8 @@ notmuch_database_reopen (notmuch_database_t *notmuch, DB_ACTION); } } + + _load_database_state (notmuch); } catch (const Xapian::Error &error) { if (! notmuch->exception_reported) { _notmuch_database_log (notmuch, "Error: A Xapian exception reopening database: %s\n", diff --git a/test/T400-hooks.sh b/test/T400-hooks.sh index 00c99337..0c84b7dd 100755 --- a/test/T400-hooks.sh +++ b/test/T400-hooks.sh @@ -28,6 +28,16 @@ EOF echo "${TOKEN}" > ${2} } +create_change_hook () { + mkdir -p ${HOOK_DIR} + cat <"${HOOK_DIR}/${1}" +#!/bin/sh +notmuch insert --no-hooks < ${2} > /dev/null +rm -f ${2} +EOF + chmod +x "${HOOK_DIR}/${1}" +} + create_failing_hook () { local HOOK_DIR=${2} mkdir -p ${HOOK_DIR} @@ -176,6 +186,20 @@ EOF NOTMUCH_NEW test_expect_equal_file write.expected write.output + test_begin_subtest "add message in pre-new [${config}]" + rm -rf ${HOOK_DIR} + generate_message '[subject]="add msg in pre-new"' + id1=$gen_msg_id + create_change_hook "pre-new" $gen_msg_filename $HOOK_DIR + generate_message '[subject]="add msg in new"' + NOTMUCH_NEW + notmuch search id:$id1 or id:$gen_msg_id | notmuch_search_sanitize > OUTPUT + cat < EXPECTED + thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; add msg in pre-new (inbox unread) + thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; add msg in new (inbox unread) +EOF + test_expect_equal_file EXPECTED OUTPUT + rm -rf ${HOOK_DIR} done test_done