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 A4CE4431FC2
\r
6 for <notmuch@notmuchmail.org>; Thu, 9 Jan 2014 23:10:10 -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
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 5ll8-SHA9A3P for <notmuch@notmuchmail.org>;
\r
17 Thu, 9 Jan 2014 23:10:01 -0800 (PST)
\r
18 Received: from mail-ee0-f44.google.com (mail-ee0-f44.google.com
\r
19 [74.125.83.44]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client
\r
20 certificate requested) by olra.theworths.org (Postfix) with ESMTPS id
\r
21 70E7C431FBC for <notmuch@notmuchmail.org>; Thu, 9 Jan 2014 23:10:01 -0800
\r
23 Received: by mail-ee0-f44.google.com with SMTP id b57so1710091eek.31
\r
24 for <notmuch@notmuchmail.org>; Thu, 09 Jan 2014 23:10:00 -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=3FgORGMngT3wLdUYKi8bcXxYsruTf6a9yKVojvc8/vo=;
\r
30 b=f8HrP5XqD1PbO2YpvcRPNi9ms6NTLhL1aUOSJEWfK6EcYWhAUgvoFn+kOhhPeOnYS3
\r
31 9ckwYE0JYUOJ3yaeseulLnHMVsUwxRHXdWlVHz5iqwNrTv5x8MdWOwcHAolGIUHjjbQM
\r
32 1b9XhYhARz4/oFO1uF8rKJqNscgroUYKXyAW58Y3387CTn/qRZ70JCsIaNd2kqcVp0Re
\r
33 sLuaCq7rs3dgDtZqwsnzMj8qGMmwCW5fOi3TNMS9/nRqYDwxnOlGXu3TuwRIEIk5VITW
\r
34 WQ0EcLnfejMDV7F2ztSJT5IepV6m6a6lH6CzU5lF5ALYiQryOiN1Q2h0XbptYczxF8Ip
\r
37 ALoCoQmUrSsl3Iwe2SDOR2RsXMCN2wMICyS1wguyW1Oyr+08W0iLmlvieTclfs36s46TIvOMDT/J
\r
38 X-Received: by 10.15.45.67 with SMTP id a43mr5624820eew.17.1389305929624;
\r
39 Thu, 09 Jan 2014 14:18:49 -0800 (PST)
\r
40 Received: from localhost (dsl-hkibrasgw2-58c36f-91.dhcp.inet.fi.
\r
42 by mx.google.com with ESMTPSA id a51sm9382988eeh.8.2014.01.09.14.18.47
\r
43 for <multiple recipients>
\r
44 (version=TLSv1.2 cipher=RC4-SHA bits=128/128);
\r
45 Thu, 09 Jan 2014 14:18:49 -0800 (PST)
\r
46 From: Jani Nikula <jani@nikula.org>
\r
47 To: notmuch@notmuchmail.org
\r
48 Subject: [PATCH 1/5] lib: make folder: prefix literal
\r
49 Date: Fri, 10 Jan 2014 00:18:32 +0200
\r
51 <d735583dd1bb48a87530fe3d52a57abd4d17acb8.1389304779.git.jani@nikula.org>
\r
52 X-Mailer: git-send-email 1.8.5.2
\r
53 In-Reply-To: <cover.1389304779.git.jani@nikula.org>
\r
54 References: <cover.1389304779.git.jani@nikula.org>
\r
55 In-Reply-To: <cover.1389304779.git.jani@nikula.org>
\r
56 References: <cover.1389304779.git.jani@nikula.org>
\r
57 X-BeenThere: notmuch@notmuchmail.org
\r
58 X-Mailman-Version: 2.1.13
\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: Fri, 10 Jan 2014 07:10:10 -0000
\r
71 In xapian terms, convert folder: prefix from probabilistic to boolean
\r
72 prefix. This change constitutes a database change: bump the database
\r
73 version and add database upgrade support.
\r
75 lib/database.cc | 39 ++++++++++++-
\r
76 lib/message.cc | 154 +++++++++++++++++++++++++-------------------------
\r
77 lib/notmuch-private.h | 3 +
\r
78 3 files changed, 117 insertions(+), 79 deletions(-)
\r
80 diff --git a/lib/database.cc b/lib/database.cc
\r
81 index f395061..145fd66 100644
\r
82 --- a/lib/database.cc
\r
83 +++ b/lib/database.cc
\r
84 @@ -42,7 +42,7 @@ typedef struct {
\r
88 -#define NOTMUCH_DATABASE_VERSION 1
\r
89 +#define NOTMUCH_DATABASE_VERSION 2
\r
91 #define STRINGIFY(s) _SUB_STRINGIFY(s)
\r
92 #define _SUB_STRINGIFY(s) #s
\r
93 @@ -208,7 +208,8 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {
\r
99 + { "folder", "P" },
\r
102 static prefix_t PROBABILISTIC_PREFIX[]= {
\r
103 @@ -216,7 +217,6 @@ static prefix_t PROBABILISTIC_PREFIX[]= {
\r
105 { "attachment", "XATTACHMENT" },
\r
106 { "subject", "XSUBJECT"},
\r
107 - { "folder", "XFOLDER"}
\r
111 @@ -1167,6 +1167,39 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
\r
116 + * Prior to version 2, the "folder:" prefix was probabilistic and
\r
117 + * stemmed. Change it to the current boolean prefix.
\r
119 + if (version < 2) {
\r
120 + notmuch_query_t *query = notmuch_query_create (notmuch, "");
\r
121 + notmuch_messages_t *messages;
\r
122 + notmuch_message_t *message;
\r
125 + total = notmuch_query_count_messages (query);
\r
127 + for (messages = notmuch_query_search_messages (query);
\r
128 + notmuch_messages_valid (messages);
\r
129 + notmuch_messages_move_to_next (messages)) {
\r
130 + if (do_progress_notify) {
\r
131 + progress_notify (closure, (double) count / total);
\r
132 + do_progress_notify = 0;
\r
135 + message = notmuch_messages_get (messages);
\r
137 + _notmuch_message_upgrade_folder (message);
\r
138 + _notmuch_message_sync (message);
\r
140 + notmuch_message_destroy (message);
\r
145 + notmuch_query_destroy (query);
\r
148 db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));
\r
151 diff --git a/lib/message.cc b/lib/message.cc
\r
152 index 1b46379..500aa26 100644
\r
153 --- a/lib/message.cc
\r
154 +++ b/lib/message.cc
\r
155 @@ -505,89 +505,27 @@ _notmuch_message_add_filename (notmuch_message_t *message,
\r
156 _notmuch_message_add_term (message, "file-direntry", direntry);
\r
158 /* New terms allow user to search with folder: specification. */
\r
159 - _notmuch_message_gen_terms (message, "folder", directory);
\r
160 + _notmuch_message_add_term (message, "folder", directory);
\r
162 talloc_free (local);
\r
164 return NOTMUCH_STATUS_SUCCESS;
\r
167 -/* Remove a particular 'filename' from 'message'.
\r
169 - * This change will not be reflected in the database until the next
\r
170 - * call to _notmuch_message_sync.
\r
172 - * If this message still has other filenames, returns
\r
173 - * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID.
\r
175 - * Note: This function does not remove a document from the database,
\r
176 - * even if the specified filename is the only filename for this
\r
177 - * message. For that functionality, see
\r
178 - * _notmuch_database_remove_message. */
\r
180 -_notmuch_message_remove_filename (notmuch_message_t *message,
\r
181 - const char *filename)
\r
183 +_notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix)
\r
185 - const char *direntry_prefix = _find_prefix ("file-direntry");
\r
186 - int direntry_prefix_len = strlen (direntry_prefix);
\r
187 - const char *folder_prefix = _find_prefix ("folder");
\r
188 - int folder_prefix_len = strlen (folder_prefix);
\r
189 - void *local = talloc_new (message);
\r
190 - char *zfolder_prefix = talloc_asprintf(local, "Z%s", folder_prefix);
\r
191 - int zfolder_prefix_len = strlen (zfolder_prefix);
\r
193 - notmuch_private_status_t private_status;
\r
194 - notmuch_status_t status;
\r
195 - Xapian::TermIterator i, last;
\r
197 - status = _notmuch_database_filename_to_direntry (
\r
198 - local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
\r
199 - if (status || !direntry)
\r
201 + Xapian::TermIterator i;
\r
202 + size_t prefix_len = strlen (prefix);
\r
204 - /* Unlink this file from its parent directory. */
\r
205 - private_status = _notmuch_message_remove_term (message,
\r
206 - "file-direntry", direntry);
\r
207 - status = COERCE_STATUS (private_status,
\r
208 - "Unexpected error from _notmuch_message_remove_term");
\r
212 - /* Re-synchronize "folder:" terms for this message. This requires:
\r
213 - * 1. removing all "folder:" terms
\r
214 - * 2. removing all "folder:" stemmed terms
\r
215 - * 3. adding back terms for all remaining filenames of the message. */
\r
217 - /* 1. removing all "folder:" terms */
\r
219 i = message->doc.termlist_begin ();
\r
220 - i.skip_to (folder_prefix);
\r
221 + i.skip_to (prefix);
\r
223 /* Terminate loop when no terms remain with desired prefix. */
\r
224 if (i == message->doc.termlist_end () ||
\r
225 - strncmp ((*i).c_str (), folder_prefix, folder_prefix_len))
\r
227 + strncmp ((*i).c_str (), prefix, prefix_len))
\r
232 - message->doc.remove_term ((*i));
\r
233 - } catch (const Xapian::InvalidArgumentError) {
\r
234 - /* Ignore failure to remove non-existent term. */
\r
238 - /* 2. removing all "folder:" stemmed terms */
\r
240 - i = message->doc.termlist_begin ();
\r
241 - i.skip_to (zfolder_prefix);
\r
243 - /* Terminate loop when no terms remain with desired prefix. */
\r
244 - if (i == message->doc.termlist_end () ||
\r
245 - strncmp ((*i).c_str (), zfolder_prefix, zfolder_prefix_len))
\r
251 message->doc.remove_term ((*i));
\r
252 @@ -595,12 +533,18 @@ _notmuch_message_remove_filename (notmuch_message_t *message,
\r
253 /* Ignore failure to remove non-existent term. */
\r
258 - /* 3. adding back terms for all remaining filenames of the message. */
\r
259 - i = message->doc.termlist_begin ();
\r
260 - i.skip_to (direntry_prefix);
\r
261 +/* Add "folder:" terms for all filenames of the message. */
\r
262 +static notmuch_status_t
\r
263 +_notmuch_message_add_folder_terms (void *ctx, notmuch_message_t *message)
\r
265 + const char *direntry_prefix = _find_prefix ("file-direntry");
\r
266 + int direntry_prefix_len = strlen (direntry_prefix);
\r
267 + Xapian::TermIterator i = message->doc.termlist_begin ();
\r
268 + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
\r
270 - for (; i != message->doc.termlist_end (); i++) {
\r
271 + for (i.skip_to (direntry_prefix); i != message->doc.termlist_end (); i++) {
\r
272 unsigned int directory_id;
\r
273 const char *direntry, *directory;
\r
275 @@ -620,18 +564,76 @@ _notmuch_message_remove_filename (notmuch_message_t *message,
\r
276 if (colon == NULL || *colon != ':')
\r
277 INTERNAL_ERROR ("malformed direntry");
\r
279 - directory = _notmuch_database_get_directory_path (local,
\r
280 + directory = _notmuch_database_get_directory_path (ctx,
\r
283 - if (strlen (directory))
\r
284 - _notmuch_message_gen_terms (message, "folder", directory);
\r
285 + _notmuch_message_add_term (message, "folder", directory);
\r
291 +/* Remove a particular 'filename' from 'message'.
\r
293 + * This change will not be reflected in the database until the next
\r
294 + * call to _notmuch_message_sync.
\r
296 + * If this message still has other filenames, returns
\r
297 + * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID.
\r
299 + * Note: This function does not remove a document from the database,
\r
300 + * even if the specified filename is the only filename for this
\r
301 + * message. For that functionality, see
\r
302 + * _notmuch_database_remove_message. */
\r
304 +_notmuch_message_remove_filename (notmuch_message_t *message,
\r
305 + const char *filename)
\r
307 + void *local = talloc_new (message);
\r
309 + notmuch_private_status_t private_status;
\r
310 + notmuch_status_t status;
\r
312 + status = _notmuch_database_filename_to_direntry (
\r
313 + local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
\r
314 + if (status || !direntry)
\r
317 + /* Unlink this file from its parent directory. */
\r
318 + private_status = _notmuch_message_remove_term (message,
\r
319 + "file-direntry", direntry);
\r
320 + status = COERCE_STATUS (private_status,
\r
321 + "Unexpected error from _notmuch_message_remove_term");
\r
325 + /* Remove all "folder:" terms from the message. */
\r
326 + _notmuch_message_remove_terms (message, _find_prefix ("folder"));
\r
328 + /* Add back "folder:" terms for all remaining filenames of the message. */
\r
329 + status = _notmuch_message_add_folder_terms (local, message);
\r
331 talloc_free (local);
\r
336 +/* Upgrade the "folder:" prefix from V1 to V2. */
\r
337 +#define FOLDER_PREFIX_V1 "XFOLDER"
\r
338 +#define ZFOLDER_PREFIX_V1 "Z" FOLDER_PREFIX_V1
\r
340 +_notmuch_message_upgrade_folder (notmuch_message_t *message)
\r
342 + /* Remove all old "folder:" terms. */
\r
343 + _notmuch_message_remove_terms (message, FOLDER_PREFIX_V1);
\r
345 + /* Remove all old "folder:" stemmed terms. */
\r
346 + _notmuch_message_remove_terms (message, ZFOLDER_PREFIX_V1);
\r
348 + /* Add new boolean "folder:" terms. */
\r
349 + _notmuch_message_add_folder_terms (message, message);
\r
353 _notmuch_message_talloc_copy_data (notmuch_message_t *message)
\r
355 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
\r
356 index af185c7..59eb2bc 100644
\r
357 --- a/lib/notmuch-private.h
\r
358 +++ b/lib/notmuch-private.h
\r
359 @@ -263,6 +263,9 @@ _notmuch_message_gen_terms (notmuch_message_t *message,
\r
361 _notmuch_message_upgrade_filename_storage (notmuch_message_t *message);
\r
364 +_notmuch_message_upgrade_folder (notmuch_message_t *message);
\r
367 _notmuch_message_add_filename (notmuch_message_t *message,
\r
368 const char *filename);
\r