lib: Add support for automatically excluding tags from queries

This is useful for tags like "deleted" and "spam" that people
generally want to exclude from query results.  These exclusions will
be overridden if a tag is explicitly mentioned in a query.
This commit is contained in:
Austin Clements 2012-01-14 19:17:33 -05:00 committed by David Bremner
parent 982096d79d
commit 3b76adf9e2
3 changed files with 42 additions and 1 deletions

View file

@ -458,7 +458,7 @@ typedef struct _notmuch_string_node {
struct _notmuch_string_node *next; struct _notmuch_string_node *next;
} notmuch_string_node_t; } notmuch_string_node_t;
typedef struct _notmuch_string_list { typedef struct visible _notmuch_string_list {
int length; int length;
notmuch_string_node_t *head; notmuch_string_node_t *head;
notmuch_string_node_t **tail; notmuch_string_node_t **tail;

View file

@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
notmuch_sort_t notmuch_sort_t
notmuch_query_get_sort (notmuch_query_t *query); notmuch_query_get_sort (notmuch_query_t *query);
/* Add a tag that will be excluded from the query results by default.
* This exclusion will be overridden if this tag appears explicitly in
* the query. */
void
notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag);
/* Execute a query for threads, returning a notmuch_threads_t object /* Execute a query for threads, returning a notmuch_threads_t object
* which can be used to iterate over the results. The returned threads * which can be used to iterate over the results. The returned threads
* object is owned by the query and as such, will only be valid until * object is owned by the query and as such, will only be valid until

View file

@ -27,6 +27,7 @@ struct _notmuch_query {
notmuch_database_t *notmuch; notmuch_database_t *notmuch;
const char *query_string; const char *query_string;
notmuch_sort_t sort; notmuch_sort_t sort;
notmuch_string_list_t *exclude_terms;
}; };
typedef struct _notmuch_mset_messages { typedef struct _notmuch_mset_messages {
@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
query->sort = NOTMUCH_SORT_NEWEST_FIRST; query->sort = NOTMUCH_SORT_NEWEST_FIRST;
query->exclude_terms = _notmuch_string_list_create (query);
return query; return query;
} }
@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query)
return query->sort; return query->sort;
} }
void
notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag)
{
char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
_notmuch_string_list_append (query->exclude_terms, term);
}
/* We end up having to call the destructors explicitly because we had /* We end up having to call the destructors explicitly because we had
* to use "placement new" in order to initialize C++ objects within a * to use "placement new" in order to initialize C++ objects within a
* block that we allocated with talloc. So C++ is making talloc * block that we allocated with talloc. So C++ is making talloc
@ -112,6 +122,27 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
return 0; return 0;
} }
/* Return a query that does not match messages with the excluded tags
* registered with the query. Any tags that explicitly appear in
* xquery will not be excluded. */
static Xapian::Query
_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
{
for (notmuch_string_node_t *term = query->exclude_terms->head; term;
term = term->next) {
Xapian::TermIterator it = xquery.get_terms_begin ();
Xapian::TermIterator end = xquery.get_terms_end ();
for (; it != end; it++) {
if ((*it).compare (term->string) == 0)
break;
}
if (it == end)
xquery = Xapian::Query (Xapian::Query::OP_AND_NOT,
xquery, Xapian::Query (term->string));
}
return xquery;
}
notmuch_messages_t * notmuch_messages_t *
notmuch_query_search_messages (notmuch_query_t *query) notmuch_query_search_messages (notmuch_query_t *query)
{ {
@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query)
mail_query, string_query); mail_query, string_query);
} }
final_query = _notmuch_exclude_tags (query, final_query);
enquire.set_weighting_scheme (Xapian::BoolWeight()); enquire.set_weighting_scheme (Xapian::BoolWeight());
switch (query->sort) { switch (query->sort) {
@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query)
mail_query, string_query); mail_query, string_query);
} }
final_query = _notmuch_exclude_tags (query, final_query);
enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING); enquire.set_docid_order(Xapian::Enquire::ASCENDING);