]> git.notmuchmail.org Git - notmuch/blobdiff - lib/message.cc
lib: support user prefix names in term generation
[notmuch] / lib / message.cc
index 6f2f634512453770a358b374ff1e3a3073888d0e..dc4a96ada6380c81cd129237870efa5d403422aa 100644 (file)
@@ -716,6 +716,8 @@ _notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix)
 
 /* Remove all terms generated by indexing, i.e. not tags or
  * properties, along with any automatic tags*/
+/* According to Xapian API docs, none of these calls throw
+ * exceptions */
 notmuch_private_status_t
 _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
 {
@@ -727,45 +729,53 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
        tag_prefix = _find_prefix ("tag"),
        type_prefix = _find_prefix ("type");
 
-    for (i = message->doc.termlist_begin ();
-        i != message->doc.termlist_end (); i++) {
+    /* Make sure we have the data to restore to Xapian*/
+    _notmuch_message_ensure_metadata (message,NULL);
 
-       const std::string term = *i;
+    /* Empirically, it turns out to be faster to remove all the terms,
+     * and add back the ones we want. */
+    message->doc.clear_terms ();
+    message->modified = true;
 
-       if (term.compare (0, type_prefix.size (), type_prefix) == 0)
-           continue;
+    /* still a mail message */
+    message->doc.add_term (type_prefix + "mail");
 
-       if (term.compare (0, id_prefix.size (), id_prefix) == 0)
-           continue;
+    /* Put back message-id */
+    message->doc.add_term (id_prefix + message->message_id);
 
-       if (term.compare (0, property_prefix.size (), property_prefix) == 0)
-           continue;
-
-       if (term.compare (0, tag_prefix.size (), tag_prefix) == 0 &&
-           term.compare (1, strlen("encrypted"), "encrypted") != 0 &&
-           term.compare (1, strlen("signed"), "signed") != 0 &&
-           term.compare (1, strlen("attachment"), "attachment") != 0)
-           continue;
+    /* Put back non-automatic tags */
+    for (notmuch_tags_t *tags = notmuch_message_get_tags (message);
+        notmuch_tags_valid (tags);
+        notmuch_tags_move_to_next (tags)) {
 
-       try {
-           message->doc.remove_term ((*i));
-           message->modified = true;
-       } catch (const Xapian::InvalidArgumentError) {
-           /* Ignore failure to remove non-existent term. */
-       } catch (const Xapian::Error &error) {
-           notmuch_database_t *notmuch = message->notmuch;
+       const char *tag = notmuch_tags_get (tags);
 
-           if (!notmuch->exception_reported) {
-               _notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred creating message: %s\n",
-                                     error.get_msg().c_str());
-               notmuch->exception_reported = true;
-           }
-           return NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
+       if (STRNCMP_LITERAL (tag, "encrypted") != 0 &&
+           STRNCMP_LITERAL (tag, "signed") != 0 &&
+           STRNCMP_LITERAL (tag, "attachment") != 0) {
+           std::string term = tag_prefix + tag;
+           message->doc.add_term(term);
        }
     }
+
+    /* Put back properties */
+    notmuch_message_properties_t *list;
+
+    for (list = notmuch_message_get_properties (message, "", false);
+        notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
+       std::string term = property_prefix +
+           notmuch_message_properties_key(list) + "=" +
+           notmuch_message_properties_value(list);
+
+       message->doc.add_term(term);
+    }
+
+    notmuch_message_properties_destroy (list);
+
     return NOTMUCH_PRIVATE_STATUS_SUCCESS;
 }
 
+
 /* Return true if p points at "new" or "cur". */
 static bool is_maildir (const char *p)
 {
@@ -1419,8 +1429,9 @@ _notmuch_message_add_term (notmuch_message_t *message,
 }
 
 /* Parse 'text' and add a term to 'message' for each parsed word. Each
- * term will be added both prefixed (if prefix_name is not NULL) and
- * also non-prefixed). */
+ * term will be added with the appropriate prefix if prefix_name is
+ * non-NULL.
+ */
 notmuch_private_status_t
 _notmuch_message_gen_terms (notmuch_message_t *message,
                            const char *prefix_name,
@@ -1432,22 +1443,21 @@ _notmuch_message_gen_terms (notmuch_message_t *message,
        return NOTMUCH_PRIVATE_STATUS_NULL_POINTER;
 
     term_gen->set_document (message->doc);
+    term_gen->set_termpos (message->termpos);
 
     if (prefix_name) {
-       const char *prefix = _find_prefix (prefix_name);
-
-       term_gen->set_termpos (message->termpos);
-       term_gen->index_text (text, 1, prefix);
-       /* Create a gap between this an the next terms so they don't
-        * appear to be a phrase. */
-       message->termpos = term_gen->get_termpos () + 100;
+       const char *prefix = _notmuch_database_prefix (message->notmuch, prefix_name);
+       if (prefix == NULL)
+           return NOTMUCH_PRIVATE_STATUS_BAD_PREFIX;
 
        _notmuch_message_invalidate_metadata (message, prefix_name);
+       term_gen->index_text (text, 1, prefix);
+    } else {
+       term_gen->index_text (text);
     }
 
-    term_gen->set_termpos (message->termpos);
-    term_gen->index_text (text);
-    /* Create a term gap, as above. */
+    /* Create a gap between this an the next terms so they don't
+     * appear to be a phrase. */
     message->termpos = term_gen->get_termpos () + 100;
 
     return NOTMUCH_PRIVATE_STATUS_SUCCESS;