1 #include "database-private.h"
4 /* NOTMUCH_FEATURE_* value. */
5 _notmuch_features value;
6 /* Feature name as it appears in the database. This name should
7 * be appropriate for displaying to the user if an older version
8 * of notmuch doesn't support this feature. */
10 /* Compatibility flags when this feature is declared. */
13 { NOTMUCH_FEATURE_FILE_TERMS,
14 "multiple paths per message", "rw" },
15 { NOTMUCH_FEATURE_DIRECTORY_DOCS,
16 "relative directory paths", "rw" },
17 /* Header values are not required for reading a database because a
18 * reader can just refer to the message file. */
19 { NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES,
20 "from/subject/message-ID in database", "w" },
21 { NOTMUCH_FEATURE_BOOL_FOLDER,
22 "exact folder:/path: search", "rw" },
23 { NOTMUCH_FEATURE_GHOSTS,
24 "mail documents for missing messages", "w" },
25 /* Knowledge of the index mime-types are not required for reading
26 * a database because a reader will just be unable to query
28 { NOTMUCH_FEATURE_INDEXED_MIMETYPES,
29 "indexed MIME types", "w" },
30 { NOTMUCH_FEATURE_LAST_MOD,
31 "modification tracking", "w" },
32 /* Existing databases will work fine for all queries not involving
34 { NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
35 "index body and headers separately", "w" },
39 _notmuch_database_print_features (const void *ctx, unsigned int features)
42 char *res = talloc_strdup (ctx, "");
44 for (i = 0; i < ARRAY_SIZE (feature_names); ++i)
45 if (features & feature_names[i].value)
46 res = talloc_asprintf_append_buffer (
47 res, "%s\t%s\n", feature_names[i].name, feature_names[i].flags);
53 /* Parse a database features string from the given database version.
54 * Returns the feature bit set.
56 * For version < 3, this ignores the features string and returns a
57 * hard-coded set of features.
59 * If there are unrecognized features that are required to open the
60 * database in mode (which should be 'r' or 'w'), return a
61 * comma-separated list of unrecognized but required features in
62 * *incompat_out suitable for presenting to the user. *incompat_out
63 * will be allocated from ctx.
66 _notmuch_database_parse_features (const void *ctx, const char *features, unsigned int version,
67 char mode, char **incompat_out)
69 _notmuch_features res = static_cast<_notmuch_features>(0);
70 unsigned int namelen, i;
74 /* Prior to database version 3, features were implied by the
77 return NOTMUCH_FEATURES_V0;
78 else if (version == 1)
79 return NOTMUCH_FEATURES_V1;
80 else if (version == 2)
81 return NOTMUCH_FEATURES_V2;
83 /* Parse the features string */
84 while ((features = strtok_len_c (features + llen, "\n", &llen)) != NULL) {
85 flags = strchr (features, '\t');
86 if (! flags || flags > features + llen)
88 namelen = flags - features;
90 for (i = 0; i < ARRAY_SIZE (feature_names); ++i) {
91 if (strlen (feature_names[i].name) == namelen &&
92 strncmp (feature_names[i].name, features, namelen) == 0) {
93 res |= feature_names[i].value;
98 if (i == ARRAY_SIZE (feature_names) && incompat_out) {
99 /* Unrecognized feature */
100 const char *have = strchr (flags, mode);
101 if (have && have < features + llen) {
102 /* This feature is required to access this database in
103 * 'mode', but we don't understand it. */
105 *incompat_out = talloc_strdup (ctx, "");
106 *incompat_out = talloc_asprintf_append_buffer (
107 *incompat_out, "%s%.*s", **incompat_out ? ", " : "",