Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 1B09C429E26 for ; Sun, 9 Mar 2014 14:41:10 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] 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 0P38PUJ9FqON for ; Sun, 9 Mar 2014 14:41:03 -0700 (PDT) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com [209.85.215.43]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 648A2431FCB for ; Sun, 9 Mar 2014 14:40:49 -0700 (PDT) Received: by mail-la0-f43.google.com with SMTP id e16so4196121lan.30 for ; Sun, 09 Mar 2014 14:40:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=PK2nnlWXwuGi6eczimmyqaHlzZevM7Pxi8TTxhCNny8=; b=c0JgRYlT7IkAaYGhmEnLHcDnFhAQLmNe7GLajCYIFHgvmnWPJKNqE9Lu7HrJwaNaBB CXnzhYbBxNXD3Ihpg0XvdopPnntiOUyLombXkO1KispyoTABrIxYQchPQbqrGaurZjIl fVFeZ5fpGv955ywdymUn8W/ERsXPDfSqlOP5oCCNn7rF9M1sGUqGGcdPCOvdtUtkONXP uVyRPPRiF5aNvIbDu4mDRonXF9UtooDPvOwLbLRsqLfQbNt5GF7ztwNpgoNMrqaW4+wy 4xj+F783OBtViNsfGLisS2xEilDcFJU0iyQqRnDHJGNEDiI1kTTBxqWQ4PfrQ74LVmw3 Zr3Q== X-Gm-Message-State: ALoCoQmTp4DX3P162u8Z8nXvvZwbORjgDBpC/Z/kwQTyK+oZ5cQ+Q4SqU2RQ0UMaaOCXhat/eblI X-Received: by 10.152.1.199 with SMTP id 7mr21284840lao.24.1394401247515; Sun, 09 Mar 2014 14:40:47 -0700 (PDT) Received: from localhost (dsl-hkibrasgw2-58c36f-91.dhcp.inet.fi. [88.195.111.91]) by mx.google.com with ESMTPSA id zf7sm26896509lab.7.2014.03.09.14.40.46 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 09 Mar 2014 14:40:46 -0700 (PDT) From: Jani Nikula To: notmuch@notmuchmail.org Subject: [PATCH v4 04/13] lib: add support for path: prefix searches Date: Sun, 9 Mar 2014 23:40:25 +0200 Message-Id: <2a63892eb579cf0cd62a34f6897a2b12d552b617.1394400503.git.jani@nikula.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: References: In-Reply-To: References: 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: Sun, 09 Mar 2014 21:41:10 -0000 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 f395061e3a73..93cc7f57e9db 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 7aff4ae5111a..21abe8e12b9d 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.9.0