--- lib/notmuch.h | 12 ++++++++++++ lib/query.cc | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index babd208..22dd69e 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -445,6 +445,18 @@ typedef enum { NOTMUCH_SORT_UNSORTED } notmuch_sort_t; +/* Values for notmuch_query_secondary_search_conjunction */ +typedef enum { + NOTMUCH_SECONDARY_SEARCH_NONE, + NOTMUCH_SECONDARY_SEARCH_AND, + NOTMUCH_SECONDARY_SEARCH_AND_NOT +} notmuch_ss_conjunction_t; + +void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction); + /* Return the query_string of this query. See notmuch_query_create. */ const char * notmuch_query_get_query_string (notmuch_query_t *query); diff --git a/lib/query.cc b/lib/query.cc index 68ac1e4..0faef51 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -26,6 +26,8 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; + const char *secondary_search_terms; + notmuch_ss_conjunction_t ss_conjunction; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; notmuch_bool_t omit_excluded_messages; @@ -92,6 +94,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->exclude_terms = _notmuch_string_list_create (query); + query->secondary_search_terms = NULL; + query->omit_excluded_messages = FALSE; return query; @@ -122,6 +126,15 @@ notmuch_query_get_sort (notmuch_query_t *query) } void +notmuch_query_set_secondary_search (notmuch_query_t *query, + const char *secondary_search_terms, + notmuch_ss_conjunction_t conjunction) +{ + query->secondary_search_terms = talloc_strdup (query, secondary_search_terms); + query->ss_conjunction = conjunction; +} + +void notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) { char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); @@ -454,6 +467,36 @@ notmuch_query_destroy (notmuch_query_t *query) talloc_free (query); } +/* This function tests whether the thread containing document with id + * seed_doc_id satisfies the secondary search terms of query.*/ +notmuch_bool_t +notmuch_thread_test_secondary_search (notmuch_query_t *query, unsigned int seed_doc_id) +{ + int count; + notmuch_message_t *seed_message; + const char *thread_id; + char *thread_id_query_string; + notmuch_query_t *thread_id_query; + + if (!query->secondary_search_terms) return TRUE; + seed_message = _notmuch_message_create (query, query->notmuch, seed_doc_id, NULL); + + thread_id = notmuch_message_get_thread_id (seed_message); + thread_id_query_string = talloc_asprintf (query, "thread:%s and %s", + thread_id, + query->secondary_search_terms); + thread_id_query = notmuch_query_create (query->notmuch, thread_id_query_string); + count = notmuch_query_count_messages (thread_id_query); + switch (query->ss_conjunction) { + case NOTMUCH_SECONDARY_SEARCH_AND: + return (count > 0); + case NOTMUCH_SECONDARY_SEARCH_AND_NOT: + return (count == 0); + default: + return TRUE; + } +} + notmuch_bool_t notmuch_threads_valid (notmuch_threads_t *threads) { @@ -462,7 +505,8 @@ notmuch_threads_valid (notmuch_threads_t *threads) while (threads->doc_id_pos < threads->doc_ids->len) { doc_id = g_array_index (threads->doc_ids, unsigned int, threads->doc_id_pos); - if (_notmuch_doc_id_set_contains (&threads->match_set, doc_id)) + if (_notmuch_doc_id_set_contains (&threads->match_set, doc_id) && + notmuch_thread_test_secondary_search (threads->query, doc_id)) break; threads->doc_id_pos++; -- 1.7.9.1