aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorGravatar Mark Walters <markwalters1009@gmail.com>2012-03-01 22:30:37 +0000
committerGravatar David Bremner <bremner@debian.org>2012-03-02 08:27:47 -0400
commitc9eb94d7fb520612374870dda9b9058a85c9b03d (patch)
tree1164a80d3d9f978c79d7c4779519ad02b766f007 /lib
parent08f7b026a9f8a32fbe14eb73b99a026544b22900 (diff)
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/notmuch-private.h1
-rw-r--r--lib/notmuch.h10
-rw-r--r--lib/query.cc59
3 files changed, 63 insertions, 7 deletions
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e0..e791bb02 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -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;
};
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7929fe72..f75afaeb 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -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'. */
diff --git a/lib/query.cc b/lib/query.cc
index c25b301d..ef2a11f8 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -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;
}
@@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query)
}
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)
{
query->sort = 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;
+
+ 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);
+ }
+ }
- exclude_query = _notmuch_exclude_tags (query, final_query);
-
- 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;
}