lib: Make notmuch_query_search_messages set the exclude flag

Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by
notmuch_query_search_messages for excluded messages. Also add an
option omit_excluded_messages to the search that we do not want the
excludes at all.

This exclude flag will be added to notmuch_query_search threads in the
next patch.
This commit is contained in:
Mark Walters 2012-03-01 22:30:37 +00:00 committed by David Bremner
parent 08f7b026a9
commit c9eb94d7fb
3 changed files with 62 additions and 6 deletions

View file

@ -401,6 +401,7 @@ typedef struct _notmuch_message_list {
*/ */
struct visible _notmuch_messages { struct visible _notmuch_messages {
notmuch_bool_t is_of_list_type; notmuch_bool_t is_of_list_type;
notmuch_doc_id_set_t *excluded_doc_ids;
notmuch_message_node_t *iterator; notmuch_message_node_t *iterator;
}; };

View file

@ -449,6 +449,13 @@ typedef enum {
const char * const char *
notmuch_query_get_query_string (notmuch_query_t *query); notmuch_query_get_query_string (notmuch_query_t *query);
/* Specify whether to results should omit the excluded results rather
* than just marking them excluded. This is useful for passing a
* notmuch_messages_t not containing the excluded messages to other
* functions. */
void
notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit);
/* Specify the sorting desired for this query. */ /* Specify the sorting desired for this query. */
void void
notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
@ -895,7 +902,8 @@ notmuch_message_get_filenames (notmuch_message_t *message);
/* Message flags */ /* Message flags */
typedef enum _notmuch_message_flag { typedef enum _notmuch_message_flag {
NOTMUCH_MESSAGE_FLAG_MATCH NOTMUCH_MESSAGE_FLAG_MATCH,
NOTMUCH_MESSAGE_FLAG_EXCLUDED
} notmuch_message_flag_t; } notmuch_message_flag_t;
/* Get a value of a flag for the email corresponding to 'message'. */ /* Get a value of a flag for the email corresponding to 'message'. */

View file

@ -28,6 +28,7 @@ struct _notmuch_query {
const char *query_string; const char *query_string;
notmuch_sort_t sort; notmuch_sort_t sort;
notmuch_string_list_t *exclude_terms; notmuch_string_list_t *exclude_terms;
notmuch_bool_t omit_excluded_messages;
}; };
typedef struct _notmuch_mset_messages { typedef struct _notmuch_mset_messages {
@ -57,6 +58,12 @@ struct visible _notmuch_threads {
notmuch_doc_id_set_t match_set; notmuch_doc_id_set_t match_set;
}; };
/* We need this in the message functions so forward declare. */
static notmuch_bool_t
_notmuch_doc_id_set_init (void *ctx,
notmuch_doc_id_set_t *doc_ids,
GArray *arr);
notmuch_query_t * notmuch_query_t *
notmuch_query_create (notmuch_database_t *notmuch, notmuch_query_create (notmuch_database_t *notmuch,
const char *query_string) const char *query_string)
@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
query->exclude_terms = _notmuch_string_list_create (query); query->exclude_terms = _notmuch_string_list_create (query);
query->omit_excluded_messages = FALSE;
return query; return query;
} }
@ -88,6 +97,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
return query->query_string; return query->query_string;
} }
void
notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit)
{
query->omit_excluded_messages = omit;
}
void void
notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort) notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort)
{ {
@ -124,8 +139,9 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
/* Return a query that matches messages with the excluded tags /* Return a query that matches messages with the excluded tags
* registered with query. Any tags that explicitly appear in xquery * registered with query. Any tags that explicitly appear in xquery
* will not be excluded. The caller of this function has to combine * will not be excluded, and will be removed from the list of exclude
* the returned query appropriately.*/ * tags. The caller of this function has to combine the returned
* query appropriately.*/
static Xapian::Query static Xapian::Query
_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
{ {
@ -142,6 +158,8 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
if (it == end) if (it == end)
exclude_query = Xapian::Query (Xapian::Query::OP_OR, exclude_query = Xapian::Query (Xapian::Query::OP_OR,
exclude_query, Xapian::Query (term->string)); exclude_query, Xapian::Query (term->string));
else
term->string = talloc_strdup (query, "");
} }
return exclude_query; return exclude_query;
} }
@ -173,6 +191,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
"mail")); "mail"));
Xapian::Query string_query, final_query, exclude_query; Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset; Xapian::MSet mset;
Xapian::MSetIterator iterator;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_PHRASE |
Xapian::QueryParser::FLAG_LOVEHATE | Xapian::QueryParser::FLAG_LOVEHATE |
@ -190,11 +209,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
final_query = Xapian::Query (Xapian::Query::OP_AND, final_query = Xapian::Query (Xapian::Query::OP_AND,
mail_query, string_query); mail_query, string_query);
} }
messages->base.excluded_doc_ids = NULL;
exclude_query = _notmuch_exclude_tags (query, final_query); if (query->exclude_terms) {
exclude_query = _notmuch_exclude_tags (query, final_query);
exclude_query = Xapian::Query (Xapian::Query::OP_AND,
exclude_query, final_query);
if (query->omit_excluded_messages)
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
final_query, exclude_query);
else {
enquire.set_weighting_scheme (Xapian::BoolWeight());
enquire.set_query (exclude_query);
mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int));
for (iterator = mset.begin (); iterator != mset.end (); iterator++) {
unsigned int doc_id = *iterator;
g_array_append_val (excluded_doc_ids, doc_id);
}
messages->base.excluded_doc_ids = talloc (messages, _notmuch_doc_id_set);
_notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids,
excluded_doc_ids);
g_array_unref (excluded_doc_ids);
}
}
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
final_query, exclude_query);
enquire.set_weighting_scheme (Xapian::BoolWeight()); enquire.set_weighting_scheme (Xapian::BoolWeight());
@ -283,6 +326,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
} }
if (messages->excluded_doc_ids &&
_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))
notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
return message; return message;
} }