1 Return-Path: <aclements@csail.mit.edu>
\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 145E3431FC3
\r
6 for <notmuch@notmuchmail.org>; Mon, 6 Oct 2014 16:17:31 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id H5yCLonCmNsE for <notmuch@notmuchmail.org>;
\r
16 Mon, 6 Oct 2014 16:17:27 -0700 (PDT)
\r
17 Received: from dmz-mailsec-scanner-6.mit.edu (dmz-mailsec-scanner-6.mit.edu
\r
19 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id DD05A431FAF
\r
22 for <notmuch@notmuchmail.org>; Mon, 6 Oct 2014 16:17:26 -0700 (PDT)
\r
23 X-AuditID: 12074423-f799d6d00000337c-b9-543323062838
\r
24 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])
\r
25 (using TLS with cipher AES256-SHA (256/256 bits))
\r
26 (Client did not present a certificate)
\r
27 by dmz-mailsec-scanner-6.mit.edu (Symantec Messaging Gateway) with SMTP
\r
28 id 3C.5C.13180.60323345; Mon, 6 Oct 2014 19:17:26 -0400 (EDT)
\r
29 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])
\r
30 by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id s96NHPcd032090;
\r
31 Mon, 6 Oct 2014 19:17:25 -0400
\r
32 Received: from drake.dyndns.org ([12.185.136.2]) (authenticated bits=0)
\r
33 (User authenticated as amdragon@ATHENA.MIT.EDU)
\r
34 by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s96NHMbk014469
\r
35 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT);
\r
36 Mon, 6 Oct 2014 19:17:24 -0400
\r
37 Received: from amthrax by drake.dyndns.org with local (Exim 4.84)
\r
38 (envelope-from <aclements@csail.mit.edu>)
\r
39 id 1XbHWs-0001Jh-2O; Mon, 06 Oct 2014 17:17:22 -0600
\r
40 From: Austin Clements <aclements@csail.mit.edu>
\r
41 To: notmuch@notmuchmail.org
\r
42 Subject: [PATCH v2 07/12] lib: Internal support for querying and creating
\r
44 Date: Mon, 6 Oct 2014 17:17:13 -0600
\r
45 Message-Id: <1412637438-4821-8-git-send-email-aclements@csail.mit.edu>
\r
46 X-Mailer: git-send-email 2.1.0
\r
47 In-Reply-To: <1412637438-4821-1-git-send-email-aclements@csail.mit.edu>
\r
48 References: <1412637438-4821-1-git-send-email-aclements@csail.mit.edu>
\r
49 X-Brightmail-Tracker:
\r
50 H4sIAAAAAAAAA+NgFtrDIsWRmVeSWpSXmKPExsUixG6nrsumbBxiMKuLx+JGazejxfWbM5kd
\r
51 mDyerbrF7LHl0HvmAKYoLpuU1JzMstQifbsEroyujZIF0wwr2p9dYWpgfKzexcjJISFgIrH4
\r
52 3mk2CFtM4sK99UA2F4eQwGwmialz97BAOBsYJW4snQRWJSSwlEni8UlXiMQSRonnV++ygCTY
\r
53 BPQlVqydxApiiwhIS+y8OxvMZhawlLj6tZ0JxBYWiJDYduQQ2CAWAVWJ72cuMoPYvAJuEo0b
\r
54 VrNAnCEnsWH3f0YQm1PAXWLNlcmsEIvdJJ7/fMoygZF/ASPDKkbZlNwq3dzEzJzi1GTd4uTE
\r
55 vLzUIl0zvdzMEr3UlNJNjOBAclHewfjnoNIhRgEORiUe3ogdhiFCrIllxZW5hxglOZiURHnn
\r
56 sBuHCPEl5adUZiQWZ8QXleakFh9ilOBgVhLh5fptFCLEm5JYWZValA+TkuZgURLn3fSDL0RI
\r
57 ID2xJDU7NbUgtQgmK8PBoSTBa6wENFSwKDU9tSItM6cEIc3EwQkynAdo+D9FoBre4oLE3OLM
\r
58 dIj8KUZFKXHeYJCEAEgiozQPrhcW6a8YxYFeEeYNAlnBA0wScN2vgAYzAQ02naMPMrgkESEl
\r
59 1cB4vPoai4TkY/8Lk4S4pPesjO1+WjXdYYroc30WbtNscbfHl5r8v21U+KdzzDN7wbu+JZPU
\r
60 fLyCjl9dvvkQy98yuwV65tqO+zdfnrtUbUOph+f+OX4/X25u5Laf6VG+acksqWeRHOUBAa9X
\r
61 Teg1TXrVJpiiJrRx3saL3k17DkxS3FJ5Rm7HhBW3lFiKMxINtZiLihMBXwDlGc8CAAA=
\r
62 X-BeenThere: notmuch@notmuchmail.org
\r
63 X-Mailman-Version: 2.1.13
\r
65 List-Id: "Use and development of the notmuch mail system."
\r
66 <notmuch.notmuchmail.org>
\r
67 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
68 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
69 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
70 List-Post: <mailto:notmuch@notmuchmail.org>
\r
71 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
72 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
73 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
74 X-List-Received-Date: Mon, 06 Oct 2014 23:17:31 -0000
\r
76 From: Austin Clements <amdragon@mit.edu>
\r
78 This updates the message abstraction to support ghost messages: it
\r
79 adds a message flag that distinguishes regular messages from ghost
\r
80 messages, and an internal function for initializing a newly created
\r
81 (blank) message as a ghost message.
\r
83 lib/message.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--
\r
84 lib/notmuch-private.h | 4 ++++
\r
85 lib/notmuch.h | 9 ++++++++-
\r
86 3 files changed, 62 insertions(+), 3 deletions(-)
\r
88 diff --git a/lib/message.cc b/lib/message.cc
\r
89 index 55d2ff6..a7a13cc 100644
\r
90 --- a/lib/message.cc
\r
91 +++ b/lib/message.cc
\r
92 @@ -39,6 +39,9 @@ struct visible _notmuch_message {
\r
93 notmuch_message_file_t *message_file;
\r
94 notmuch_message_list_t *replies;
\r
95 unsigned long flags;
\r
96 + /* For flags that are initialized on-demand, lazy_flags indicates
\r
97 + * if each flag has been initialized. */
\r
98 + unsigned long lazy_flags;
\r
100 Xapian::Document doc;
\r
101 Xapian::termcount termpos;
\r
102 @@ -99,6 +102,7 @@ _notmuch_message_create_for_document (const void *talloc_owner,
\r
104 message->frozen = 0;
\r
105 message->flags = 0;
\r
106 + message->lazy_flags = 0;
\r
108 /* Each of these will be lazily created as needed. */
\r
109 message->message_id = NULL;
\r
110 @@ -192,7 +196,7 @@ _notmuch_message_create (const void *talloc_owner,
\r
112 * There is already a document with message ID 'message_id' in the
\r
113 * database. The returned message can be used to query/modify the
\r
115 + * document. The message may be a ghost message.
\r
117 * NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND:
\r
119 @@ -305,6 +309,7 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
\r
120 const char *thread_prefix = _find_prefix ("thread"),
\r
121 *tag_prefix = _find_prefix ("tag"),
\r
122 *id_prefix = _find_prefix ("id"),
\r
123 + *type_prefix = _find_prefix ("type"),
\r
124 *filename_prefix = _find_prefix ("file-direntry"),
\r
125 *replyto_prefix = _find_prefix ("replyto");
\r
127 @@ -337,10 +342,25 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
\r
128 message->message_id =
\r
129 _notmuch_message_get_term (message, i, end, id_prefix);
\r
131 + /* Get document type */
\r
132 + assert (strcmp (id_prefix, type_prefix) < 0);
\r
133 + if (! NOTMUCH_TEST_BIT (message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST)) {
\r
134 + i.skip_to (type_prefix);
\r
135 + /* "T" is the prefix "type" fields. See
\r
136 + * BOOLEAN_PREFIX_INTERNAL. */
\r
137 + if (*i == "Tmail")
\r
138 + NOTMUCH_CLEAR_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
\r
139 + else if (*i == "Tghost")
\r
140 + NOTMUCH_SET_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
\r
142 + INTERNAL_ERROR ("Message without type term");
\r
143 + NOTMUCH_SET_BIT (&message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST);
\r
146 /* Get filename list. Here we get only the terms. We lazily
\r
147 * expand them to full file names when needed in
\r
148 * _notmuch_message_ensure_filename_list. */
\r
149 - assert (strcmp (id_prefix, filename_prefix) < 0);
\r
150 + assert (strcmp (type_prefix, filename_prefix) < 0);
\r
151 if (!message->filename_term_list && !message->filename_list)
\r
152 message->filename_term_list =
\r
153 _notmuch_database_get_terms_with_prefix (message, i, end,
\r
154 @@ -371,6 +391,11 @@ _notmuch_message_invalidate_metadata (notmuch_message_t *message,
\r
155 message->tag_list = NULL;
\r
158 + if (strcmp ("type", prefix_name) == 0) {
\r
159 + NOTMUCH_CLEAR_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
\r
160 + NOTMUCH_CLEAR_BIT (&message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST);
\r
163 if (strcmp ("file-direntry", prefix_name) == 0) {
\r
164 talloc_free (message->filename_term_list);
\r
165 talloc_free (message->filename_list);
\r
166 @@ -869,6 +894,10 @@ notmuch_bool_t
\r
167 notmuch_message_get_flag (notmuch_message_t *message,
\r
168 notmuch_message_flag_t flag)
\r
170 + if (flag == NOTMUCH_MESSAGE_FLAG_GHOST &&
\r
171 + ! NOTMUCH_TEST_BIT (message->lazy_flags, flag))
\r
172 + _notmuch_message_ensure_metadata (message);
\r
174 return NOTMUCH_TEST_BIT (message->flags, flag);
\r
177 @@ -880,6 +909,7 @@ notmuch_message_set_flag (notmuch_message_t *message,
\r
178 NOTMUCH_SET_BIT (&message->flags, flag);
\r
180 NOTMUCH_CLEAR_BIT (&message->flags, flag);
\r
181 + NOTMUCH_SET_BIT (&message->lazy_flags, flag);
\r
185 @@ -989,6 +1019,24 @@ _notmuch_message_delete (notmuch_message_t *message)
\r
186 return NOTMUCH_STATUS_SUCCESS;
\r
189 +/* Transform a blank message into a ghost message. The caller must
\r
190 + * _notmuch_message_sync the message. */
\r
191 +notmuch_private_status_t
\r
192 +_notmuch_message_initialize_ghost (notmuch_message_t *message,
\r
193 + const char *thread_id)
\r
195 + notmuch_private_status_t status;
\r
197 + status = _notmuch_message_add_term (message, "type", "ghost");
\r
200 + status = _notmuch_message_add_term (message, "thread", thread_id);
\r
204 + return NOTMUCH_PRIVATE_STATUS_SUCCESS;
\r
207 /* Ensure that 'message' is not holding any file object open. Future
\r
208 * calls to various functions will still automatically open the
\r
209 * message file as needed.
\r
210 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
\r
211 index 7250291..2f43c1d 100644
\r
212 --- a/lib/notmuch-private.h
\r
213 +++ b/lib/notmuch-private.h
\r
214 @@ -308,6 +308,10 @@ _notmuch_message_sync (notmuch_message_t *message);
\r
216 _notmuch_message_delete (notmuch_message_t *message);
\r
218 +notmuch_private_status_t
\r
219 +_notmuch_message_initialize_ghost (notmuch_message_t *message,
\r
220 + const char *thread_id);
\r
223 _notmuch_message_close (notmuch_message_t *message);
\r
225 diff --git a/lib/notmuch.h b/lib/notmuch.h
\r
226 index dae0416..92594b9 100644
\r
227 --- a/lib/notmuch.h
\r
228 +++ b/lib/notmuch.h
\r
229 @@ -1221,7 +1221,14 @@ notmuch_message_get_filenames (notmuch_message_t *message);
\r
231 typedef enum _notmuch_message_flag {
\r
232 NOTMUCH_MESSAGE_FLAG_MATCH,
\r
233 - NOTMUCH_MESSAGE_FLAG_EXCLUDED
\r
234 + NOTMUCH_MESSAGE_FLAG_EXCLUDED,
\r
236 + /* This message is a "ghost message", meaning it has no filenames
\r
237 + * or content, but we know it exists because it was referenced by
\r
238 + * some other message. A ghost message has only a message ID and
\r
241 + NOTMUCH_MESSAGE_FLAG_GHOST,
\r
242 } notmuch_message_flag_t;
\r