[RFC patch 5/5] WIP: index user headers
David Bremner
david at tethera.net
Sat Nov 17 06:09:01 PST 2018
---
lib/database.cc | 37 +++++++++++++++++++++++++++++--------
lib/index.cc | 34 ++++++++++++++++++++++++++++++++++
lib/message.cc | 5 ++++-
lib/notmuch-private.h | 4 ++++
test/T720-user-header.sh | 17 +++++++++++++++++
5 files changed, 88 insertions(+), 9 deletions(-)
diff --git a/lib/database.cc b/lib/database.cc
index b2654ab7..c25d867f 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -293,8 +293,6 @@ prefix_t prefix_table[] = {
NOTMUCH_FIELD_PROCESSOR},
};
-#define CONFIG_HEADER_PREFIX "index.header."
-
static void
_setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch)
{
@@ -308,7 +306,6 @@ static notmuch_status_t
_setup_user_query_fields (notmuch_database_t *notmuch)
{
notmuch_config_list_t *list;
- void *local = talloc_new(notmuch);
notmuch_status_t status;
size_t prefix_capacity = 4;
@@ -318,7 +315,7 @@ _setup_user_query_fields (notmuch_database_t *notmuch)
if (notmuch->user_prefix == NULL)
return NOTMUCH_STATUS_OUT_OF_MEMORY;
- status = notmuch_database_get_config_list (notmuch, "index.header.", &list);
+ status = notmuch_database_get_config_list (notmuch, CONFIG_HEADER_PREFIX, &list);
if (status)
return status;
for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
@@ -333,11 +330,11 @@ _setup_user_query_fields (notmuch_database_t *notmuch)
const char *key = notmuch_config_list_key (list)
+ sizeof (CONFIG_HEADER_PREFIX) - 1;
- char *prefix = talloc_asprintf(local, "XU:%s", key);
+ char *prefix = talloc_asprintf(notmuch, "XU:%s", key);
for (char *p = prefix + 1; *p; p++)
*p = toupper (*p);
- query_field->name = key;
+ query_field->name = talloc_strdup(notmuch, key);
query_field->prefix = prefix;
query_field->flags = NOTMUCH_FIELD_PROBABILISTIC | NOTMUCH_FIELD_EXTERNAL;
@@ -346,8 +343,6 @@ _setup_user_query_fields (notmuch_database_t *notmuch)
prefix_index++;
}
- talloc_free (local);
-
notmuch_config_list_destroy (list);
return NOTMUCH_STATUS_SUCCESS;
@@ -399,6 +394,32 @@ _find_prefix (const char *name)
return "";
}
+const char *
+_maybe_user_prefix (notmuch_database_t *notmuch, const char *name)
+{
+
+ unsigned int i;
+
+ /*XXX TODO: reduce code duplication */
+ for (i = 0; i < ARRAY_SIZE (prefix_table); i++) {
+ if (strcmp (name, prefix_table[i].name) == 0)
+ return prefix_table[i].prefix;
+ }
+
+ if (notmuch->user_prefix) {
+ unsigned int i;
+
+ for (i = 0; notmuch->user_prefix[i].name; i++) {
+ if (strcmp (name, notmuch->user_prefix[i].name) == 0)
+ return notmuch->user_prefix[i].prefix;
+ }
+ }
+
+ return NULL;
+}
+
+
+
static const struct {
/* NOTMUCH_FEATURE_* value. */
_notmuch_features value;
diff --git a/lib/index.cc b/lib/index.cc
index efd9da4c..6324b5a0 100644
--- a/lib/index.cc
+++ b/lib/index.cc
@@ -595,6 +595,38 @@ _index_encrypted_mime_part (notmuch_message_t *message,
}
+static notmuch_status_t
+_notmuch_message_index_user_headers (notmuch_message_t *message, GMimeMessage *mime_message) {
+ notmuch_database_t *notmuch = notmuch_message_get_database (message);
+
+ notmuch_config_list_t *list;
+ notmuch_status_t status;
+
+ status = notmuch_database_get_config_list (notmuch, CONFIG_HEADER_PREFIX, &list);
+ if (status)
+ return status;
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+
+ const char *prefix_name = notmuch_config_list_key (list)
+ + sizeof (CONFIG_HEADER_PREFIX) - 1;
+
+ const char *header_name = notmuch_config_list_value (list);
+
+ /* this is gmime 3.0 specific, I think */
+
+ const char *header = g_mime_object_get_header (GMIME_OBJECT (mime_message), header_name);
+ if (header == NULL)
+ return NOTMUCH_STATUS_SUCCESS;
+
+
+ _notmuch_message_gen_terms (message, prefix_name, header);
+ }
+
+ return NOTMUCH_STATUS_SUCCESS;
+
+}
+
+
notmuch_status_t
_notmuch_message_index_file (notmuch_message_t *message,
notmuch_indexopts_t *indexopts,
@@ -625,6 +657,8 @@ _notmuch_message_index_file (notmuch_message_t *message,
subject = g_mime_message_get_subject (mime_message);
_notmuch_message_gen_terms (message, "subject", subject);
+ status = _notmuch_message_index_user_headers (message, mime_message);
+
_index_mime_part (message, indexopts, g_mime_message_get_mime_part (mime_message));
return NOTMUCH_STATUS_SUCCESS;
diff --git a/lib/message.cc b/lib/message.cc
index 6f2f6345..f428e210 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -1434,7 +1434,10 @@ _notmuch_message_gen_terms (notmuch_message_t *message,
term_gen->set_document (message->doc);
if (prefix_name) {
- const char *prefix = _find_prefix (prefix_name);
+ const char *prefix = _maybe_user_prefix (message->notmuch, prefix_name);
+
+ if (prefix == NULL)
+ return NOTMUCH_PRIVATE_STATUS_BAD_PREFIX;
term_gen->set_termpos (message->termpos);
term_gen->index_text (text, 1, prefix);
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 09f828ab..098be4eb 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -136,6 +136,7 @@ typedef enum _notmuch_private_status {
/* Then add our own private values. */
NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND,
+ NOTMUCH_PRIVATE_STATUS_BAD_PREFIX,
NOTMUCH_PRIVATE_STATUS_LAST_STATUS
} notmuch_private_status_t;
@@ -181,6 +182,9 @@ typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
const char *
_find_prefix (const char *name);
+const char *
+_maybe_user_prefix (notmuch_database_t *notmuch, const char *name);
+
char *
_notmuch_message_id_compressed (void *ctx, const char *message_id);
diff --git a/test/T720-user-header.sh b/test/T720-user-header.sh
index ab4d4712..c02861cc 100755
--- a/test/T720-user-header.sh
+++ b/test/T720-user-header.sh
@@ -56,4 +56,21 @@ Query((Tmail AND (XU:LISTnotmuchmail at 1 PHRASE 2 XU:LISTorg at 2)))
EOF
test_expect_equal_file EXPECTED OUTPUT
+test_begin_subtest "index user header"
+notmuch config set index.header.list "List-Id"
+notmuch reindex '*'
+notmuch search --output=files list:notmuch | notmuch_search_files_sanitize | sort > OUTPUT
+cat <<EOF > EXPECTED
+MAIL_DIR/bar/baz/05:2,
+MAIL_DIR/bar/baz/23:2,
+MAIL_DIR/bar/baz/24:2,
+MAIL_DIR/bar/cur/20:2,
+MAIL_DIR/bar/new/21:2,
+MAIL_DIR/bar/new/22:2,
+MAIL_DIR/foo/cur/08:2,
+MAIL_DIR/foo/new/03:2,
+MAIL_DIR/new/04:2,
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_done
--
2.19.1
More information about the notmuch
mailing list