char *message_id;
char *thread_id;
char *in_reply_to;
+ notmuch_string_list_t *tag_list;
notmuch_string_list_t *filename_term_list;
notmuch_string_list_t *filename_list;
char *author;
message->message_id = NULL;
message->thread_id = NULL;
message->in_reply_to = NULL;
+ message->tag_list = NULL;
message->filename_term_list = NULL;
message->filename_list = NULL;
message->message_file = NULL;
{
Xapian::TermIterator i, end;
const char *thread_prefix = _find_prefix ("thread"),
+ *tag_prefix = _find_prefix ("tag"),
*id_prefix = _find_prefix ("id"),
*filename_prefix = _find_prefix ("file-direntry"),
*replyto_prefix = _find_prefix ("replyto");
message->thread_id =
_notmuch_message_get_term (message, i, end, thread_prefix);
+ /* Get tags */
+ assert (strcmp (thread_prefix, tag_prefix) < 0);
+ if (!message->tag_list) {
+ message->tag_list =
+ _notmuch_database_get_terms_with_prefix (message, i, end,
+ tag_prefix);
+ _notmuch_string_list_sort (message->tag_list);
+ }
+
/* Get id */
- assert (strcmp (thread_prefix, id_prefix) < 0);
+ assert (strcmp (tag_prefix, id_prefix) < 0);
if (!message->message_id)
message->message_id =
_notmuch_message_get_term (message, i, end, id_prefix);
message->thread_id = NULL;
}
+ if (strcmp ("tag", prefix_name) == 0) {
+ talloc_unlink (message, message->tag_list);
+ message->tag_list = NULL;
+ }
+
if (strcmp ("file-direntry", prefix_name) == 0) {
talloc_free (message->filename_term_list);
talloc_free (message->filename_list);
notmuch_tags_t *
notmuch_message_get_tags (notmuch_message_t *message)
{
- Xapian::TermIterator i, end;
- notmuch_string_list_t *tags;
- i = message->doc.termlist_begin();
- end = message->doc.termlist_end();
- tags = _notmuch_database_get_terms_with_prefix (message, i, end,
- _find_prefix ("tag"));
- _notmuch_string_list_sort (tags);
- return _notmuch_tags_create (message, tags);
+ notmuch_tags_t *tags;
+
+ if (!message->tag_list)
+ _notmuch_message_ensure_metadata (message);
+
+ tags = _notmuch_tags_create (message, message->tag_list);
+ /* _notmuch_tags_create steals the reference to the tag_list, but
+ * in this case it's still used by the message, so we add an
+ * *additional* talloc reference to the list. As a result, it's
+ * possible to modify the message tags (which talloc_unlink's the
+ * current list from the message) while still iterating because
+ * the iterator will keep the current list alive. */
+ talloc_reference (message, message->tag_list);
+ return tags;
}
const char *
if (! message->frozen)
_notmuch_message_sync (message);
+ talloc_free (tags);
return NOTMUCH_STATUS_SUCCESS;
}