From 59823f964250be6d0ddbdfc45d4b07803bab267d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 8 Feb 2014 20:50:44 +0200 Subject: [PATCH 1/1] lib: add support for path: prefix searches The path: prefix is a literal boolean prefix matching the paths, relative from the maildir root, of the message files. path:foo matches all message files in foo (but not in foo/new or foo/cur). path:foo/new matches all message files in foo/new. path:"" matches all message files in the top level maildir. path:foo/** matches all message files in foo and recursively in all subdirectories of foo. path:** matches all message files recursively, i.e. all messages. --- lib/database.cc | 7 ++++--- lib/message.cc | 52 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index f395061e..93cc7f57 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -100,8 +100,8 @@ typedef struct { * In addition, terms from the content of the message are added with * "from", "to", "attachment", and "subject" prefixes for use by the * user in searching. Similarly, terms from the path of the mail - * message are added with a "folder" prefix. But the database doesn't - * really care itself about any of these. + * message are added with "folder" and "path" prefixes. But the + * database doesn't really care itself about any of these. * * The data portion of a mail document is empty. * @@ -208,7 +208,8 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = { { "thread", "G" }, { "tag", "K" }, { "is", "K" }, - { "id", "Q" } + { "id", "Q" }, + { "path", "P" }, }; static prefix_t PROBABILISTIC_PREFIX[]= { diff --git a/lib/message.cc b/lib/message.cc index 7aff4ae5..21abe8e1 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -504,6 +504,40 @@ _notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix) } } +#define RECURSIVE_SUFFIX "/**" + +/* Add "path:" terms for directory. */ +static notmuch_status_t +_notmuch_message_add_path_terms (notmuch_message_t *message, + const char *directory) +{ + /* Add exact "path:" term. */ + _notmuch_message_add_term (message, "path", directory); + + if (strlen (directory)) { + char *path, *p; + + path = talloc_asprintf (NULL, "%s%s", directory, RECURSIVE_SUFFIX); + if (! path) + return NOTMUCH_STATUS_OUT_OF_MEMORY; + + /* Add recursive "path:" terms for directory and all parents. */ + for (p = path + strlen (path) - 1; p > path; p--) { + if (*p == '/') { + strcpy (p, RECURSIVE_SUFFIX); + _notmuch_message_add_term (message, "path", path); + } + } + + talloc_free (path); + } + + /* Recursive all-matching path:** for consistency. */ + _notmuch_message_add_term (message, "path", "**"); + + return NOTMUCH_STATUS_SUCCESS; +} + /* Add directory based terms for all filenames of the message. */ static notmuch_status_t _notmuch_message_add_directory_terms (void *ctx, notmuch_message_t *message) @@ -538,6 +572,8 @@ _notmuch_message_add_directory_terms (void *ctx, notmuch_message_t *message) directory_id); if (strlen (directory)) _notmuch_message_gen_terms (message, "folder", directory); + + _notmuch_message_add_path_terms (message, directory); } return status; @@ -577,6 +613,8 @@ _notmuch_message_add_filename (notmuch_message_t *message, /* New terms allow user to search with folder: specification. */ _notmuch_message_gen_terms (message, "folder", directory); + _notmuch_message_add_path_terms (message, directory); + talloc_free (local); return NOTMUCH_STATUS_SUCCESS; @@ -618,18 +656,18 @@ _notmuch_message_remove_filename (notmuch_message_t *message, if (status) return status; - /* Re-synchronize "folder:" terms for this message. This requires: - * 1. removing all "folder:" terms - * 2. removing all "folder:" stemmed terms - * 3. adding back terms for all remaining filenames of the message. */ + /* Re-synchronize "folder:" and "path:" terms for this message. */ - /* 1. removing all "folder:" terms */ + /* Remove all "folder:" terms. */ _notmuch_message_remove_terms (message, folder_prefix); - /* 2. removing all "folder:" stemmed terms */ + /* Remove all "folder:" stemmed terms. */ _notmuch_message_remove_terms (message, zfolder_prefix); - /* 3. adding back terms for all remaining filenames of the message. */ + /* Remove all "path:" terms. */ + _notmuch_message_remove_terms (message, _find_prefix ("path")); + + /* Add back terms for all remaining filenames of the message. */ status = _notmuch_message_add_directory_terms (local, message); talloc_free (local); -- 2.43.0