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 {
notmuch_bool_t is_of_list_type;
notmuch_doc_id_set_t *excluded_doc_ids;
notmuch_message_node_t *iterator;
};

View file

@ -449,6 +449,13 @@ typedef enum {
const char *
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. */
void
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 */
typedef enum _notmuch_message_flag {
NOTMUCH_MESSAGE_FLAG_MATCH
NOTMUCH_MESSAGE_FLAG_MATCH,
NOTMUCH_MESSAGE_FLAG_EXCLUDED
} notmuch_message_flag_t;
/* 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;
notmuch_sort_t sort;
notmuch_string_list_t *exclude_terms;
notmuch_bool_t omit_excluded_messages;
};
typedef struct _notmuch_mset_messages {
@ -57,6 +58,12 @@ struct visible _notmuch_threads {
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_create (notmuch_database_t *notmuch,
const char *query_string)
@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
query->exclude_terms = _notmuch_string_list_create (query);
query->omit_excluded_messages = FALSE;
return query;
}
@ -88,6 +97,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
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
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
* registered with query. Any tags that explicitly appear in xquery
* will not be excluded. The caller of this function has to combine
* the returned query appropriately.*/
* will not be excluded, and will be removed from the list of exclude
* tags. The caller of this function has to combine the returned
* query appropriately.*/
static Xapian::Query
_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)
exclude_query = Xapian::Query (Xapian::Query::OP_OR,
exclude_query, Xapian::Query (term->string));
else
term->string = talloc_strdup (query, "");
}
return exclude_query;
}
@ -173,6 +191,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
"mail"));
Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
Xapian::MSetIterator iterator;
unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
Xapian::QueryParser::FLAG_PHRASE |
Xapian::QueryParser::FLAG_LOVEHATE |
@ -190,11 +209,35 @@ notmuch_query_search_messages (notmuch_query_t *query)
final_query = Xapian::Query (Xapian::Query::OP_AND,
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());
@ -283,6 +326,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
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;
}