notmuch_database_t *notmuch,
const char *thread_id);
+void
+_notmuch_thread_add_tag (notmuch_thread_t *thread, const char *tag);
+
/* message.cc */
notmuch_message_t *
notmuch_query_t *query;
notmuch_thread_results_t *results;
notmuch_thread_t *thread;
+ notmuch_tags_t *tags;
char *query_str;
int i;
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
notmuch_thread_results_has_more (results);
notmuch_thread_results_advance (results))
{
+ int first = 1;
+
thread = notmuch_thread_results_get (results);
- printf ("%s\n", notmuch_thread_get_thread_id (thread));
+ printf ("%s (", notmuch_thread_get_thread_id (thread));
+
+ for (tags = notmuch_thread_get_tags (thread);
+ notmuch_tags_has_more (tags);
+ notmuch_tags_advance (tags))
+ {
+ if (! first)
+ printf (" ");
+ printf ("%s", notmuch_tags_get (tags));
+ first = 0;
+ }
+
+ printf (")\n");
notmuch_thread_destroy (thread);
}
const char *
notmuch_thread_get_thread_id (notmuch_thread_t *thread);
+/* Get the tags for 'thread', returning a notmuch_tags_t object which
+ * can be used to iterate over all tags.
+ *
+ * Note: In the Notmuch database, tags are stored on individual
+ * messages, not on threads. So the tags returned here will be all
+ * tags of the messages which matched the search and which belong to
+ * this thread.
+ *
+ * The tags object is owned by the thread and as such, will only be
+ * valid for as long as the thread is valid, (for example, until
+ * notmuch_thread_destroy or until the query from which it derived is
+ * destroyed).
+ *
+ * Typical usage might be:
+ *
+ * notmuch_thread_t *thread;
+ * notmuch_tags_t *tags;
+ * const char *tag;
+ *
+ * thread = notmuch_thread_results_get (thread_results);
+ *
+ * for (tags = notmuch_thread_get_tags (thread);
+ * notmuch_tags_has_more (tags);
+ * notmuch_result_advance (tags))
+ * {
+ * tag = notmuch_tags_get (tags);
+ * ....
+ * }
+ *
+ * notmuch_thread_destroy (thread);
+ *
+ * Note that there's no explicit destructor needed for the
+ * notmuch_tags_t object. (For consistency, we do provide a
+ * notmuch_tags_destroy function, but there's no good reason to call
+ * it if the message is about to be destroyed).
+ */
+notmuch_tags_t *
+notmuch_thread_get_tags (notmuch_thread_t *thread);
+
/* Destroy a notmuch_thread_t object. */
void
notmuch_thread_destroy (notmuch_thread_t *thread);
struct _notmuch_thread_results {
notmuch_database_t *notmuch;
- GPtrArray *thread_ids;
+ GPtrArray *threads;
unsigned int index;
};
static int
_notmuch_thread_results_destructor (notmuch_thread_results_t *results)
{
- g_ptr_array_free (results->thread_ids, TRUE);
+ g_ptr_array_free (results->threads, TRUE);
return 0;
}
notmuch_query_search_threads (notmuch_query_t *query)
{
notmuch_thread_results_t *thread_results;
+ notmuch_thread_t *thread;
+ const char *thread_id;
notmuch_message_results_t *message_results;
notmuch_message_t *message;
- const char *thread_id;
+ notmuch_tags_t *tags;
+ const char *tag;
GHashTable *seen;
thread_results = talloc (query, notmuch_thread_results_t);
return NULL;
thread_results->notmuch = query->notmuch;
- thread_results->thread_ids = g_ptr_array_new ();
+ thread_results->threads = g_ptr_array_new ();
thread_results->index = 0;
talloc_set_destructor (thread_results, _notmuch_thread_results_destructor);
notmuch_message_results_advance (message_results))
{
message = notmuch_message_results_get (message_results);
+
thread_id = notmuch_message_get_thread_id (message);
- if (g_hash_table_lookup_extended (seen,
- thread_id, NULL, NULL))
+ if (! g_hash_table_lookup_extended (seen,
+ thread_id, NULL,
+ (void **) &thread))
{
- continue;
- }
+ thread = _notmuch_thread_create (query, query->notmuch,
+ thread_id);
+
+ g_hash_table_insert (seen, xstrdup (thread_id), thread);
- g_hash_table_insert (seen, xstrdup (thread_id), NULL);
+ g_ptr_array_add (thread_results->threads, thread);
+ }
- g_ptr_array_add (thread_results->thread_ids,
- talloc_strdup (thread_results, thread_id));
+ for (tags = notmuch_message_get_tags (message);
+ notmuch_tags_has_more (tags);
+ notmuch_tags_advance (tags))
+ {
+ tag = notmuch_tags_get (tags);
+ _notmuch_thread_add_tag (thread, tag);
+ }
}
g_hash_table_unref (seen);
notmuch_bool_t
notmuch_thread_results_has_more (notmuch_thread_results_t *results)
{
- return (results->index < results->thread_ids->len);
+ return (results->index < results->threads->len);
}
notmuch_thread_t *
notmuch_thread_results_get (notmuch_thread_results_t *results)
{
- notmuch_thread_t *thread;
- const char *thread_id;
-
if (! notmuch_thread_results_has_more (results))
return NULL;
- thread_id = (const char *) g_ptr_array_index (results->thread_ids,
- results->index);
-
- thread = _notmuch_thread_create (results,
- results->notmuch,
- thread_id);
-
- return thread;
+ return (notmuch_thread_t *) g_ptr_array_index (results->threads,
+ results->index);
}
void
#include <xapian.h>
+#include <glib.h> /* GHashTable */
+
struct _notmuch_thread {
notmuch_database_t *notmuch;
char *thread_id;
+ GHashTable *tags;
};
+static int
+_notmuch_thread_destructor (notmuch_thread_t *thread)
+{
+ g_hash_table_unref (thread->tags);
+
+ return 0;
+}
+
/* Create a new notmuch_thread_t object for an existing document in
* the database.
*
if (unlikely (thread == NULL))
return NULL;
+ talloc_set_destructor (thread, _notmuch_thread_destructor);
+
thread->notmuch = notmuch;
thread->thread_id = talloc_strdup (thread, thread_id);
+ thread->tags = g_hash_table_new_full (g_str_hash, g_str_equal,
+ free, NULL);
return thread;
}
return thread->thread_id;
}
+void
+_notmuch_thread_add_tag (notmuch_thread_t *thread, const char *tag)
+{
+ g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
+}
+
+notmuch_tags_t *
+notmuch_thread_get_tags (notmuch_thread_t *thread)
+{
+ notmuch_tags_t *tags;
+ GList *keys, *l;
+
+ tags = _notmuch_tags_create (thread);
+ if (unlikely (tags == NULL))
+ return NULL;
+
+ keys = g_hash_table_get_keys (thread->tags);
+
+ for (l = keys; l; l = l->next)
+ _notmuch_tags_add_tag (tags, (char *) l->data);
+
+ g_list_free (keys);
+
+ _notmuch_tags_prepare_iterator (tags);
+
+ return tags;
+}
+
void
notmuch_thread_destroy (notmuch_thread_t *thread)
{