]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database-private.h
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / lib / database-private.h
index 1a78b60ee52633339737bb093e05f67d564fb72d..61232f1ae3ffcc51bb0dd6b96c91e1b9296e33d3 100644 (file)
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ * along with this program.  If not, see https://www.gnu.org/licenses/ .
  *
  * Author: Carl Worth <cworth@cworth.org>
  */
 
 #include "notmuch-private.h"
 
+#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+
+#ifdef SILENCE_XAPIAN_DEPRECATION_WARNINGS
+#define XAPIAN_DEPRECATED(D) D
+#endif
+
 #include <xapian.h>
 
-#pragma GCC visibility push(hidden)
+#if HAVE_SFSEXP
+#include <sexp.h>
+#endif
 
 /* Bit masks for _notmuch_database::features.  Features are named,
  * independent aspects of the database schema.
@@ -60,7 +68,7 @@ enum _notmuch_features {
      * unset, file names are stored in document data.
      *
      * Introduced: version 1. */
-    NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
+    NOTMUCH_FEATURE_FILE_TERMS                 = 1 << 0,
 
     /* If set, directory timestamps are stored in documents with
      * XDIRECTORY terms and relative paths.  If unset, directory
@@ -68,7 +76,7 @@ enum _notmuch_features {
      * absolute paths.
      *
      * Introduced: version 1. */
-    NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
+    NOTMUCH_FEATURE_DIRECTORY_DOCS             = 1 << 1,
 
     /* If set, the from, subject, and message-id headers are stored in
      * message document values.  If unset, message documents *may*
@@ -77,21 +85,21 @@ enum _notmuch_features {
      *
      * Introduced: optional in version 1, required as of version 3.
      */
-    NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
+    NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES     = 1 << 2,
 
     /* If set, folder terms are boolean and path terms exist.  If
      * unset, folder terms are probabilistic and stemmed and path
      * terms do not exist.
      *
      * Introduced: version 2. */
-    NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
+    NOTMUCH_FEATURE_BOOL_FOLDER                        = 1 << 3,
 
     /* If set, missing messages are stored in ghost mail documents.
      * If unset, thread IDs of ghost messages are stored as database
      * metadata instead of in ghost documents.
      *
      * Introduced: version 3. */
-    NOTMUCH_FEATURE_GHOSTS = 1 << 4,
+    NOTMUCH_FEATURE_GHOSTS                     = 1 << 4,
 
 
     /* If set, then the database was created after the introduction of
@@ -99,51 +107,83 @@ enum _notmuch_features {
      * mixture of messages with indexed and non-indexed mime types.
      *
      * Introduced: version 3. */
-    NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
+    NOTMUCH_FEATURE_INDEXED_MIMETYPES          = 1 << 5,
 
     /* If set, messages store the revision number of the last
      * modification in NOTMUCH_VALUE_LAST_MOD.
      *
      * Introduced: version 3. */
-    NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
+    NOTMUCH_FEATURE_LAST_MOD                   = 1 << 6,
+
+    /* If set, unprefixed terms are stored only for the message body,
+     * not for headers.
+     *
+     * Introduced: version 3. */
+    NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY         = 1 << 7,
 };
 
 /* In C++, a named enum is its own type, so define bitwise operators
  * on _notmuch_features. */
 inline _notmuch_features
-operator|(_notmuch_features a, _notmuch_features b)
+operator| (_notmuch_features a, _notmuch_features b)
 {
     return static_cast<_notmuch_features>(
        static_cast<unsigned>(a) | static_cast<unsigned>(b));
 }
 
 inline _notmuch_features
-operator&(_notmuch_features a, _notmuch_features b)
+operator& (_notmuch_features a, _notmuch_features b)
 {
     return static_cast<_notmuch_features>(
        static_cast<unsigned>(a) & static_cast<unsigned>(b));
 }
 
 inline _notmuch_features
-operator~(_notmuch_features a)
+operator~ (_notmuch_features a)
 {
     return static_cast<_notmuch_features>(~static_cast<unsigned>(a));
 }
 
 inline _notmuch_features&
-operator|=(_notmuch_features &a, _notmuch_features b)
+operator|= (_notmuch_features &a, _notmuch_features b)
 {
     a = a | b;
     return a;
 }
 
 inline _notmuch_features&
-operator&=(_notmuch_features &a, _notmuch_features b)
+operator&= (_notmuch_features &a, _notmuch_features b)
 {
     a = a & b;
     return a;
 }
 
+/*
+ * Configuration options for xapian database fields */
+typedef enum {
+    NOTMUCH_FIELD_NO_FLAGS     = 0,
+    NOTMUCH_FIELD_EXTERNAL     = 1 << 0,
+    NOTMUCH_FIELD_PROBABILISTIC = 1 << 1,
+    NOTMUCH_FIELD_PROCESSOR    = 1 << 2,
+    NOTMUCH_FIELD_STRIP_TRAILING_SLASH = 1 << 3,
+} notmuch_field_flag_t;
+
+/*
+ * define bitwise operators to hide casts */
+inline notmuch_field_flag_t
+operator| (notmuch_field_flag_t a, notmuch_field_flag_t b)
+{
+    return static_cast<notmuch_field_flag_t>(
+       static_cast<unsigned>(a) | static_cast<unsigned>(b));
+}
+
+inline notmuch_field_flag_t
+operator& (notmuch_field_flag_t a, notmuch_field_flag_t b)
+{
+    return static_cast<notmuch_field_flag_t>(
+       static_cast<unsigned>(a) & static_cast<unsigned>(b));
+}
+
 #define NOTMUCH_QUERY_PARSER_FLAGS (Xapian::QueryParser::FLAG_BOOLEAN | \
                                    Xapian::QueryParser::FLAG_PHRASE | \
                                    Xapian::QueryParser::FLAG_LOVEHATE | \
@@ -151,24 +191,75 @@ operator&=(_notmuch_features &a, _notmuch_features b)
                                    Xapian::QueryParser::FLAG_WILDCARD | \
                                    Xapian::QueryParser::FLAG_PURE_NOT)
 
+/*
+ * explicit and implied parameters to open */
+typedef enum {
+    NOTMUCH_PARAM_NONE         = 0,
+    /* database passed explicitely */
+    NOTMUCH_PARAM_DATABASE     = 1 << 0,
+    /* config file passed explicitely */
+    NOTMUCH_PARAM_CONFIG       = 1 << 1,
+    /* profile name passed explicitely */
+    NOTMUCH_PARAM_PROFILE      = 1 << 2,
+    /* split (e.g. XDG) configuration */
+    NOTMUCH_PARAM_SPLIT                = 1 << 3,
+} notmuch_open_param_t;
+
+/*
+ * define bitwise operators to hide casts */
+
+inline notmuch_open_param_t
+operator| (notmuch_open_param_t a, notmuch_open_param_t b)
+{
+    return static_cast<notmuch_open_param_t>(
+       static_cast<unsigned>(a) | static_cast<unsigned>(b));
+}
+
+inline notmuch_open_param_t&
+operator|= (notmuch_open_param_t &a, notmuch_open_param_t b)
+{
+    a = a | b;
+    return a;
+}
+
+inline notmuch_open_param_t
+operator& (notmuch_open_param_t a, notmuch_open_param_t b)
+{
+    return static_cast<notmuch_open_param_t>(
+       static_cast<unsigned>(a) & static_cast<unsigned>(b));
+}
+
 struct _notmuch_database {
-    notmuch_bool_t exception_reported;
+    bool exception_reported;
+
+    /* Path to actual database */
+    const char *xapian_path;
 
-    char *path;
+    /* Path to config loaded, if any */
+    const char *config_path;
 
-    notmuch_database_mode_t mode;
     int atomic_nesting;
-    /* TRUE if changes have been made in this atomic section */
-    notmuch_bool_t atomic_dirty;
+    /* true if changes have been made in this atomic section */
+    bool atomic_dirty;
     Xapian::Database *xapian_db;
-
+    Xapian::WritableDatabase *writable_xapian_db;
+    bool open;
     /* Bit mask of features used by this database.  This is a
      * bitwise-OR of NOTMUCH_FEATURE_* values (above). */
     enum _notmuch_features features;
 
     unsigned int last_doc_id;
+
+    /* 16 bytes (+ terminator) for hexadecimal representation of
+     * a 64-bit integer. */
+    char thread_id_str[17];
     uint64_t last_thread_id;
 
+    /* How many transactions have successfully completed since we last committed */
+    int transaction_count;
+    /* when to commit and reset the counter */
+    int transaction_threshold;
+
     /* error reporting; this value persists only until the
      * next library call. May be NULL */
     char *status_string;
@@ -179,20 +270,36 @@ struct _notmuch_database {
     unsigned long revision;
     const char *uuid;
 
+    /* Keep track of the number of times the database has been re-opened
+     * (or other global invalidations of notmuch's caching)
+     */
+    unsigned long view;
     Xapian::QueryParser *query_parser;
+    Xapian::Stem *stemmer;
     Xapian::TermGenerator *term_gen;
-    Xapian::ValueRangeProcessor *value_range_processor;
-    Xapian::ValueRangeProcessor *date_range_processor;
-#if HAVE_XAPIAN_FIELD_PROCESSOR
-    Xapian::FieldProcessor *date_field_processor;
-    Xapian::FieldProcessor *query_field_processor;
-#endif
-    Xapian::ValueRangeProcessor *last_mod_range_processor;
+    Xapian::RangeProcessor *value_range_processor;
+    Xapian::RangeProcessor *date_range_processor;
+    Xapian::RangeProcessor *last_mod_range_processor;
+
+    /* XXX it's slightly gross to use two parallel string->string maps
+     * here, but at least they are small */
+    notmuch_string_map_t *user_prefix;
+    notmuch_string_map_t *user_header;
+
+    /* Cached and possibly overridden configuration */
+    notmuch_string_map_t *config;
+
+    /* Track what parameters were specified when opening */
+    notmuch_open_param_t params;
+
+    /* list of regular expressions to check for text indexing */
+    regex_t *index_as_text;
+    size_t index_as_text_length;
 };
 
 /* Prior to database version 3, features were implied by the database
  * version number, so hard-code them for earlier versions. */
-#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features)0)
+#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features) 0)
 #define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \
                             NOTMUCH_FEATURE_DIRECTORY_DOCS)
 #define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)
@@ -219,6 +326,70 @@ _notmuch_database_get_terms_with_prefix (void *ctx, Xapian::TermIterator &i,
                                         Xapian::TermIterator &end,
                                         const char *prefix);
 
-#pragma GCC visibility pop
+void
+_notmuch_database_find_doc_ids (notmuch_database_t *notmuch,
+                               const char *prefix_name,
+                               const char *value,
+                               Xapian::PostingIterator *begin,
+                               Xapian::PostingIterator *end);
+
+#define NOTMUCH_DATABASE_VERSION 3
+
+/* features.cc */
+
+_notmuch_features
+_notmuch_database_parse_features (const void *ctx, const char *features, unsigned int version,
+                                 char mode, char **incompat_out);
+
+char *
+_notmuch_database_print_features (const void *ctx, unsigned int features);
+
+/* prefix.cc */
+notmuch_status_t
+_notmuch_database_setup_standard_query_fields (notmuch_database_t *notmuch);
+
+notmuch_status_t
+_notmuch_database_setup_user_query_fields (notmuch_database_t *notmuch);
+
+#if __cplusplus
+/* query.cc */
+notmuch_status_t
+_notmuch_query_string_to_xapian_query (notmuch_database_t *notmuch,
+                                      std::string query_string,
+                                      Xapian::Query &output,
+                                      std::string &msg);
+
+notmuch_status_t
+_notmuch_query_expand (notmuch_database_t *notmuch, const char *field, Xapian::Query subquery,
+                      Xapian::Query &output, std::string &msg);
+
+/* regexp-fields.cc */
+notmuch_status_t
+_notmuch_regexp_to_query (notmuch_database_t *notmuch, Xapian::valueno slot, std::string field,
+                         std::string regexp_str,
+                         Xapian::Query &output, std::string &msg);
+
+/* thread-fp.cc */
+notmuch_status_t
+_notmuch_query_name_to_query (notmuch_database_t *notmuch, const std::string name,
+                             Xapian::Query &output);
+
+#if HAVE_SFSEXP
+/* parse-sexp.cc */
+notmuch_status_t
+_notmuch_sexp_string_to_xapian_query (notmuch_database_t *notmuch, const char *querystr,
+                                     Xapian::Query &output);
+#endif
 
+/* parse-time-vrp.h */
+notmuch_status_t
+_notmuch_date_strings_to_query (Xapian::valueno slot, const std::string &from, const std::string &to,
+                               Xapian::Query &output, std::string &msg);
+
+/* lastmod-fp.h */
+notmuch_status_t
+_notmuch_lastmod_strings_to_query (notmuch_database_t *notmuch,
+                                  const std::string &from, const std::string &to,
+                                  Xapian::Query &output, std::string &msg);
+#endif
 #endif