Re: [PATCH 9/9] add has: query prefix to search for specific properties
[notmuch-archives.git] / 69 / 65b7194ba67ce4cddd00e51e2957da77b98eff
1 Return-Path: <jani@nikula.org>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 1F4CB429E25\r
6         for <notmuch@notmuchmail.org>; Sat, 22 Feb 2014 14:26:11 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
9 X-Spam-Flag: NO\r
10 X-Spam-Score: -0.7\r
11 X-Spam-Level: \r
12 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
13         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id DwWUcfNAT9u3 for <notmuch@notmuchmail.org>;\r
17         Sat, 22 Feb 2014 14:26:05 -0800 (PST)\r
18 Received: from mail-ea0-f176.google.com (mail-ea0-f176.google.com\r
19         [209.85.215.176]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id 0C3C9431FD2\r
22         for <notmuch@notmuchmail.org>; Sat, 22 Feb 2014 14:25:57 -0800 (PST)\r
23 Received: by mail-ea0-f176.google.com with SMTP id b10so2277437eae.21\r
24         for <notmuch@notmuchmail.org>; Sat, 22 Feb 2014 14:25:56 -0800 (PST)\r
25 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
26         d=1e100.net; s=20130820;\r
27         h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\r
28         :references:in-reply-to:references;\r
29         bh=Bw3EqsZmQxSICAETngxVnl25gifKwBq8V2WAe033C58=;\r
30         b=JAsFnL+JHoWwsIQrhIrs0sy16i+R5PvDfvNc/Sdk4a2yg0rCUiVaK0nwiqCbKX7U6V\r
31         WqEWO+Tqebvp3zn39gQC/RST121mIDqur/n97WpcXfGcWlHXDd4SvXuGI3H39QmoGnbE\r
32         A4bg1mQQPu3nk85dt5GgHES+CQ2OchEagZITbAf7ApSvKwgM+r8r48zZlzrqghGxGpV/\r
33         t9gu1QI5K3BkplZKpVgG+HLwL6mf6ULMHnF7ITEKT4ajqWH4t4efdWfp3bENfpEdPDFY\r
34         Rv/oickkyZtiZDY77zkCBy4X6JI7WoAU0kopepSCia+HsMJYztm4HlduT0TtmjfxrGPM\r
35         FKjg==\r
36 X-Gm-Message-State:\r
37  ALoCoQl/uIaWBduy6W1YC4VIh+kp25fidq/8znOJz3nsutqqiOMq3Bzq3lwVn4lTUrd0OmO016dO\r
38 X-Received: by 10.14.177.135 with SMTP id d7mr4770813eem.33.1393107956754;\r
39         Sat, 22 Feb 2014 14:25:56 -0800 (PST)\r
40 Received: from localhost (dsl-hkibrasgw2-58c36f-91.dhcp.inet.fi.\r
41         [88.195.111.91])\r
42         by mx.google.com with ESMTPSA id m9sm43763356eeh.3.2014.02.22.14.25.55\r
43         for <multiple recipients>\r
44         (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
45         Sat, 22 Feb 2014 14:25:56 -0800 (PST)\r
46 From: Jani Nikula <jani@nikula.org>\r
47 To: notmuch@notmuchmail.org\r
48 Subject: [PATCH v2 04/13] lib: make folder: prefix literal\r
49 Date: Sun, 23 Feb 2014 00:25:35 +0200\r
50 Message-Id:\r
51  <aedea7da8caa363dea7737c1446081b8441d2cb0.1393105055.git.jani@nikula.org>\r
52 X-Mailer: git-send-email 1.8.5.3\r
53 In-Reply-To: <cover.1393105055.git.jani@nikula.org>\r
54 References: <cover.1393105055.git.jani@nikula.org>\r
55 In-Reply-To: <cover.1393105055.git.jani@nikula.org>\r
56 References: <cover.1393105055.git.jani@nikula.org>\r
57 X-BeenThere: notmuch@notmuchmail.org\r
58 X-Mailman-Version: 2.1.13\r
59 Precedence: list\r
60 List-Id: "Use and development of the notmuch mail system."\r
61         <notmuch.notmuchmail.org>\r
62 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
63         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
64 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
65 List-Post: <mailto:notmuch@notmuchmail.org>\r
66 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
67 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
68         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
69 X-List-Received-Date: Sat, 22 Feb 2014 22:26:11 -0000\r
70 \r
71 In xapian terms, convert folder: prefix from probabilistic to boolean\r
72 prefix, matching the paths, relative form the maildir root, of the\r
73 message files, ignoring the maildir new and cur leaf directories.\r
74 \r
75 folder:foo matches all message files in foo, foo/new, and foo/cur.\r
76 \r
77 folder:foo/new does *not* match message files in foo/new.\r
78 \r
79 folder:"" matches all message files in the top level maildir and its\r
80 new and cur subdirectories.\r
81 \r
82 This change constitutes a database change: bump the database version\r
83 and add database upgrade support for folder: terms. The upgrade also\r
84 adds path: terms.\r
85 ---\r
86  lib/database.cc       | 38 ++++++++++++++++++++++--\r
87  lib/message.cc        | 80 ++++++++++++++++++++++++++++++++++++++++++++-------\r
88  lib/notmuch-private.h |  3 ++\r
89  3 files changed, 108 insertions(+), 13 deletions(-)\r
90 \r
91 diff --git a/lib/database.cc b/lib/database.cc\r
92 index 93cc7f57e9db..186e3a7976fe 100644\r
93 --- a/lib/database.cc\r
94 +++ b/lib/database.cc\r
95 @@ -42,7 +42,7 @@ typedef struct {\r
96      const char *prefix;\r
97  } prefix_t;\r
98  \r
99 -#define NOTMUCH_DATABASE_VERSION 1\r
100 +#define NOTMUCH_DATABASE_VERSION 2\r
101  \r
102  #define STRINGIFY(s) _SUB_STRINGIFY(s)\r
103  #define _SUB_STRINGIFY(s) #s\r
104 @@ -210,6 +210,7 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {\r
105      { "is",                    "K" },\r
106      { "id",                    "Q" },\r
107      { "path",                  "P" },\r
108 +    { "folder",                        "XFOLDER:" },\r
109  };\r
110  \r
111  static prefix_t PROBABILISTIC_PREFIX[]= {\r
112 @@ -217,7 +218,6 @@ static prefix_t PROBABILISTIC_PREFIX[]= {\r
113      { "to",                    "XTO" },\r
114      { "attachment",            "XATTACHMENT" },\r
115      { "subject",               "XSUBJECT"},\r
116 -    { "folder",                        "XFOLDER"}\r
117  };\r
118  \r
119  const char *\r
120 @@ -1168,6 +1168,40 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,\r
121         }\r
122      }\r
123  \r
124 +    /*\r
125 +     * Prior to version 2, the "folder:" prefix was probabilistic and\r
126 +     * stemmed. Change it to the current boolean prefix. Add "path:"\r
127 +     * prefixes while at it.\r
128 +     */\r
129 +    if (version < 2) {\r
130 +       notmuch_query_t *query = notmuch_query_create (notmuch, "");\r
131 +       notmuch_messages_t *messages;\r
132 +       notmuch_message_t *message;\r
133 +\r
134 +       count = 0;\r
135 +       total = notmuch_query_count_messages (query);\r
136 +\r
137 +       for (messages = notmuch_query_search_messages (query);\r
138 +            notmuch_messages_valid (messages);\r
139 +            notmuch_messages_move_to_next (messages)) {\r
140 +           if (do_progress_notify) {\r
141 +               progress_notify (closure, (double) count / total);\r
142 +               do_progress_notify = 0;\r
143 +           }\r
144 +\r
145 +           message = notmuch_messages_get (messages);\r
146 +\r
147 +           _notmuch_message_upgrade_folder (message);\r
148 +           _notmuch_message_sync (message);\r
149 +\r
150 +           notmuch_message_destroy (message);\r
151 +\r
152 +           count++;\r
153 +       }\r
154 +\r
155 +       notmuch_query_destroy (query);\r
156 +    }\r
157 +\r
158      db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));\r
159      db->flush ();\r
160  \r
161 diff --git a/lib/message.cc b/lib/message.cc\r
162 index 21abe8e12b9d..31cb9f107dd7 100644\r
163 --- a/lib/message.cc\r
164 +++ b/lib/message.cc\r
165 @@ -504,6 +504,56 @@ _notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix)\r
166      }\r
167  }\r
168  \r
169 +/* Return true if p points at "new" or "cur". */\r
170 +static bool is_maildir (const char *p)\r
171 +{\r
172 +    return strcmp (p, "cur") == 0 || strcmp (p, "new") == 0;\r
173 +}\r
174 +\r
175 +/* Add "folder:" term for directory. */\r
176 +static notmuch_status_t\r
177 +_notmuch_message_add_folder_terms (notmuch_message_t *message,\r
178 +                                  const char *directory)\r
179 +{\r
180 +    char *folder, *last;\r
181 +\r
182 +    folder = talloc_strdup (NULL, directory);\r
183 +    if (! folder)\r
184 +       return NOTMUCH_STATUS_OUT_OF_MEMORY;\r
185 +\r
186 +    /*\r
187 +     * If the message file is in a leaf directory named "new" or\r
188 +     * "cur", presume maildir and index the parent directory. Thus a\r
189 +     * "folder:" prefix search matches messages in the specified\r
190 +     * maildir folder, i.e. in the specified directory and its "new"\r
191 +     * and "cur" subdirectories.\r
192 +     *\r
193 +     * Note that this means the "folder:" prefix can't be used for\r
194 +     * distinguishing between message files in "new" or "cur". The\r
195 +     * "path:" prefix needs to be used for that.\r
196 +     *\r
197 +     * Note the deliberate difference to _filename_is_in_maildir(). We\r
198 +     * don't want to index different things depending on the existence\r
199 +     * or non-existence of all maildir sibling directories "new",\r
200 +     * "cur", and "tmp". Doing so would be surprising, and difficult\r
201 +     * for the user to fix in case all subdirectories were not in\r
202 +     * place during indexing.\r
203 +     */\r
204 +    last = strrchr (folder, '/');\r
205 +    if (last) {\r
206 +       if (is_maildir (last + 1))\r
207 +           *last = '\0';\r
208 +    } else if (is_maildir (folder)) {\r
209 +       *folder = '\0';\r
210 +    }\r
211 +\r
212 +    _notmuch_message_add_term (message, "folder", folder);\r
213 +\r
214 +    talloc_free (folder);\r
215 +\r
216 +    return NOTMUCH_STATUS_SUCCESS;\r
217 +}\r
218 +\r
219  #define RECURSIVE_SUFFIX "/**"\r
220  \r
221  /* Add "path:" terms for directory. */\r
222 @@ -570,9 +620,8 @@ _notmuch_message_add_directory_terms (void *ctx, notmuch_message_t *message)\r
223         directory = _notmuch_database_get_directory_path (ctx,\r
224                                                           message->notmuch,\r
225                                                           directory_id);\r
226 -       if (strlen (directory))\r
227 -           _notmuch_message_gen_terms (message, "folder", directory);\r
228  \r
229 +       _notmuch_message_add_folder_terms (message, directory);\r
230         _notmuch_message_add_path_terms (message, directory);\r
231      }\r
232  \r
233 @@ -610,9 +659,7 @@ _notmuch_message_add_filename (notmuch_message_t *message,\r
234       * notmuch_directory_get_child_files() . */\r
235      _notmuch_message_add_term (message, "file-direntry", direntry);\r
236  \r
237 -    /* New terms allow user to search with folder: specification. */\r
238 -    _notmuch_message_gen_terms (message, "folder", directory);\r
239 -\r
240 +    _notmuch_message_add_folder_terms (message, directory);\r
241      _notmuch_message_add_path_terms (message, directory);\r
242  \r
243      talloc_free (local);\r
244 @@ -637,8 +684,6 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
245                                   const char *filename)\r
246  {\r
247      void *local = talloc_new (message);\r
248 -    const char *folder_prefix = _find_prefix ("folder");\r
249 -    char *zfolder_prefix = talloc_asprintf(local, "Z%s", folder_prefix);\r
250      char *direntry;\r
251      notmuch_private_status_t private_status;\r
252      notmuch_status_t status;\r
253 @@ -659,10 +704,7 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
254      /* Re-synchronize "folder:" and "path:" terms for this message. */\r
255  \r
256      /* Remove all "folder:" terms. */\r
257 -    _notmuch_message_remove_terms (message, folder_prefix);\r
258 -\r
259 -    /* Remove all "folder:" stemmed terms. */\r
260 -    _notmuch_message_remove_terms (message, zfolder_prefix);\r
261 +    _notmuch_message_remove_terms (message, _find_prefix ("folder"));\r
262  \r
263      /* Remove all "path:" terms. */\r
264      _notmuch_message_remove_terms (message, _find_prefix ("path"));\r
265 @@ -675,6 +717,22 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
266      return status;\r
267  }\r
268  \r
269 +/* Upgrade the "folder:" prefix from V1 to V2. */\r
270 +#define FOLDER_PREFIX_V1       "XFOLDER"\r
271 +#define ZFOLDER_PREFIX_V1      "Z" FOLDER_PREFIX_V1\r
272 +void\r
273 +_notmuch_message_upgrade_folder (notmuch_message_t *message)\r
274 +{\r
275 +    /* Remove all old "folder:" terms. */\r
276 +    _notmuch_message_remove_terms (message, FOLDER_PREFIX_V1);\r
277 +\r
278 +    /* Remove all old "folder:" stemmed terms. */\r
279 +    _notmuch_message_remove_terms (message, ZFOLDER_PREFIX_V1);\r
280 +\r
281 +    /* Add new boolean "folder:" and "path:" terms. */\r
282 +    _notmuch_message_add_directory_terms (message, message);\r
283 +}\r
284 +\r
285  char *\r
286  _notmuch_message_talloc_copy_data (notmuch_message_t *message)\r
287  {\r
288 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
289 index af185c7c5ba8..59eb2bc285a5 100644\r
290 --- a/lib/notmuch-private.h\r
291 +++ b/lib/notmuch-private.h\r
292 @@ -263,6 +263,9 @@ _notmuch_message_gen_terms (notmuch_message_t *message,\r
293  void\r
294  _notmuch_message_upgrade_filename_storage (notmuch_message_t *message);\r
295  \r
296 +void\r
297 +_notmuch_message_upgrade_folder (notmuch_message_t *message);\r
298 +\r
299  notmuch_status_t\r
300  _notmuch_message_add_filename (notmuch_message_t *message,\r
301                                const char *filename);\r
302 -- \r
303 1.8.5.3\r
304 \r