From 3b07221a194d970004d922f52ee7afbeb734aaec Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sun, 23 Feb 2014 00:25:35 +0200 Subject: [PATCH] [PATCH v2 04/13] lib: make folder: prefix literal --- 69/65b7194ba67ce4cddd00e51e2957da77b98eff | 304 ++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 69/65b7194ba67ce4cddd00e51e2957da77b98eff diff --git a/69/65b7194ba67ce4cddd00e51e2957da77b98eff b/69/65b7194ba67ce4cddd00e51e2957da77b98eff new file mode 100644 index 000000000..5caae648a --- /dev/null +++ b/69/65b7194ba67ce4cddd00e51e2957da77b98eff @@ -0,0 +1,304 @@ +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 1F4CB429E25 + for ; Sat, 22 Feb 2014 14:26:11 -0800 (PST) +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 DwWUcfNAT9u3 for ; + Sat, 22 Feb 2014 14:26:05 -0800 (PST) +Received: from mail-ea0-f176.google.com (mail-ea0-f176.google.com + [209.85.215.176]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) + (No client certificate requested) + by olra.theworths.org (Postfix) with ESMTPS id 0C3C9431FD2 + for ; Sat, 22 Feb 2014 14:25:57 -0800 (PST) +Received: by mail-ea0-f176.google.com with SMTP id b10so2277437eae.21 + for ; Sat, 22 Feb 2014 14:25:56 -0800 (PST) +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=Bw3EqsZmQxSICAETngxVnl25gifKwBq8V2WAe033C58=; + b=JAsFnL+JHoWwsIQrhIrs0sy16i+R5PvDfvNc/Sdk4a2yg0rCUiVaK0nwiqCbKX7U6V + WqEWO+Tqebvp3zn39gQC/RST121mIDqur/n97WpcXfGcWlHXDd4SvXuGI3H39QmoGnbE + A4bg1mQQPu3nk85dt5GgHES+CQ2OchEagZITbAf7ApSvKwgM+r8r48zZlzrqghGxGpV/ + t9gu1QI5K3BkplZKpVgG+HLwL6mf6ULMHnF7ITEKT4ajqWH4t4efdWfp3bENfpEdPDFY + Rv/oickkyZtiZDY77zkCBy4X6JI7WoAU0kopepSCia+HsMJYztm4HlduT0TtmjfxrGPM + FKjg== +X-Gm-Message-State: + ALoCoQl/uIaWBduy6W1YC4VIh+kp25fidq/8znOJz3nsutqqiOMq3Bzq3lwVn4lTUrd0OmO016dO +X-Received: by 10.14.177.135 with SMTP id d7mr4770813eem.33.1393107956754; + Sat, 22 Feb 2014 14:25:56 -0800 (PST) +Received: from localhost (dsl-hkibrasgw2-58c36f-91.dhcp.inet.fi. + [88.195.111.91]) + by mx.google.com with ESMTPSA id m9sm43763356eeh.3.2014.02.22.14.25.55 + for + (version=TLSv1.2 cipher=RC4-SHA bits=128/128); + Sat, 22 Feb 2014 14:25:56 -0800 (PST) +From: Jani Nikula +To: notmuch@notmuchmail.org +Subject: [PATCH v2 04/13] lib: make folder: prefix literal +Date: Sun, 23 Feb 2014 00:25:35 +0200 +Message-Id: + +X-Mailer: git-send-email 1.8.5.3 +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: Sat, 22 Feb 2014 22:26:11 -0000 + +In xapian terms, convert folder: prefix from probabilistic to boolean +prefix, matching the paths, relative form the maildir root, of the +message files, ignoring the maildir new and cur leaf directories. + +folder:foo matches all message files in foo, foo/new, and foo/cur. + +folder:foo/new does *not* match message files in foo/new. + +folder:"" matches all message files in the top level maildir and its +new and cur subdirectories. + +This change constitutes a database change: bump the database version +and add database upgrade support for folder: terms. The upgrade also +adds path: terms. +--- + lib/database.cc | 38 ++++++++++++++++++++++-- + lib/message.cc | 80 ++++++++++++++++++++++++++++++++++++++++++++------- + lib/notmuch-private.h | 3 ++ + 3 files changed, 108 insertions(+), 13 deletions(-) + +diff --git a/lib/database.cc b/lib/database.cc +index 93cc7f57e9db..186e3a7976fe 100644 +--- a/lib/database.cc ++++ b/lib/database.cc +@@ -42,7 +42,7 @@ typedef struct { + const char *prefix; + } prefix_t; + +-#define NOTMUCH_DATABASE_VERSION 1 ++#define NOTMUCH_DATABASE_VERSION 2 + + #define STRINGIFY(s) _SUB_STRINGIFY(s) + #define _SUB_STRINGIFY(s) #s +@@ -210,6 +210,7 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = { + { "is", "K" }, + { "id", "Q" }, + { "path", "P" }, ++ { "folder", "XFOLDER:" }, + }; + + static prefix_t PROBABILISTIC_PREFIX[]= { +@@ -217,7 +218,6 @@ static prefix_t PROBABILISTIC_PREFIX[]= { + { "to", "XTO" }, + { "attachment", "XATTACHMENT" }, + { "subject", "XSUBJECT"}, +- { "folder", "XFOLDER"} + }; + + const char * +@@ -1168,6 +1168,40 @@ notmuch_database_upgrade (notmuch_database_t *notmuch, + } + } + ++ /* ++ * Prior to version 2, the "folder:" prefix was probabilistic and ++ * stemmed. Change it to the current boolean prefix. Add "path:" ++ * prefixes while at it. ++ */ ++ if (version < 2) { ++ notmuch_query_t *query = notmuch_query_create (notmuch, ""); ++ notmuch_messages_t *messages; ++ notmuch_message_t *message; ++ ++ count = 0; ++ total = notmuch_query_count_messages (query); ++ ++ for (messages = notmuch_query_search_messages (query); ++ notmuch_messages_valid (messages); ++ notmuch_messages_move_to_next (messages)) { ++ if (do_progress_notify) { ++ progress_notify (closure, (double) count / total); ++ do_progress_notify = 0; ++ } ++ ++ message = notmuch_messages_get (messages); ++ ++ _notmuch_message_upgrade_folder (message); ++ _notmuch_message_sync (message); ++ ++ notmuch_message_destroy (message); ++ ++ count++; ++ } ++ ++ notmuch_query_destroy (query); ++ } ++ + db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION)); + db->flush (); + +diff --git a/lib/message.cc b/lib/message.cc +index 21abe8e12b9d..31cb9f107dd7 100644 +--- a/lib/message.cc ++++ b/lib/message.cc +@@ -504,6 +504,56 @@ _notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix) + } + } + ++/* Return true if p points at "new" or "cur". */ ++static bool is_maildir (const char *p) ++{ ++ return strcmp (p, "cur") == 0 || strcmp (p, "new") == 0; ++} ++ ++/* Add "folder:" term for directory. */ ++static notmuch_status_t ++_notmuch_message_add_folder_terms (notmuch_message_t *message, ++ const char *directory) ++{ ++ char *folder, *last; ++ ++ folder = talloc_strdup (NULL, directory); ++ if (! folder) ++ return NOTMUCH_STATUS_OUT_OF_MEMORY; ++ ++ /* ++ * If the message file is in a leaf directory named "new" or ++ * "cur", presume maildir and index the parent directory. Thus a ++ * "folder:" prefix search matches messages in the specified ++ * maildir folder, i.e. in the specified directory and its "new" ++ * and "cur" subdirectories. ++ * ++ * Note that this means the "folder:" prefix can't be used for ++ * distinguishing between message files in "new" or "cur". The ++ * "path:" prefix needs to be used for that. ++ * ++ * Note the deliberate difference to _filename_is_in_maildir(). We ++ * don't want to index different things depending on the existence ++ * or non-existence of all maildir sibling directories "new", ++ * "cur", and "tmp". Doing so would be surprising, and difficult ++ * for the user to fix in case all subdirectories were not in ++ * place during indexing. ++ */ ++ last = strrchr (folder, '/'); ++ if (last) { ++ if (is_maildir (last + 1)) ++ *last = '\0'; ++ } else if (is_maildir (folder)) { ++ *folder = '\0'; ++ } ++ ++ _notmuch_message_add_term (message, "folder", folder); ++ ++ talloc_free (folder); ++ ++ return NOTMUCH_STATUS_SUCCESS; ++} ++ + #define RECURSIVE_SUFFIX "/**" + + /* Add "path:" terms for directory. */ +@@ -570,9 +620,8 @@ _notmuch_message_add_directory_terms (void *ctx, notmuch_message_t *message) + directory = _notmuch_database_get_directory_path (ctx, + message->notmuch, + directory_id); +- if (strlen (directory)) +- _notmuch_message_gen_terms (message, "folder", directory); + ++ _notmuch_message_add_folder_terms (message, directory); + _notmuch_message_add_path_terms (message, directory); + } + +@@ -610,9 +659,7 @@ _notmuch_message_add_filename (notmuch_message_t *message, + * notmuch_directory_get_child_files() . */ + _notmuch_message_add_term (message, "file-direntry", direntry); + +- /* New terms allow user to search with folder: specification. */ +- _notmuch_message_gen_terms (message, "folder", directory); +- ++ _notmuch_message_add_folder_terms (message, directory); + _notmuch_message_add_path_terms (message, directory); + + talloc_free (local); +@@ -637,8 +684,6 @@ _notmuch_message_remove_filename (notmuch_message_t *message, + const char *filename) + { + void *local = talloc_new (message); +- const char *folder_prefix = _find_prefix ("folder"); +- char *zfolder_prefix = talloc_asprintf(local, "Z%s", folder_prefix); + char *direntry; + notmuch_private_status_t private_status; + notmuch_status_t status; +@@ -659,10 +704,7 @@ _notmuch_message_remove_filename (notmuch_message_t *message, + /* Re-synchronize "folder:" and "path:" terms for this message. */ + + /* Remove all "folder:" terms. */ +- _notmuch_message_remove_terms (message, folder_prefix); +- +- /* Remove all "folder:" stemmed terms. */ +- _notmuch_message_remove_terms (message, zfolder_prefix); ++ _notmuch_message_remove_terms (message, _find_prefix ("folder")); + + /* Remove all "path:" terms. */ + _notmuch_message_remove_terms (message, _find_prefix ("path")); +@@ -675,6 +717,22 @@ _notmuch_message_remove_filename (notmuch_message_t *message, + return status; + } + ++/* Upgrade the "folder:" prefix from V1 to V2. */ ++#define FOLDER_PREFIX_V1 "XFOLDER" ++#define ZFOLDER_PREFIX_V1 "Z" FOLDER_PREFIX_V1 ++void ++_notmuch_message_upgrade_folder (notmuch_message_t *message) ++{ ++ /* Remove all old "folder:" terms. */ ++ _notmuch_message_remove_terms (message, FOLDER_PREFIX_V1); ++ ++ /* Remove all old "folder:" stemmed terms. */ ++ _notmuch_message_remove_terms (message, ZFOLDER_PREFIX_V1); ++ ++ /* Add new boolean "folder:" and "path:" terms. */ ++ _notmuch_message_add_directory_terms (message, message); ++} ++ + char * + _notmuch_message_talloc_copy_data (notmuch_message_t *message) + { +diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h +index af185c7c5ba8..59eb2bc285a5 100644 +--- a/lib/notmuch-private.h ++++ b/lib/notmuch-private.h +@@ -263,6 +263,9 @@ _notmuch_message_gen_terms (notmuch_message_t *message, + void + _notmuch_message_upgrade_filename_storage (notmuch_message_t *message); + ++void ++_notmuch_message_upgrade_folder (notmuch_message_t *message); ++ + notmuch_status_t + _notmuch_message_add_filename (notmuch_message_t *message, + const char *filename); +-- +1.8.5.3 + -- 2.26.2