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.
---
 lib/notmuch-private.h |    1 +
 lib/notmuch.h         |   10 ++++++++-
 lib/query.cc          |   52 +++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 7bf153e..e791bb0 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 7929fe7..f75afae 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 c25b301..90a71a1 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;
@@ -173,6 +188,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 +206,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 (query, 
_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 +323,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;
 }
 
-- 
1.7.2.3

_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to