[PATCH] WIP: remove all non-prefixed-terms (and stemmed versions)
[notmuch-archives.git] / 93 / 06ffe85afcb0b296b5e729df3e45120beed24c
1 Return-Path: <bremner@tesseract.cs.unb.ca>\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 CCD876DE81BA\r
6  for <notmuch@notmuchmail.org>; Sun, 14 Aug 2016 16:41:53 -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.001\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.001 tagged_above=-999 required=5\r
12  tests=[AWL=-0.002, HEADER_FROM_DIFFERENT_DOMAINS=0.001]\r
13  autolearn=disabled\r
14 Received: from arlo.cworth.org ([127.0.0.1])\r
15  by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
16  with ESMTP id sAEvMdRXwP9Q for <notmuch@notmuchmail.org>;\r
17  Sun, 14 Aug 2016 16:41:45 -0700 (PDT)\r
18 Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197])\r
19  by arlo.cworth.org (Postfix) with ESMTPS id F08A56DEAEF3\r
20  for <notmuch@notmuchmail.org>; Sun, 14 Aug 2016 16:24:10 -0700 (PDT)\r
21 Received: from remotemail by fethera.tethera.net with local (Exim 4.84_2)\r
22  (envelope-from <bremner@tesseract.cs.unb.ca>)\r
23  id 1bZ4lN-0005Jc-Ol; Sun, 14 Aug 2016 19:24:17 -0400\r
24 Received: (nullmailer pid 9958 invoked by uid 1000);\r
25  Sun, 14 Aug 2016 12:43:42 -0000\r
26 From: David Bremner <david@tethera.net>\r
27 To: Daniel Kahn Gillmor <dkg@fifthhorseman.net>,\r
28  Notmuch Mail <notmuch@notmuchmail.org>\r
29 Subject: [PATCH] WIP: remove all non-prefixed-terms (and stemmed versions)\r
30 Date: Sun, 14 Aug 2016 21:43:18 +0900\r
31 Message-Id: <1471178598-9639-1-git-send-email-david@tethera.net>\r
32 X-Mailer: git-send-email 2.8.1\r
33 In-Reply-To: <1467970047-8013-16-git-send-email-dkg@fifthhorseman.net>\r
34 References: <1467970047-8013-16-git-send-email-dkg@fifthhorseman.net>\r
35 X-BeenThere: notmuch@notmuchmail.org\r
36 X-Mailman-Version: 2.1.20\r
37 Precedence: list\r
38 List-Id: "Use and development of the notmuch mail system."\r
39  <notmuch.notmuchmail.org>\r
40 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
41  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
42 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
43 List-Post: <mailto:notmuch@notmuchmail.org>\r
44 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
45 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
46  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
47 X-List-Received-Date: Sun, 14 Aug 2016 23:41:54 -0000\r
48 \r
49 The testing here is not really suitable for production, since we export\r
50 a function just for testing.  It would be possible to modify the test\r
51 framework to test functions in notmuch-private.h, but this was the quick\r
52 and dirty solution.\r
53 ---\r
54 \r
55 dkg wrote:\r
56 \r
57 > I could find no way to distinguish terms which were added during\r
58 >  indexing of the message body from other terms associated with the\r
59 >  document.\r
60 \r
61 I think this does the trick. If it makes sense, I can polish it\r
62 up. I'd appreciate any ideas about the right way to manage the\r
63 testing.  We could either modify the test framework to test internal\r
64 functions, or continue on testing only exported functions and the CLI.\r
65 \r
66  lib/message.cc             | 33 ++++++++++++++++++++++\r
67  lib/notmuch-private.h      |  2 ++\r
68  lib/notmuch.h              |  4 +++\r
69  test/T650-message-terms.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++\r
70  4 files changed, 109 insertions(+)\r
71  create mode 100755 test/T650-message-terms.sh\r
72 \r
73 diff --git a/lib/message.cc b/lib/message.cc\r
74 index 9d3e807..9a9845a 100644\r
75 --- a/lib/message.cc\r
76 +++ b/lib/message.cc\r
77 @@ -577,6 +577,39 @@ _notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix)\r
78      }\r
79  }\r
80  \r
81 +void notmuch_test_clear_terms(notmuch_message_t *message) {\r
82 +    _notmuch_message_remove_unprefixed_terms (message);\r
83 +    _notmuch_message_sync (message);\r
84 +}\r
85 +void\r
86 +_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message)\r
87 +{\r
88 +    Xapian::TermIterator i;\r
89 +\r
90 +    for (i = message->doc.termlist_begin ();\r
91 +        i != message->doc.termlist_end () &&\r
92 +            ((*i).c_str ()[0] < 'A');\r
93 +            i++) {\r
94 +       try {\r
95 +           message->doc.remove_term ((*i));\r
96 +           message->modified = TRUE;\r
97 +       } catch (const Xapian::InvalidArgumentError) {\r
98 +           /* Ignore failure to remove non-existent term. */\r
99 +       }\r
100 +    }\r
101 +\r
102 +    /* We want to remove stemmed terms, but only those not from a\r
103 +       prefixed term */\r
104 +    for (i.skip_to ("Z["); i != message->doc.termlist_end (); i++) {\r
105 +       try {\r
106 +           message->doc.remove_term ((*i));\r
107 +           message->modified = TRUE;\r
108 +       } catch (const Xapian::InvalidArgumentError) {\r
109 +           /* Ignore failure to remove non-existent term. */\r
110 +       }\r
111 +    }\r
112 +}\r
113 +\r
114  /* Return true if p points at "new" or "cur". */\r
115  static bool is_maildir (const char *p)\r
116  {\r
117 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
118 index 65f7ead..646fc78 100644\r
119 --- a/lib/notmuch-private.h\r
120 +++ b/lib/notmuch-private.h\r
121 @@ -502,6 +502,8 @@ _notmuch_message_add_reply (notmuch_message_t *message,\r
122  notmuch_database_t *\r
123  _notmuch_message_database (notmuch_message_t *message);\r
124  \r
125 +void\r
126 +_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message);\r
127  /* sha1.c */\r
128  \r
129  char *\r
130 diff --git a/lib/notmuch.h b/lib/notmuch.h\r
131 index e03a05d..e964b1a 100644\r
132 --- a/lib/notmuch.h\r
133 +++ b/lib/notmuch.h\r
134 @@ -1658,6 +1658,10 @@ notmuch_message_thaw (notmuch_message_t *message);\r
135  void\r
136  notmuch_message_destroy (notmuch_message_t *message);\r
137  \r
138 +/* for testing */\r
139 +\r
140 +void\r
141 +notmuch_test_clear_terms(notmuch_message_t *message);\r
142  /**\r
143   * @name Message Properties\r
144   *\r
145 diff --git a/test/T650-message-terms.sh b/test/T650-message-terms.sh\r
146 new file mode 100755\r
147 index 0000000..553e95b\r
148 --- /dev/null\r
149 +++ b/test/T650-message-terms.sh\r
150 @@ -0,0 +1,70 @@\r
151 +#!/usr/bin/env bash\r
152 +test_description="message API"\r
153 +\r
154 +. ./test-lib.sh || exit 1\r
155 +\r
156 +add_email_corpus\r
157 +\r
158 +cat <<EOF > c_head\r
159 +#include <stdio.h>\r
160 +#include <string.h>\r
161 +#include <stdlib.h>\r
162 +#include <talloc.h>\r
163 +#include <notmuch-test.h>\r
164 +\r
165 +int main (int argc, char** argv)\r
166 +{\r
167 +   notmuch_database_t *db;\r
168 +   notmuch_message_t *message = NULL;\r
169 +   const char *val;\r
170 +   notmuch_status_t stat;\r
171 +\r
172 +   EXPECT0(notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db));\r
173 +   EXPECT0(notmuch_database_find_message(db, "4EFC743A.3060609@april.org", &message));\r
174 +   if (message == NULL) {\r
175 +       fprintf (stderr, "unable to find message");\r
176 +       exit (1);\r
177 +   }\r
178 +EOF\r
179 +\r
180 +cat <<EOF > c_tail\r
181 +   EXPECT0(notmuch_database_destroy(db));\r
182 +}\r
183 +EOF\r
184 +\r
185 +add_email_corpus\r
186 +\r
187 +test_begin_subtest "check unique term"\r
188 +byid=$(notmuch count id:4EFC743A.3060609@april.org)\r
189 +byterm=$(notmuch count Boulogne)\r
190 +test_expect_equal "$byid" "$byterm"\r
191 +\r
192 +xapian-delve -1 -a ${MAIL_DIR}/.notmuch/xapian > BEFORE\r
193 +\r
194 +test_begin_subtest "clear non-prefixed terms from message"\r
195 +cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}\r
196 +{\r
197 +notmuch_test_clear_terms(message);\r
198 +}\r
199 +EOF\r
200 +byterm=$(notmuch count Boulogne)\r
201 +test_expect_equal 0 "$byterm"\r
202 +\r
203 +test_begin_subtest "check removed terms"\r
204 +xapian-delve -1 -a ${MAIL_DIR}/.notmuch/xapian > AFTER\r
205 +comm -2 -3 BEFORE AFTER | egrep '^Z?a' > REMOVED\r
206 +cat <<EOF > EXPECTED\r
207 +Zallan\r
208 +Zarch\r
209 +Zarch_packaging_standard\r
210 +Zarchlinux\r
211 +Zaur\r
212 +allan\r
213 +arch\r
214 +arch_packaging_standards\r
215 +archlinux\r
216 +aur\r
217 +EOF\r
218 +test_expect_equal_file EXPECTED REMOVED\r
219 +\r
220 +test_done\r
221 -- \r
222 2.8.1\r
223 \r