--- lib/notmuch.h | 13 +++++++++++++ lib/query.cc | 35 +++++++++++++++++++++++++++++++++++ notmuch-search.c | 24 ++++-------------------- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 2faa146..927ea3c 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -927,6 +927,19 @@ notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query); /** + * Execute a query for tags, outputing a notmuch_tags_t object + * which can be used to iterate over the results. The output + * tags object is owned by the query and as such, will only be + * valid until notmuch_query_destroy. + * + * @param[in] query the query to collect tags for + * @param[out] out the return tags list + * + */ +notmuch_status_t +notmuch_query_search_tags (notmuch_query_t *query, notmuch_tags_t **out); + +/** * Destroy a notmuch_query_t along with any associated resources. * * This will in turn destroy any notmuch_threads_t and diff --git a/lib/query.cc b/lib/query.cc index 7eb73a1..7245b12 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -310,6 +310,41 @@ _notmuch_query_search_documents (notmuch_query_t *query, } } +notmuch_status_t +notmuch_query_search_tags (notmuch_query_t *query, notmuch_tags_t **tags) +{ + notmuch_messages_t *messages = NULL; + notmuch_database_t *notmuch = notmuch_query_get_database (query); + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; + const char *query_string = notmuch_query_get_query_string (query); + + if (tags == NULL) + return NOTMUCH_STATUS_NULL_POINTER; + + /* Special-case query of "*" or '' for better performance. */ + if (strcmp (query_string, "*") == 0 || *query_string == '\0') { + *tags = notmuch_database_get_all_tags (notmuch); + if (*tags == NULL) + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + } else { + notmuch_status_t status; + status = notmuch_query_search_messages_st (query, &messages); + if (status) + goto DONE; + + *tags = notmuch_messages_collect_tags (messages); + talloc_steal (query, *tags); + if (*tags == NULL) + status = NOTMUCH_STATUS_OUT_OF_MEMORY; + } + + DONE: + if (messages) + notmuch_messages_destroy (messages); + + return status; +} + notmuch_bool_t _notmuch_mset_messages_valid (notmuch_messages_t *messages) { diff --git a/notmuch-search.c b/notmuch-search.c index 8c65d5a..8722735 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -611,31 +611,18 @@ do_search_messages (search_context_t *ctx) return 0; } + static int do_search_tags (const search_context_t *ctx) { - notmuch_messages_t *messages = NULL; notmuch_tags_t *tags; const char *tag; sprinter_t *format = ctx->format; notmuch_query_t *query = ctx->query; - notmuch_database_t *notmuch = ctx->notmuch; - - /* should the following only special case if no excluded terms - * specified? */ - - /* Special-case query of "*" for better performance. */ - if (strcmp (notmuch_query_get_query_string (query), "*") == 0) { - tags = notmuch_database_get_all_tags (notmuch); - } else { - notmuch_status_t status; - status = notmuch_query_search_messages_st (query, &messages); - if (print_status_query ("notmuch search", query, status)) - return 1; - tags = notmuch_messages_collect_tags (messages); - } - if (tags == NULL) + if (print_status_query ("notmuch search", + query, + notmuch_query_search_tags (query, &tags))) return 1; format->begin_list (format); @@ -653,9 +640,6 @@ do_search_tags (const search_context_t *ctx) notmuch_tags_destroy (tags); - if (messages) - notmuch_messages_destroy (messages); - format->end (format); return 0; -- 2.8.1