]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database.cc
Merge branch 'release'
[notmuch] / lib / database.cc
index ba440d4db87e4608b043167860cc09e911f4aeda..a679cbabbac95a2d39885292341370e1d040d8c0 100644 (file)
@@ -21,6 +21,7 @@
 #include "database-private.h"
 #include "parse-time-vrp.h"
 #include "query-fp.h"
+#include "regexp-fields.h"
 #include "string-util.h"
 
 #include <iostream>
@@ -261,6 +262,7 @@ prefix_t prefix_table[] = {
     { "tag",                   "K",            NOTMUCH_FIELD_EXTERNAL },
     { "is",                    "K",            NOTMUCH_FIELD_EXTERNAL },
     { "id",                    "Q",            NOTMUCH_FIELD_EXTERNAL },
+    { "mid",                   "Q",            NOTMUCH_FIELD_EXTERNAL },
     { "path",                  "P",            NOTMUCH_FIELD_EXTERNAL },
     { "property",              "XPROPERTY",    NOTMUCH_FIELD_EXTERNAL },
     /*
@@ -270,8 +272,15 @@ prefix_t prefix_table[] = {
      * discussion.
      */
     { "folder",                        "XFOLDER:",     NOTMUCH_FIELD_EXTERNAL },
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+    { "date",                  NULL,           NOTMUCH_FIELD_EXTERNAL |
+                                               NOTMUCH_FIELD_PROCESSOR },
+    { "query",                 NULL,           NOTMUCH_FIELD_EXTERNAL |
+                                               NOTMUCH_FIELD_PROCESSOR },
+#endif
     { "from",                  "XFROM",        NOTMUCH_FIELD_EXTERNAL |
-                                               NOTMUCH_FIELD_PROBABILISTIC },
+                                               NOTMUCH_FIELD_PROBABILISTIC |
+                                               NOTMUCH_FIELD_PROCESSOR },
     { "to",                    "XTO",          NOTMUCH_FIELD_EXTERNAL |
                                                NOTMUCH_FIELD_PROBABILISTIC },
     { "attachment",            "XATTACHMENT",  NOTMUCH_FIELD_EXTERNAL |
@@ -279,9 +288,47 @@ prefix_t prefix_table[] = {
     { "mimetype",              "XMIMETYPE",    NOTMUCH_FIELD_EXTERNAL |
                                                NOTMUCH_FIELD_PROBABILISTIC },
     { "subject",               "XSUBJECT",     NOTMUCH_FIELD_EXTERNAL |
-                                               NOTMUCH_FIELD_PROBABILISTIC },
+                                               NOTMUCH_FIELD_PROBABILISTIC |
+                                               NOTMUCH_FIELD_PROCESSOR},
 };
 
+static void
+_setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch)
+{
+    if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC)
+       notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
+    else
+       notmuch->query_parser->add_boolean_prefix (prefix->name, prefix->prefix);
+}
+
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+static void
+_setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch)
+{
+    if (prefix->flags & NOTMUCH_FIELD_PROCESSOR) {
+       Xapian::FieldProcessor *fp;
+
+       if (STRNCMP_LITERAL (prefix->name, "date") == 0)
+           fp = (new DateFieldProcessor())->release ();
+       else if (STRNCMP_LITERAL(prefix->name, "query") == 0)
+           fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release ();
+       else
+           fp = (new RegexpFieldProcessor (prefix->name, *notmuch->query_parser, notmuch))->release ();
+
+       /* we treat all field-processor fields as boolean in order to get the raw input */
+       notmuch->query_parser->add_boolean_prefix (prefix->name, fp);
+    } else {
+       _setup_query_field_default (prefix, notmuch);
+    }
+}
+#else
+static inline void
+_setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch)
+{
+    _setup_query_field_default (prefix, notmuch);
+}
+#endif
+
 const char *
 _find_prefix (const char *name)
 {
@@ -1028,18 +1075,6 @@ notmuch_database_open_verbose (const char *path,
        notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
        notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
        notmuch->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
-#if HAVE_XAPIAN_FIELD_PROCESSOR
-       /* This currently relies on the query parser to pass anything
-        * with a .. to the range processor */
-       {
-           Xapian::FieldProcessor * date_fp = new DateFieldProcessor();
-           Xapian::FieldProcessor * query_fp =
-               new QueryFieldProcessor (*notmuch->query_parser, notmuch);
-
-           notmuch->query_parser->add_boolean_prefix("date", date_fp->release ());
-           notmuch->query_parser->add_boolean_prefix("query", query_fp->release ());
-       }
-#endif
        notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:");
 
        notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
@@ -1053,12 +1088,7 @@ notmuch_database_open_verbose (const char *path,
        for (i = 0; i < ARRAY_SIZE (prefix_table); i++) {
            const prefix_t *prefix = &prefix_table[i];
            if (prefix->flags & NOTMUCH_FIELD_EXTERNAL) {
-               if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC) {
-                   notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
-               } else {
-                   notmuch->query_parser->add_boolean_prefix (prefix->name,
-                                                              prefix->prefix);
-               }
+               _setup_query_field (prefix, notmuch);
            }
        }
     } catch (const Xapian::Error &error) {
@@ -2463,53 +2493,53 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     if (ret)
        goto DONE;
 
-    try {
-       /* Before we do any real work, (especially before doing a
-        * potential SHA-1 computation on the entire file's contents),
-        * let's make sure that what we're looking at looks like an
-        * actual email message.
-        */
-       from = _notmuch_message_file_get_header (message_file, "from");
-       subject = _notmuch_message_file_get_header (message_file, "subject");
-       to = _notmuch_message_file_get_header (message_file, "to");
+    /* Before we do any real work, (especially before doing a
+     * potential SHA-1 computation on the entire file's contents),
+     * let's make sure that what we're looking at looks like an
+     * actual email message.
+     */
+    from = _notmuch_message_file_get_header (message_file, "from");
+    subject = _notmuch_message_file_get_header (message_file, "subject");
+    to = _notmuch_message_file_get_header (message_file, "to");
+
+    if ((from == NULL || *from == '\0') &&
+       (subject == NULL || *subject == '\0') &&
+       (to == NULL || *to == '\0')) {
+       ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
+       goto DONE;
+    }
 
-       if ((from == NULL || *from == '\0') &&
-           (subject == NULL || *subject == '\0') &&
-           (to == NULL || *to == '\0'))
-       {
-           ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
-           goto DONE;
-       }
+    /* Now that we're sure it's mail, the first order of business
+     * is to find a message ID (or else create one ourselves).
+     */
+    header = _notmuch_message_file_get_header (message_file, "message-id");
+    if (header && *header != '\0') {
+       message_id = _parse_message_id (message_file, header, NULL);
 
-       /* Now that we're sure it's mail, the first order of business
-        * is to find a message ID (or else create one ourselves). */
+       /* So the header value isn't RFC-compliant, but it's
+        * better than no message-id at all.
+        */
+       if (message_id == NULL)
+           message_id = talloc_strdup (message_file, header);
+    }
 
-       header = _notmuch_message_file_get_header (message_file, "message-id");
-       if (header && *header != '\0') {
-           message_id = _parse_message_id (message_file, header, NULL);
+    if (message_id == NULL ) {
+       /* No message-id at all, let's generate one by taking a
+        * hash over the file's contents.
+        */
+       char *sha1 = _notmuch_sha1_of_file (filename);
 
-           /* So the header value isn't RFC-compliant, but it's
-            * better than no message-id at all. */
-           if (message_id == NULL)
-               message_id = talloc_strdup (message_file, header);
+       /* If that failed too, something is really wrong. Give up. */
+       if (sha1 == NULL) {
+           ret = NOTMUCH_STATUS_FILE_ERROR;
+           goto DONE;
        }
 
-       if (message_id == NULL ) {
-           /* No message-id at all, let's generate one by taking a
-            * hash over the file's contents. */
-           char *sha1 = _notmuch_sha1_of_file (filename);
-
-           /* If that failed too, something is really wrong. Give up. */
-           if (sha1 == NULL) {
-               ret = NOTMUCH_STATUS_FILE_ERROR;
-               goto DONE;
-           }
-
-           message_id = talloc_asprintf (message_file,
-                                         "notmuch-sha1-%s", sha1);
-           free (sha1);
-       }
+       message_id = talloc_asprintf (message_file, "notmuch-sha1-%s", sha1);
+       free (sha1);
+    }
 
+    try {
        /* Now that we have a message ID, we get a message object,
         * (which may or may not reference an existing document in the
         * database). */