From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 83798431FBF for ; Tue, 11 Mar 2014 16:02:27 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NwgXMjS0Um2h for ; Tue, 11 Mar 2014 16:02:25 -0700 (PDT) Received: from yantan.tethera.net (yantan.tethera.net [199.188.72.155]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 4D8B0429E2E for ; Tue, 11 Mar 2014 16:02:11 -0700 (PDT) Received: from remotemail by yantan.tethera.net with local (Exim 4.80) (envelope-from ) id 1WNVgY-0001v5-LN; Tue, 11 Mar 2014 20:02:10 -0300 Received: (nullmailer pid 25849 invoked by uid 1000); Tue, 11 Mar 2014 23:01:46 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [Patch v6 05/14] lib: add support for path: prefix searches Date: Tue, 11 Mar 2014 20:01:31 -0300 Message-Id: <1394578900-25618-6-git-send-email-david@tethera.net> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1394578900-25618-1-git-send-email-david@tethera.net> References: <1394578900-25618-1-git-send-email-david@tethera.net> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Mar 2014 23:02:27 -0000 From: Jani Nikula 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 f395061..93cc7f5 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 7aff4ae..21abe8e 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); -- 1.8.5.3