]> git.notmuchmail.org Git - notmuch/blob - lib/database-private.h
Merge tag '0.23.6'
[notmuch] / lib / database-private.h
1 /* database-private.h - For peeking into the internals of notmuch_database_t
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see https://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 #ifndef NOTMUCH_DATABASE_PRIVATE_H
22 #define NOTMUCH_DATABASE_PRIVATE_H
23
24 /* According to WG14/N1124, a C++ implementation won't provide us a
25  * macro like PRIx64 (which gives a printf format string for
26  * formatting a uint64_t as hexadecimal) unless we define
27  * __STDC_FORMAT_MACROS before including inttypes.h. That's annoying,
28  * but there it is.
29  */
30 #define __STDC_FORMAT_MACROS
31 #include <inttypes.h>
32
33 #include "notmuch-private.h"
34
35 #ifdef SILENCE_XAPIAN_DEPRECATION_WARNINGS
36 #define XAPIAN_DEPRECATED(D) D
37 #endif
38
39 #include <xapian.h>
40
41 #pragma GCC visibility push(hidden)
42
43 /* Bit masks for _notmuch_database::features.  Features are named,
44  * independent aspects of the database schema.
45  *
46  * A database stores the set of features that it "uses" (implicitly
47  * before database version 3 and explicitly as of version 3).
48  *
49  * A given library version will "recognize" a particular set of
50  * features; if a database uses a feature that the library does not
51  * recognize, the library will refuse to open it.  It is assumed the
52  * set of recognized features grows monotonically over time.  A
53  * library version will "implement" some subset of the recognized
54  * features: some operations may require that the database use (or not
55  * use) some feature, while other operations may support both
56  * databases that use and that don't use some feature.
57  *
58  * On disk, the database stores string names for these features (see
59  * the feature_names array).  These enum bit values are never
60  * persisted to disk and may change freely.
61  */
62 enum _notmuch_features {
63     /* If set, file names are stored in "file-direntry" terms.  If
64      * unset, file names are stored in document data.
65      *
66      * Introduced: version 1. */
67     NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
68
69     /* If set, directory timestamps are stored in documents with
70      * XDIRECTORY terms and relative paths.  If unset, directory
71      * timestamps are stored in documents with XTIMESTAMP terms and
72      * absolute paths.
73      *
74      * Introduced: version 1. */
75     NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
76
77     /* If set, the from, subject, and message-id headers are stored in
78      * message document values.  If unset, message documents *may*
79      * have these values, but if the value is empty, it must be
80      * retrieved from the message file.
81      *
82      * Introduced: optional in version 1, required as of version 3.
83      */
84     NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
85
86     /* If set, folder terms are boolean and path terms exist.  If
87      * unset, folder terms are probabilistic and stemmed and path
88      * terms do not exist.
89      *
90      * Introduced: version 2. */
91     NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
92
93     /* If set, missing messages are stored in ghost mail documents.
94      * If unset, thread IDs of ghost messages are stored as database
95      * metadata instead of in ghost documents.
96      *
97      * Introduced: version 3. */
98     NOTMUCH_FEATURE_GHOSTS = 1 << 4,
99
100
101     /* If set, then the database was created after the introduction of
102      * indexed mime types. If unset, then the database may contain a
103      * mixture of messages with indexed and non-indexed mime types.
104      *
105      * Introduced: version 3. */
106     NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
107
108     /* If set, messages store the revision number of the last
109      * modification in NOTMUCH_VALUE_LAST_MOD.
110      *
111      * Introduced: version 3. */
112     NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
113 };
114
115 /* In C++, a named enum is its own type, so define bitwise operators
116  * on _notmuch_features. */
117 inline _notmuch_features
118 operator|(_notmuch_features a, _notmuch_features b)
119 {
120     return static_cast<_notmuch_features>(
121         static_cast<unsigned>(a) | static_cast<unsigned>(b));
122 }
123
124 inline _notmuch_features
125 operator&(_notmuch_features a, _notmuch_features b)
126 {
127     return static_cast<_notmuch_features>(
128         static_cast<unsigned>(a) & static_cast<unsigned>(b));
129 }
130
131 inline _notmuch_features
132 operator~(_notmuch_features a)
133 {
134     return static_cast<_notmuch_features>(~static_cast<unsigned>(a));
135 }
136
137 inline _notmuch_features&
138 operator|=(_notmuch_features &a, _notmuch_features b)
139 {
140     a = a | b;
141     return a;
142 }
143
144 inline _notmuch_features&
145 operator&=(_notmuch_features &a, _notmuch_features b)
146 {
147     a = a & b;
148     return a;
149 }
150
151 /*
152  * Configuration options for xapian database fields */
153 typedef enum notmuch_field_flags {
154     NOTMUCH_FIELD_NO_FLAGS = 0,
155     NOTMUCH_FIELD_EXTERNAL = 1 << 0,
156     NOTMUCH_FIELD_PROBABILISTIC = 1 << 1
157 } notmuch_field_flag_t;
158
159 /*
160  * define bitwise operators to hide casts */
161 inline notmuch_field_flag_t
162 operator|(notmuch_field_flag_t a, notmuch_field_flag_t b)
163 {
164     return static_cast<notmuch_field_flag_t>(
165         static_cast<unsigned>(a) | static_cast<unsigned>(b));
166 }
167
168 inline notmuch_field_flag_t
169 operator&(notmuch_field_flag_t a, notmuch_field_flag_t b)
170 {
171     return static_cast<notmuch_field_flag_t>(
172         static_cast<unsigned>(a) & static_cast<unsigned>(b));
173 }
174
175 #define NOTMUCH_QUERY_PARSER_FLAGS (Xapian::QueryParser::FLAG_BOOLEAN | \
176                                     Xapian::QueryParser::FLAG_PHRASE | \
177                                     Xapian::QueryParser::FLAG_LOVEHATE | \
178                                     Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE | \
179                                     Xapian::QueryParser::FLAG_WILDCARD | \
180                                     Xapian::QueryParser::FLAG_PURE_NOT)
181
182 struct _notmuch_database {
183     notmuch_bool_t exception_reported;
184
185     char *path;
186
187     notmuch_database_mode_t mode;
188     int atomic_nesting;
189     /* TRUE if changes have been made in this atomic section */
190     notmuch_bool_t atomic_dirty;
191     Xapian::Database *xapian_db;
192
193     /* Bit mask of features used by this database.  This is a
194      * bitwise-OR of NOTMUCH_FEATURE_* values (above). */
195     enum _notmuch_features features;
196
197     unsigned int last_doc_id;
198     uint64_t last_thread_id;
199
200     /* error reporting; this value persists only until the
201      * next library call. May be NULL */
202     char *status_string;
203
204     /* Highest committed revision number.  Modifications are recorded
205      * under a higher revision number, which can be generated with
206      * notmuch_database_new_revision. */
207     unsigned long revision;
208     const char *uuid;
209
210     /* Keep track of the number of times the database has been re-opened
211      * (or other global invalidations of notmuch's caching)
212      */
213     unsigned long view;
214     Xapian::QueryParser *query_parser;
215     Xapian::TermGenerator *term_gen;
216     Xapian::ValueRangeProcessor *value_range_processor;
217     Xapian::ValueRangeProcessor *date_range_processor;
218     Xapian::ValueRangeProcessor *last_mod_range_processor;
219 };
220
221 /* Prior to database version 3, features were implied by the database
222  * version number, so hard-code them for earlier versions. */
223 #define NOTMUCH_FEATURES_V0 ((enum _notmuch_features)0)
224 #define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \
225                              NOTMUCH_FEATURE_DIRECTORY_DOCS)
226 #define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)
227
228 /* Current database features.  If any of these are missing from a
229  * database, request an upgrade.
230  * NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES and
231  * NOTMUCH_FEATURE_INDEXED_MIMETYPES are not included because upgrade
232  * doesn't currently introduce the features (though brand new databases
233  * will have it). */
234 #define NOTMUCH_FEATURES_CURRENT \
235     (NOTMUCH_FEATURE_FILE_TERMS | NOTMUCH_FEATURE_DIRECTORY_DOCS | \
236      NOTMUCH_FEATURE_BOOL_FOLDER | NOTMUCH_FEATURE_GHOSTS | \
237      NOTMUCH_FEATURE_LAST_MOD)
238
239 /* Return the list of terms from the given iterator matching a prefix.
240  * The prefix will be stripped from the strings in the returned list.
241  * The list will be allocated using ctx as the talloc context.
242  *
243  * The function returns NULL on failure.
244  */
245 notmuch_string_list_t *
246 _notmuch_database_get_terms_with_prefix (void *ctx, Xapian::TermIterator &i,
247                                          Xapian::TermIterator &end,
248                                          const char *prefix);
249
250 #pragma GCC visibility pop
251
252 #endif