[PATCH v3 1/2] lib: Add support for automatically excluding tags from queries

2012-01-14 Thread Austin Clements
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.
---
 lib/notmuch-private.h |2 +-
 lib/notmuch.h |6 ++
 lib/query.cc  |   35 +++
 3 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 60a932f..7bf153e 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -458,7 +458,7 @@ typedef struct _notmuch_string_node {
 struct _notmuch_string_node *next;
 } notmuch_string_node_t;

-typedef struct _notmuch_string_list {
+typedef struct visible _notmuch_string_list {
 int length;
 notmuch_string_node_t *head;
 notmuch_string_node_t **tail;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 9f23a10..7929fe7 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, 
notmuch_sort_t sort);
 notmuch_sort_t
 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
  * 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
diff --git a/lib/query.cc b/lib/query.cc
index b6c0f12..0b36602 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -27,6 +27,7 @@ struct _notmuch_query {
 notmuch_database_t *notmuch;
 const char *query_string;
 notmuch_sort_t sort;
+notmuch_string_list_t *exclude_terms;
 };

 typedef struct _notmuch_mset_messages {
@@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch,

 query->sort = NOTMUCH_SORT_NEWEST_FIRST;

+query->exclude_terms = _notmuch_string_list_create (query);
+
 return query;
 }

@@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query)
 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
  * to use "placement new" in order to initialize C++ objects within a
  * 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 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_query_search_messages (notmuch_query_t *query)
 {
@@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query)
 mail_query, string_query);
}

+   final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme (Xapian::BoolWeight());

switch (query->sort) {
@@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query)
 mail_query, string_query);
}

+   final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);

-- 
1.7.7.3



[PATCH v3 1/2] lib: Add support for automatically excluding tags from queries

2012-01-14 Thread Austin Clements
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.
---
 lib/notmuch-private.h |2 +-
 lib/notmuch.h |6 ++
 lib/query.cc  |   35 +++
 3 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 60a932f..7bf153e 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -458,7 +458,7 @@ typedef struct _notmuch_string_node {
 struct _notmuch_string_node *next;
 } notmuch_string_node_t;
 
-typedef struct _notmuch_string_list {
+typedef struct visible _notmuch_string_list {
 int length;
 notmuch_string_node_t *head;
 notmuch_string_node_t **tail;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 9f23a10..7929fe7 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, 
notmuch_sort_t sort);
 notmuch_sort_t
 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
  * 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
diff --git a/lib/query.cc b/lib/query.cc
index b6c0f12..0b36602 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -27,6 +27,7 @@ struct _notmuch_query {
 notmuch_database_t *notmuch;
 const char *query_string;
 notmuch_sort_t sort;
+notmuch_string_list_t *exclude_terms;
 };
 
 typedef struct _notmuch_mset_messages {
@@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
 
 query-sort = NOTMUCH_SORT_NEWEST_FIRST;
 
+query-exclude_terms = _notmuch_string_list_create (query);
+
 return query;
 }
 
@@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query)
 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
  * to use placement new in order to initialize C++ objects within a
  * 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 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_query_search_messages (notmuch_query_t *query)
 {
@@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query)
 mail_query, string_query);
}
 
+   final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme (Xapian::BoolWeight());
 
switch (query-sort) {
@@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query)
 mail_query, string_query);
}
 
+   final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
 
-- 
1.7.7.3

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