database error
[notmuch-archives.git] / 8e / f4bde6970b50310f70bcd58ecafb77aa8f1998
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 235EA6DE1778\r
6  for <notmuch@notmuchmail.org>; Fri,  5 Jun 2015 10:30:59 -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.239\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0.239 tagged_above=-999 required=5 tests=[AWL=0.229, \r
12  T_HEADER_FROM_DIFFERENT_DOMAINS=0.01] 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 YKAsOXzskGOw for <notmuch@notmuchmail.org>;\r
16  Fri,  5 Jun 2015 10:30:57 -0700 (PDT)\r
17 Received: from mx.xen14.node3324.gplhost.com (gitolite.debian.net\r
18  [87.98.215.224])\r
19  by arlo.cworth.org (Postfix) with ESMTPS id 284546DE179F\r
20  for <notmuch@notmuchmail.org>; Fri,  5 Jun 2015 10:30:57 -0700 (PDT)\r
21 Received: from remotemail by mx.xen14.node3324.gplhost.com with local (Exim\r
22  4.80) (envelope-from <bremner@tesseract.cs.unb.ca>)\r
23  id 1Z0vRe-0002nz-Th; Fri, 05 Jun 2015 17:30:14 +0000\r
24 Received: (nullmailer pid 24256 invoked by uid 1000); Fri, 05 Jun 2015\r
25  17:28:42 -0000\r
26 From: David Bremner <david@tethera.net>\r
27 To: notmuch@notmuchmail.org\r
28 Subject: [PATCH 5/6] cli: add global option "--db-revision"\r
29 Date: Fri,  5 Jun 2015 19:28:37 +0200\r
30 Message-Id: <1433525318-23756-6-git-send-email-david@tethera.net>\r
31 X-Mailer: git-send-email 2.1.4\r
32 In-Reply-To: <1433525318-23756-1-git-send-email-david@tethera.net>\r
33 References: <1432936375-astroid-4-0i1n6yczs2-1520@strange>\r
34  <1433525318-23756-1-git-send-email-david@tethera.net>\r
35 X-BeenThere: notmuch@notmuchmail.org\r
36 X-Mailman-Version: 2.1.18\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: <http://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: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
46  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
47 X-List-Received-Date: Fri, 05 Jun 2015 17:30:59 -0000\r
48 \r
49 The function notmuch_exit_if_unmatched_db_revision is split from\r
50 notmuch_process_shared_options because it needs an open notmuch\r
51 database.\r
52 ---\r
53  doc/man1/notmuch.rst           | 10 ++++++++--\r
54  notmuch-client.h               |  4 ++++\r
55  notmuch-compact.c              |  4 ++++\r
56  notmuch-config.c               |  4 ++++\r
57  notmuch-count.c                |  2 ++\r
58  notmuch-dump.c                 |  2 ++\r
59  notmuch-insert.c               |  2 ++\r
60  notmuch-new.c                  |  3 ++-\r
61  notmuch-reply.c                |  2 ++\r
62  notmuch-restore.c              |  2 ++\r
63  notmuch-search.c               |  2 ++\r
64  notmuch-setup.c                |  4 ++++\r
65  notmuch-show.c                 |  2 ++\r
66  notmuch-tag.c                  |  2 ++\r
67  notmuch.c                      | 18 ++++++++++++++++++\r
68  test/T570-revision-tracking.sh | 26 ++++++++++++++++++++++++++\r
69  test/random-corpus.c           |  2 ++\r
70  17 files changed, 88 insertions(+), 3 deletions(-)\r
71 \r
72 diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst\r
73 index ae0461a..b3f75a4 100644\r
74 --- a/doc/man1/notmuch.rst\r
75 +++ b/doc/man1/notmuch.rst\r
76 @@ -49,9 +49,15 @@ Supported global options for ``notmuch`` include\r
77          Specify the configuration file to use. This overrides any\r
78          configuration file specified by ${NOTMUCH\_CONFIG}.\r
79  \r
80 +    ``--db-revision=UUID``\r
81 +       Enforce that the database revision is UUID. This is useful to\r
82 +       detect rollover in modification counts on messages. You can\r
83 +       find this UUID in the first column of output from\r
84 +       ``notmuch count --output=modifications``\r
85 +\r
86  All global options except ``--config`` can also be specified after the\r
87 -command. For example, ``notmuch subcommand --version`` is equivalent to\r
88 -``notmuch --version subcommand``.\r
89 +command. For example, ``notmuch subcommand --db-revision`` is\r
90 +equivalent to ``notmuch --db-revision subcommand``.\r
91  \r
92  COMMANDS\r
93  ========\r
94 diff --git a/notmuch-client.h b/notmuch-client.h\r
95 index 78680aa..d3fab21 100644\r
96 --- a/notmuch-client.h\r
97 +++ b/notmuch-client.h\r
98 @@ -466,7 +466,11 @@ notmuch_database_dump (notmuch_database_t *notmuch,\r
99                        notmuch_bool_t gzip_output);\r
100  \r
101  #include "command-line-arguments.h"\r
102 +\r
103 +extern char *notmuch_requested_db_revision;\r
104  extern const notmuch_opt_desc_t  notmuch_shared_options [];\r
105 +void notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch);\r
106 +\r
107  void notmuch_process_shared_options (const char* subcommand_name);\r
108  int notmuch_minimal_options (const char* subcommand_name,\r
109                              int argc, char **argv);\r
110 diff --git a/notmuch-compact.c b/notmuch-compact.c\r
111 index 5be551d..3da4bfb 100644\r
112 --- a/notmuch-compact.c\r
113 +++ b/notmuch-compact.c\r
114 @@ -46,6 +46,10 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])\r
115      if (opt_index < 0)\r
116         return EXIT_FAILURE;\r
117  \r
118 +    if (notmuch_requested_db_revision)\r
119 +       fprintf (stderr, "Warning: ignoring --db-revision=%s\n",\r
120 +                notmuch_requested_db_revision);\r
121 +\r
122      notmuch_process_shared_options (argv[0]);\r
123  \r
124      if (! quiet)\r
125 diff --git a/notmuch-config.c b/notmuch-config.c\r
126 index 9348278..f1826e4 100644\r
127 --- a/notmuch-config.c\r
128 +++ b/notmuch-config.c\r
129 @@ -878,6 +878,10 @@ notmuch_config_command (notmuch_config_t *config, int argc, char *argv[])\r
130      if (opt_index < 0)\r
131         return EXIT_FAILURE;\r
132  \r
133 +    if (notmuch_requested_db_revision)\r
134 +       fprintf (stderr, "Warning: ignoring --db-revision=%s\n",\r
135 +                notmuch_requested_db_revision);\r
136 +\r
137      /* skip at least subcommand argument */\r
138      argc-= opt_index;\r
139      argv+= opt_index;\r
140 diff --git a/notmuch-count.c b/notmuch-count.c\r
141 index 7c61ccb..dda85b5 100644\r
142 --- a/notmuch-count.c\r
143 +++ b/notmuch-count.c\r
144 @@ -191,6 +191,8 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])\r
145                                NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
146         return EXIT_FAILURE;\r
147  \r
148 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
149 +\r
150      query_str = query_string_from_args (config, argc-opt_index, argv+opt_index);\r
151      if (query_str == NULL) {\r
152         fprintf (stderr, "Out of memory.\n");\r
153 diff --git a/notmuch-dump.c b/notmuch-dump.c\r
154 index fab22bd..9c0b82d 100644\r
155 --- a/notmuch-dump.c\r
156 +++ b/notmuch-dump.c\r
157 @@ -215,6 +215,8 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])\r
158                                NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
159         return EXIT_FAILURE;\r
160  \r
161 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
162 +\r
163      char *output_file_name = NULL;\r
164      int opt_index;\r
165  \r
166 diff --git a/notmuch-insert.c b/notmuch-insert.c\r
167 index c277d62..42d346f 100644\r
168 --- a/notmuch-insert.c\r
169 +++ b/notmuch-insert.c\r
170 @@ -536,6 +536,8 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])\r
171                                NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
172         return EXIT_FAILURE;\r
173  \r
174 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
175 +\r
176      /* Write the message to the Maildir new directory. */\r
177      newpath = maildir_write_new (config, STDIN_FILENO, maildir);\r
178      if (! newpath) {\r
179 diff --git a/notmuch-new.c b/notmuch-new.c\r
180 index 8ff1ade..2064a86 100644\r
181 --- a/notmuch-new.c\r
182 +++ b/notmuch-new.c\r
183 @@ -995,10 +995,11 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])\r
184                 fputs (status_string, stderr);\r
185                 free (status_string);\r
186             }\r
187 -\r
188             return EXIT_FAILURE;\r
189         }\r
190  \r
191 +       notmuch_exit_if_unmatched_db_revision (notmuch);\r
192 +\r
193         if (notmuch_database_needs_upgrade (notmuch)) {\r
194             time_t now = time (NULL);\r
195             struct tm *gm_time = gmtime (&now);\r
196 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
197 index 4464741..52e0d9b 100644\r
198 --- a/notmuch-reply.c\r
199 +++ b/notmuch-reply.c\r
200 @@ -831,6 +831,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])\r
201                                NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
202         return EXIT_FAILURE;\r
203  \r
204 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
205 +\r
206      query = notmuch_query_create (notmuch, query_string);\r
207      if (query == NULL) {\r
208         fprintf (stderr, "Out of memory\n");\r
209 diff --git a/notmuch-restore.c b/notmuch-restore.c\r
210 index 2a534dc..3e96aa8 100644\r
211 --- a/notmuch-restore.c\r
212 +++ b/notmuch-restore.c\r
213 @@ -165,6 +165,8 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])\r
214      }\r
215  \r
216      notmuch_process_shared_options (argv[0]);\r
217 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
218 +\r
219      name_for_error = input_file_name ? input_file_name : "stdin";\r
220  \r
221      if (! accumulate)\r
222 diff --git a/notmuch-search.c b/notmuch-search.c\r
223 index b89a17e..919837c 100644\r
224 --- a/notmuch-search.c\r
225 +++ b/notmuch-search.c\r
226 @@ -583,6 +583,8 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar\r
227         return EXIT_FAILURE;\r
228      }\r
229  \r
230 +    notmuch_exit_if_unmatched_db_revision (ctx->notmuch);\r
231 +\r
232      query_str = query_string_from_args (ctx->notmuch, argc, argv);\r
233      if (query_str == NULL) {\r
234         fprintf (stderr, "Out of memory.\n");\r
235 diff --git a/notmuch-setup.c b/notmuch-setup.c\r
236 index 7dd5822..dffda81 100644\r
237 --- a/notmuch-setup.c\r
238 +++ b/notmuch-setup.c\r
239 @@ -148,6 +148,10 @@ notmuch_setup_command (notmuch_config_t *config,\r
240      if (notmuch_minimal_options ("setup", argc, argv) < 0)\r
241         return EXIT_FAILURE;\r
242  \r
243 +    if (notmuch_requested_db_revision)\r
244 +       fprintf (stderr, "Warning: ignoring --db-revision=%s\n",\r
245 +                notmuch_requested_db_revision);\r
246 +\r
247      if (notmuch_config_is_new (config))\r
248         welcome_message_pre_setup ();\r
249  \r
250 diff --git a/notmuch-show.c b/notmuch-show.c\r
251 index b80933a..2535c8c 100644\r
252 --- a/notmuch-show.c\r
253 +++ b/notmuch-show.c\r
254 @@ -1213,6 +1213,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])\r
255                                NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))\r
256         return EXIT_FAILURE;\r
257  \r
258 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
259 +\r
260      query = notmuch_query_create (notmuch, query_string);\r
261      if (query == NULL) {\r
262         fprintf (stderr, "Out of memory\n");\r
263 diff --git a/notmuch-tag.c b/notmuch-tag.c\r
264 index 38d99aa..22446fe 100644\r
265 --- a/notmuch-tag.c\r
266 +++ b/notmuch-tag.c\r
267 @@ -261,6 +261,8 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])\r
268                                NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))\r
269         return EXIT_FAILURE;\r
270  \r
271 +    notmuch_exit_if_unmatched_db_revision (notmuch);\r
272 +\r
273      if (notmuch_config_get_maildir_synchronize_flags (config))\r
274         tag_flags |= TAG_FLAG_MAILDIR_SYNC;\r
275  \r
276 diff --git a/notmuch.c b/notmuch.c\r
277 index c528dce..fab737c 100644\r
278 --- a/notmuch.c\r
279 +++ b/notmuch.c\r
280 @@ -47,10 +47,12 @@ static int\r
281  _help_for (const char *topic);\r
282  \r
283  static notmuch_bool_t print_version = FALSE, print_help = FALSE;\r
284 +char *notmuch_requested_db_revision = NULL;\r
285  \r
286  const notmuch_opt_desc_t notmuch_shared_options [] = {\r
287      { NOTMUCH_OPT_BOOLEAN, &print_version, "version", 'v', 0 },\r
288      { NOTMUCH_OPT_BOOLEAN, &print_help, "help", 'h', 0 },\r
289 +    { NOTMUCH_OPT_STRING, &notmuch_requested_db_revision, "db-revision", 'd', 0 },\r
290      {0, 0, 0, 0, 0}\r
291  };\r
292  \r
293 @@ -218,6 +220,22 @@ be supported in the future.\n", notmuch_format_version);\r
294      }\r
295  }\r
296  \r
297 +void\r
298 +notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch)\r
299 +{\r
300 +    const char *uuid = NULL;\r
301 +\r
302 +    if (!notmuch_requested_db_revision)\r
303 +       return;\r
304 +    IGNORE_RESULT (notmuch_database_get_revision (notmuch, &uuid));\r
305 +\r
306 +    if (strcmp (notmuch_requested_db_revision, uuid) != 0){\r
307 +       fprintf (stderr, "Error: requested database revision %s does not match %s\n",\r
308 +                notmuch_requested_db_revision, uuid);\r
309 +       exit (1);\r
310 +    }\r
311 +}\r
312 +\r
313  static void\r
314  exec_man (const char *page)\r
315  {\r
316 diff --git a/test/T570-revision-tracking.sh b/test/T570-revision-tracking.sh\r
317 index 062fd59..bb09bf6 100755\r
318 --- a/test/T570-revision-tracking.sh\r
319 +++ b/test/T570-revision-tracking.sh\r
320 @@ -46,4 +46,30 @@ notmuch tag +a-random-tag-8743632 '*'\r
321  after=$(notmuch count --output=modifications '*' | cut -f2)\r
322  result=$(($before < $after))\r
323  test_expect_equal 1 ${result}\r
324 +\r
325 +notmuch count --output=modifications '*' | cut -f1 > UUID\r
326 +\r
327 +test_expect_success 'search succeeds with correct db revision' \\r
328 +                   "notmuch search --db-revision=$(cat UUID) '*'"\r
329 +\r
330 +test_expect_success 'db-revision works as global option ' \\r
331 +                   "notmuch --db-revision=$(cat UUID) search '*'"\r
332 +\r
333 +test_expect_code 1 'db-revision works as global option II' \\r
334 +                   "notmuch --db-revision=this-is-no-uuid search '*'"\r
335 +\r
336 +test_expect_code 1 'search fails with incorrect db revision' \\r
337 +                "notmuch search --db-revision=this-is-no-uuid '*'"\r
338 +\r
339 +test_expect_success 'show succeeds with correct db revision' \\r
340 +                   "notmuch show --db-revision=$(cat UUID) '*'"\r
341 +\r
342 +test_expect_code 1 'show fails with incorrect db revision' \\r
343 +                "notmuch show --db-revision=this-is-no-uuid '*'"\r
344 +\r
345 +test_expect_success 'tag succeeds with correct db revision' \\r
346 +                   "notmuch tag --db-revision=$(cat UUID) +test '*'"\r
347 +\r
348 +test_expect_code 1 'tag fails with incorrect db revision' \\r
349 +                "notmuch show --db-revision=this-is-no-uuid '*' +test2"\r
350  test_done\r
351 diff --git a/test/random-corpus.c b/test/random-corpus.c\r
352 index b377eb4..542b453 100644\r
353 --- a/test/random-corpus.c\r
354 +++ b/test/random-corpus.c\r
355 @@ -119,6 +119,8 @@ const notmuch_opt_desc_t notmuch_shared_options[] = {\r
356         { 0, 0, 0, 0, 0 }\r
357  };\r
358  \r
359 +char *notmuch_requested_db_revision = NULL;\r
360 +\r
361  void\r
362  notmuch_process_shared_options (unused (const char *dummy))\r
363  {\r
364 -- \r
365 2.1.4\r
366 \r