Re: [PATCH 0/4] Allow specifying alternate names for addresses in other_email
[notmuch-archives.git] / 55 / a531851feeb9e2286999b3ce679e863f564ef9
1 Return-Path: <dkg@fifthhorseman.net>\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 arlo.cworth.org (Postfix) with ESMTP id DCDAB6DE035F\r
6  for <notmuch@notmuchmail.org>; Fri,  8 Apr 2016 18:55:32 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[AWL=0.000]\r
12  autolearn=disabled\r
13 Received: from arlo.cworth.org ([127.0.0.1])\r
14  by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
15  with ESMTP id mtrx5Qx8H29X for <notmuch@notmuchmail.org>;\r
16  Fri,  8 Apr 2016 18:55:24 -0700 (PDT)\r
17 Received: from che.mayfirst.org (che.mayfirst.org [209.234.253.108])\r
18  by arlo.cworth.org (Postfix) with ESMTP id 5C0176DE0319\r
19  for <notmuch@notmuchmail.org>; Fri,  8 Apr 2016 18:55:08 -0700 (PDT)\r
20 Received: from fifthhorseman.net (unknown [201.140.212.132])\r
21  by che.mayfirst.org (Postfix) with ESMTPSA id 333E710070\r
22  for <notmuch@notmuchmail.org>; Fri,  8 Apr 2016 21:55:06 -0400 (EDT)\r
23 Received: by fifthhorseman.net (Postfix, from userid 1000)\r
24  id 4F4291FF50; Fri,  8 Apr 2016 22:54:52 -0300 (ART)\r
25 From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
26 To: Notmuch Mail <notmuch@notmuchmail.org>\r
27 Subject: [PATCH v4 3/7] fix thread breakage via ghost-on-removal\r
28 Date: Fri,  8 Apr 2016 22:54:48 -0300\r
29 Message-Id: <1460166892-29721-3-git-send-email-dkg@fifthhorseman.net>\r
30 X-Mailer: git-send-email 2.8.0.rc3\r
31 In-Reply-To: <1460166892-29721-1-git-send-email-dkg@fifthhorseman.net>\r
32 References: <1459445693-3900-1-git-send-email-dkg@fifthhorseman.net>\r
33  <1460166892-29721-1-git-send-email-dkg@fifthhorseman.net>\r
34 X-BeenThere: notmuch@notmuchmail.org\r
35 X-Mailman-Version: 2.1.20\r
36 Precedence: list\r
37 List-Id: "Use and development of the notmuch mail system."\r
38  <notmuch.notmuchmail.org>\r
39 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
40  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
41 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
42 List-Post: <mailto:notmuch@notmuchmail.org>\r
43 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
44 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
45  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
46 X-List-Received-Date: Sat, 09 Apr 2016 01:55:33 -0000\r
47 \r
48 implement ghost-on-removal, the solution to T590-thread-breakage.sh\r
49 that just adds a ghost message after removing each message.\r
50 \r
51 It leaks information about whether we've ever seen a given message id,\r
52 but it's a fairly simple implementation.\r
53 \r
54 Note that _resolve_message_id_to_thread_id already introduces new\r
55 message_ids to the database, so i think just searching for a given\r
56 message ID may introduce the same metadata leakage.\r
57 ---\r
58  lib/message.cc               | 30 +++++++++++++++++++++++++++---\r
59  test/T590-thread-breakage.sh | 25 ++++++++++++-------------\r
60  2 files changed, 39 insertions(+), 16 deletions(-)\r
61 \r
62 diff --git a/lib/message.cc b/lib/message.cc\r
63 index 8d72ea2..435b78a 100644\r
64 --- a/lib/message.cc\r
65 +++ b/lib/message.cc\r
66 @@ -1037,20 +1037,44 @@ _notmuch_message_sync (notmuch_message_t *message)\r
67      message->modified = FALSE;\r
68  }\r
69  \r
70 -/* Delete a message document from the database. */\r
71 +/* Delete a message document from the database, leaving a ghost\r
72 + * message in its place */\r
73  notmuch_status_t\r
74  _notmuch_message_delete (notmuch_message_t *message)\r
75  {\r
76      notmuch_status_t status;\r
77      Xapian::WritableDatabase *db;\r
78 +    const char *mid, *tid;\r
79 +    notmuch_message_t *ghost;\r
80 +    notmuch_private_status_t private_status;\r
81 +    notmuch_database_t *notmuch;\r
82 +           \r
83 +    mid = notmuch_message_get_message_id (message);\r
84 +    tid = notmuch_message_get_thread_id (message);\r
85 +    notmuch = message->notmuch;\r
86  \r
87      status = _notmuch_database_ensure_writable (message->notmuch);\r
88      if (status)\r
89         return status;\r
90  \r
91 -    db = static_cast <Xapian::WritableDatabase *> (message->notmuch->xapian_db);\r
92 +    db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);\r
93      db->delete_document (message->doc_id);\r
94 -    return NOTMUCH_STATUS_SUCCESS;\r
95 +           \r
96 +    /* and reintroduce a ghost in its place */\r
97 +    ghost = _notmuch_message_create_for_message_id (notmuch, mid, &private_status);\r
98 +    if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {\r
99 +       private_status = _notmuch_message_initialize_ghost (ghost, tid);\r
100 +       if (! private_status)\r
101 +           _notmuch_message_sync (ghost);\r
102 +    } else if (private_status == NOTMUCH_PRIVATE_STATUS_SUCCESS) {\r
103 +       /* this is deeply weird, and we should not have gotten into\r
104 +          this state.  is there a better error message to return\r
105 +          here? */\r
106 +       return NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;\r
107 +    }\r
108 +\r
109 +    notmuch_message_destroy (ghost);\r
110 +    return COERCE_STATUS (private_status, "Error converting to ghost message");\r
111  }\r
112  \r
113  /* Transform a blank message into a ghost message.  The caller must\r
114 diff --git a/test/T590-thread-breakage.sh b/test/T590-thread-breakage.sh\r
115 index 2b933f6..81f27db 100755\r
116 --- a/test/T590-thread-breakage.sh\r
117 +++ b/test/T590-thread-breakage.sh\r
118 @@ -96,20 +96,11 @@ notmuch new >/dev/null\r
119  test_thread_count 1 'First message removed: still only one thread'\r
120  test_content_count apple 0\r
121  test_content_count banana 1\r
122 -test_begin_subtest 'should be one ghost after first message removed'\r
123 -test_subtest_known_broken\r
124 -ghosts=$(../ghost-report ${MAIL_DIR}/.notmuch/xapian)\r
125 -test_expect_equal "$ghosts" "1"\r
126 +test_ghost_count 1 'should be one ghost after first message removed'\r
127  \r
128  message_a\r
129  notmuch new >/dev/null\r
130 -# this is known to fail (it shows 2 threads) because no "ghost\r
131 -# message" was created for message A when it was removed from the\r
132 -# index, despite message B still pointing to it.\r
133 -test_begin_subtest 'First message reappears: should return to the same thread'\r
134 -test_subtest_known_broken\r
135 -count=$(notmuch count --output=threads)\r
136 -test_expect_equal "$count" "1"\r
137 +test_thread_count 1 'First message reappears: should return to the same thread'\r
138  test_content_count apple 1\r
139  test_content_count banana 1\r
140  test_ghost_count 0\r
141 @@ -119,13 +110,21 @@ notmuch new >/dev/null\r
142  test_thread_count 1 'Removing second message: still only one thread'\r
143  test_content_count apple 1\r
144  test_content_count banana 0\r
145 -test_ghost_count 0 'No ghosts should remain after deletion of second message'\r
146 +test_begin_subtest 'No ghosts should remain after deletion of second message'\r
147 +# this is known to fail; we are leaking ghost messages deliberately\r
148 +test_subtest_known_broken\r
149 +ghosts=$(../ghost-report ${MAIL_DIR}/.notmuch/xapian)\r
150 +test_expect_equal "$ghosts" "0"\r
151  \r
152  rm -f ${MAIL_DIR}/cur/a\r
153  notmuch new >/dev/null\r
154  test_thread_count 0 'All messages gone: no threads'\r
155  test_content_count apple 0\r
156  test_content_count banana 0\r
157 -test_ghost_count 0\r
158 +test_begin_subtest 'No ghosts should remain after full thread deletion'\r
159 +# this is known to fail; we are leaking ghost messages deliberately\r
160 +test_subtest_known_broken\r
161 +ghosts=$(../ghost-report ${MAIL_DIR}/.notmuch/xapian)\r
162 +test_expect_equal "$ghosts" "0"\r
163  \r
164  test_done\r
165 -- \r
166 2.8.0.rc3\r
167 \r