Re: [RFC PATCH] test: add devel/test-in-docker.sh
[notmuch-archives.git] / 00 / e13fce76588ebe4721e8e5b278c7b03897edbc
1 Return-Path: <sojkam1@fel.cvut.cz>\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 23FBE404965\r
6         for <notmuch@notmuchmail.org>; Thu, 18 Mar 2010 08:40:59 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -2.269\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-2.269 tagged_above=-999 required=5 tests=[AWL=0.330,\r
12         BAYES_00=-2.599] autolearn=ham\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 OKmA-PbJGQQg for <notmuch@notmuchmail.org>;\r
16         Thu, 18 Mar 2010 08:40:55 -0700 (PDT)\r
17 Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
18         by olra.theworths.org (Postfix) with ESMTP id 81BEE404964\r
19         for <notmuch@notmuchmail.org>; Thu, 18 Mar 2010 08:40:54 -0700 (PDT)\r
20 Received: from localhost (unknown [192.168.200.4])\r
21         by max.feld.cvut.cz (Postfix) with ESMTP id E82B719F3409;\r
22         Thu, 18 Mar 2010 16:40:53 +0100 (CET)\r
23 X-Virus-Scanned: IMAP AMAVIS\r
24 Received: from max.feld.cvut.cz ([192.168.200.1])\r
25         by localhost (styx.feld.cvut.cz [192.168.200.4]) (amavisd-new,\r
26         port 10044)\r
27         with ESMTP id xS-7LdHy5MBJ; Thu, 18 Mar 2010 16:40:51 +0100 (CET)\r
28 Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
29         by max.feld.cvut.cz (Postfix) with ESMTP id 1D18519F3401;\r
30         Thu, 18 Mar 2010 16:40:51 +0100 (CET)\r
31 Received: from steelpick.localdomain (k335-30.felk.cvut.cz [147.32.86.30])\r
32         (Authenticated sender: sojkam1)\r
33         by imap.feld.cvut.cz (Postfix) with ESMTPSA id ED612FA004;\r
34         Thu, 18 Mar 2010 16:40:50 +0100 (CET)\r
35 Received: from wsh by steelpick.localdomain with local (Exim 4.71)\r
36         (envelope-from <sojkam1@fel.cvut.cz>)\r
37         id 1NsHq6-0005Hf-It; Thu, 18 Mar 2010 16:40:50 +0100\r
38 From: Michal Sojka <sojkam1@fel.cvut.cz>\r
39 To: notmuch@notmuchmail.org\r
40 Date: Thu, 18 Mar 2010 16:39:37 +0100\r
41 Message-Id: <1268926780-20045-2-git-send-email-sojkam1@fel.cvut.cz>\r
42 X-Mailer: git-send-email 1.7.0\r
43 In-Reply-To: <1268926780-20045-1-git-send-email-sojkam1@fel.cvut.cz>\r
44 References: <1268926780-20045-1-git-send-email-sojkam1@fel.cvut.cz>\r
45 Subject: [notmuch] [PATCH 1/4] Mailstore abstraction interface\r
46 X-BeenThere: notmuch@notmuchmail.org\r
47 X-Mailman-Version: 2.1.13\r
48 Precedence: list\r
49 List-Id: "Use and development of the notmuch mail system."\r
50         <notmuch.notmuchmail.org>\r
51 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
53 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
54 List-Post: <mailto:notmuch@notmuchmail.org>\r
55 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
56 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
57         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
58 X-List-Received-Date: Thu, 18 Mar 2010 15:40:59 -0000\r
59 \r
60 The goal of mailstore abstraction is to allow notmuch to store tags\r
61 together with email messages. The abstract interface is needed because\r
62 people want to use different ways of storing their emails. This\r
63 patchseries implements two types of mailstore - plain files and\r
64 maildir. It is expected that additional git-based mailstore will\r
65 follow.\r
66 \r
67 This patch contains only the interface changes. No functionality is\r
68 added, removed or changed.\r
69 \r
70 A new configuration group [mailstore] is defined. Currently, there is\r
71 only one key 'type' whose value determines the used mailstore. The\r
72 default value of this option is the plain-file mailstore currently\r
73 implemented in notmuch.\r
74 \r
75 Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>\r
76 ---\r
77  lib/Makefile.local      |    2 +\r
78  lib/database-private.h  |    1 +\r
79  lib/database.cc         |   15 ++++++--\r
80  lib/mailstore-files.c   |   43 ++++++++++++++++++++++++\r
81  lib/mailstore-private.h |   59 ++++++++++++++++++++++++++++++++\r
82  lib/mailstore.c         |   77 ++++++++++++++++++++++++++++++++++++++++++\r
83  lib/message.cc          |   13 +++++++\r
84  lib/notmuch.h           |   85 ++++++++++++++++++++++++++++++++++++++++++++--\r
85  notmuch-client.h        |    7 ++++\r
86  notmuch-config.c        |   34 +++++++++++++++++++\r
87  notmuch-count.c         |    3 +-\r
88  notmuch-dump.c          |    3 +-\r
89  notmuch-new.c           |    6 ++-\r
90  notmuch-reply.c         |    3 +-\r
91  notmuch-restore.c       |    3 +-\r
92  notmuch-search-tags.c   |    3 +-\r
93  notmuch-search.c        |    3 +-\r
94  notmuch-show.c          |    3 +-\r
95  notmuch-tag.c           |    3 +-\r
96  19 files changed, 348 insertions(+), 18 deletions(-)\r
97  create mode 100644 lib/mailstore-files.c\r
98  create mode 100644 lib/mailstore-private.h\r
99  create mode 100644 lib/mailstore.c\r
100 \r
101 diff --git a/lib/Makefile.local b/lib/Makefile.local\r
102 index 495b27e..fc8883d 100644\r
103 --- a/lib/Makefile.local\r
104 +++ b/lib/Makefile.local\r
105 @@ -3,6 +3,8 @@ extra_cflags += -I$(dir)\r
106  \r
107  libnotmuch_c_srcs =            \\r
108         $(dir)/libsha1.c        \\r
109 +       $(dir)/mailstore.c      \\r
110 +       $(dir)/mailstore-files.c\\r
111         $(dir)/message-file.c   \\r
112         $(dir)/messages.c       \\r
113         $(dir)/sha1.c           \\r
114 diff --git a/lib/database-private.h b/lib/database-private.h\r
115 index 41918d7..4499b1a 100644\r
116 --- a/lib/database-private.h\r
117 +++ b/lib/database-private.h\r
118 @@ -49,6 +49,7 @@ struct _notmuch_database {\r
119      Xapian::TermGenerator *term_gen;\r
120      Xapian::ValueRangeProcessor *value_range_processor;\r
121  \r
122 +    notmuch_mailstore_t *mailstore;\r
123  };\r
124  \r
125  /* Convert tags from Xapian internal format to notmuch format.\r
126 diff --git a/lib/database.cc b/lib/database.cc\r
127 index c91e97c..93c8d0f 100644\r
128 --- a/lib/database.cc\r
129 +++ b/lib/database.cc\r
130 @@ -19,6 +19,7 @@\r
131   */\r
132  \r
133  #include "database-private.h"\r
134 +#include "mailstore-private.h"\r
135  \r
136  #include <iostream>\r
137  \r
138 @@ -438,7 +439,7 @@ parse_references (void *ctx,\r
139  }\r
140  \r
141  notmuch_database_t *\r
142 -notmuch_database_create (const char *path)\r
143 +notmuch_database_create (const char *path, notmuch_mailstore_t *mailstore)\r
144  {\r
145      notmuch_database_t *notmuch = NULL;\r
146      char *notmuch_path = NULL;\r
147 @@ -474,7 +475,8 @@ notmuch_database_create (const char *path)\r
148      }\r
149  \r
150      notmuch = notmuch_database_open (path,\r
151 -                                    NOTMUCH_DATABASE_MODE_READ_WRITE);\r
152 +                                    NOTMUCH_DATABASE_MODE_READ_WRITE,\r
153 +                                    mailstore);\r
154      notmuch_database_upgrade (notmuch, NULL, NULL);\r
155  \r
156    DONE:\r
157 @@ -497,7 +499,8 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)\r
158  \r
159  notmuch_database_t *\r
160  notmuch_database_open (const char *path,\r
161 -                      notmuch_database_mode_t mode)\r
162 +                      notmuch_database_mode_t mode,\r
163 +                      notmuch_mailstore_t *mailstore)\r
164  {\r
165      notmuch_database_t *notmuch = NULL;\r
166      char *notmuch_path = NULL, *xapian_path = NULL;\r
167 @@ -605,6 +608,9 @@ notmuch_database_open (const char *path,\r
168             prefix_t *prefix = &PROBABILISTIC_PREFIX[i];\r
169             notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);\r
170         }\r
171 +\r
172 +       notmuch->mailstore = mailstore;\r
173 +       mailstore->notmuch = notmuch;\r
174      } catch (const Xapian::Error &error) {\r
175         fprintf (stderr, "A Xapian exception occurred opening database: %s\n",\r
176                  error.get_msg().c_str());\r
177 @@ -1493,7 +1499,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
178  \r
179    DONE:\r
180      if (message) {\r
181 -       if (ret == NOTMUCH_STATUS_SUCCESS && message_ret)\r
182 +       if ((ret == NOTMUCH_STATUS_SUCCESS ||\r
183 +            ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) && message_ret)\r
184             *message_ret = message;\r
185         else\r
186             notmuch_message_destroy (message);\r
187 diff --git a/lib/mailstore-files.c b/lib/mailstore-files.c\r
188 new file mode 100644\r
189 index 0000000..92d7f5d\r
190 --- /dev/null\r
191 +++ b/lib/mailstore-files.c\r
192 @@ -0,0 +1,43 @@\r
193 +/* mailstore-files.c - Original notmuch mail store - a collection of\r
194 + * plain-text email messages (one message per file).\r
195 + *\r
196 + * Copyright Â© 2009 Carl Worth\r
197 + *\r
198 + * This program is free software: you can redistribute it and/or modify\r
199 + * it under the terms of the GNU General Public License as published by\r
200 + * the Free Software Foundation, either version 3 of the License, or\r
201 + * (at your option) any later version.\r
202 + *\r
203 + * This program is distributed in the hope that it will be useful,\r
204 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
205 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
206 + * GNU General Public License for more details.\r
207 + *\r
208 + * You should have received a copy of the GNU General Public License\r
209 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
210 + *\r
211 + * Authors: Carl Worth <cworth@cworth.org>\r
212 + *         Michal Sojka <sojkam1@fel.cvut.cz>\r
213 + */\r
214 +\r
215 +#include "notmuch.h"\r
216 +#include "mailstore-private.h"\r
217 +\r
218 +\r
219 +static FILE *\r
220 +open_file(notmuch_mailstore_t *mailstore, const char *filename)\r
221 +{\r
222 +    const char *db_path, *abs_filename;\r
223 +\r
224 +    db_path = notmuch_database_get_path(mailstore->notmuch);\r
225 +    abs_filename = talloc_asprintf(mailstore, "%s/%s", db_path, filename);\r
226 +    if (unlikely(abs_filename == NULL))\r
227 +       return NULL;\r
228 +    return fopen (abs_filename, "r");\r
229 +}\r
230 +\r
231 +/* Original notmuch mail store */\r
232 +struct _notmuch_mailstore mailstore_files = {\r
233 +    .type = "files",\r
234 +    .open_file = open_file,\r
235 +};\r
236 diff --git a/lib/mailstore-private.h b/lib/mailstore-private.h\r
237 new file mode 100644\r
238 index 0000000..f606e3f\r
239 --- /dev/null\r
240 +++ b/lib/mailstore-private.h\r
241 @@ -0,0 +1,59 @@\r
242 +/* mailstore-private.h - Mailstore abstraction\r
243 + *\r
244 + * Copyright Â© 2010 Michal Sojka\r
245 + *\r
246 + * This program is free software: you can redistribute it and/or modify\r
247 + * it under the terms of the GNU General Public License as published by\r
248 + * the Free Software Foundation, either version 3 of the License, or\r
249 + * (at your option) any later version.\r
250 + *\r
251 + * This program is distributed in the hope that it will be useful,\r
252 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
253 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
254 + * GNU General Public License for more details.\r
255 + *\r
256 + * You should have received a copy of the GNU General Public License\r
257 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
258 + *\r
259 + * Author: Michal Sojka <sojkam1@fel.cvut.cz>\r
260 + */\r
261 +\r
262 +#ifndef MAILSTORE_PRIVATE_H\r
263 +#define MAILSTORE_PRIVATE_H\r
264 +\r
265 +#include "notmuch-private.h"\r
266 +\r
267 +struct _notmuch_mailstore {\r
268 +    /* Constant fields */\r
269 +    const char *type;      /* identification in .notmuch-config */\r
270 +    void *priv;\r
271 +\r
272 +    /* Count files in mailstore so that initial invocation of notmuch\r
273 +     * new can report remaining time */\r
274 +    void (*count_files)(notmuch_mailstore_t *mailstore,\r
275 +                       const char *path, int *count,\r
276 +                       volatile sig_atomic_t *interrupted);\r
277 +    /* Scan for new messages and add them to the database. */\r
278 +    notmuch_private_status_t (*index_new)(notmuch_mailstore_t *mailstore,\r
279 +                                         const char* path,\r
280 +                                         notmuch_indexing_context_t *ctx);\r
281 +    /* Store the tags assigned to the 'messages' to the\r
282 +     * 'mailstore'. */\r
283 +    notmuch_private_status_t (*sync_tags)(notmuch_mailstore_t *mailstore,\r
284 +                                         notmuch_message_t *message);\r
285 +    /* Return file handle from which the message can be read.\r
286 +     *\r
287 +     * Currently, this is not used and all message access is hardcoded\r
288 +     * to notmuch. We will need this operation for git-based and other\r
289 +     * non-filesystem mailstores. */\r
290 +    FILE * (*open_file)(notmuch_mailstore_t *mailstore,\r
291 +                       const char *filename);\r
292 +\r
293 +    /* Run-time fields */\r
294 +    notmuch_database_t *notmuch;\r
295 +};\r
296 +\r
297 +extern struct _notmuch_mailstore mailstore_files;\r
298 +extern struct _notmuch_mailstore mailstore_maildir;\r
299 +\r
300 +#endif /* MAILSTORE_PRIVATE_H */\r
301 diff --git a/lib/mailstore.c b/lib/mailstore.c\r
302 new file mode 100644\r
303 index 0000000..cdac9a6\r
304 --- /dev/null\r
305 +++ b/lib/mailstore.c\r
306 @@ -0,0 +1,77 @@\r
307 +/* mailstore.c - Mailstore abstraction\r
308 + *\r
309 + * Copyright Â© 2010 Michal Sojka\r
310 + *\r
311 + * This program is free software: you can redistribute it and/or modify\r
312 + * it under the terms of the GNU General Public License as published by\r
313 + * the Free Software Foundation, either version 3 of the License, or\r
314 + * (at your option) any later version.\r
315 + *\r
316 + * This program is distributed in the hope that it will be useful,\r
317 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
318 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
319 + * GNU General Public License for more details.\r
320 + *\r
321 + * You should have received a copy of the GNU General Public License\r
322 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
323 + *\r
324 + * Author: Michal Sojka <sojkam1@fel.cvut.cz>\r
325 + */\r
326 +\r
327 +#include <notmuch.h>\r
328 +#include "mailstore-private.h"\r
329 +\r
330 +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))\r
331 +\r
332 +static notmuch_mailstore_t *available[] = {\r
333 +    &mailstore_files,\r
334 +};\r
335 +\r
336 +notmuch_mailstore_t *\r
337 +notmuch_mailstore_get_by_type (const char *type)\r
338 +{\r
339 +    unsigned i;\r
340 +\r
341 +    if (type == NULL)\r
342 +       return available[0];\r
343 +\r
344 +    for (i = 0; i < ARRAY_SIZE(available); i++) {\r
345 +       if (strcasecmp (type, available[i]->type) == 0)\r
346 +           return available[i];\r
347 +    }\r
348 +    return NULL;\r
349 +}\r
350 +\r
351 +const char *\r
352 +notmuch_mailstore_get_type (notmuch_mailstore_t *mailstore)\r
353 +{\r
354 +    if (!mailstore)\r
355 +       return NULL;\r
356 +\r
357 +    return mailstore->type;\r
358 +}\r
359 +\r
360 +void\r
361 +notmuch_mailstore_count_files (notmuch_mailstore_t *mailstore,\r
362 +                             const char *path, int *count,\r
363 +                             volatile sig_atomic_t *interrupted)\r
364 +{\r
365 +    mailstore->count_files (mailstore, path, count, interrupted);\r
366 +}\r
367 +\r
368 +notmuch_status_t\r
369 +notmuch_mailstore_index_new (notmuch_mailstore_t *mailstore,\r
370 +                           const char *path,\r
371 +                           notmuch_indexing_context_t *ctx)\r
372 +{\r
373 +    notmuch_private_status_t status;\r
374 +    status = mailstore->index_new (mailstore, path, ctx);\r
375 +    return COERCE_STATUS (status, "Index new");\r
376 +}\r
377 +\r
378 +FILE *\r
379 +notmuch_mailstore_open_file (notmuch_mailstore_t *mailstore,\r
380 +                            const char *filename)\r
381 +{\r
382 +    return mailstore->open_file (mailstore, filename);\r
383 +}\r
384 diff --git a/lib/message.cc b/lib/message.cc\r
385 index 721c9a6..c32ee7d 100644\r
386 --- a/lib/message.cc\r
387 +++ b/lib/message.cc\r
388 @@ -20,6 +20,7 @@\r
389  \r
390  #include "notmuch-private.h"\r
391  #include "database-private.h"\r
392 +#include "mailstore-private.h"\r
393  \r
394  #include <stdint.h>\r
395  \r
396 @@ -555,10 +556,22 @@ void\r
397  _notmuch_message_sync (notmuch_message_t *message)\r
398  {\r
399      Xapian::WritableDatabase *db;\r
400 +    notmuch_private_status_t status;\r
401  \r
402      if (message->notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)\r
403         return;\r
404  \r
405 +    if (message->notmuch->mailstore->sync_tags) {\r
406 +       status = message->notmuch->mailstore->sync_tags (message->notmuch->mailstore,\r
407 +                                                        message);\r
408 +       if (status != NOTMUCH_PRIVATE_STATUS_SUCCESS) {\r
409 +           fprintf (stderr, "Error: Cannot sync tags to mailstore (%s)\n",\r
410 +                    notmuch_status_to_string ((notmuch_status_t)status));\r
411 +           /* Exit to avoid unsynchronized mailstore. */\r
412 +           exit(1);\r
413 +       }\r
414 +    }\r
415 +\r
416      db = static_cast <Xapian::WritableDatabase *> (message->notmuch->xapian_db);\r
417      db->replace_document (message->doc_id, message->doc);\r
418  }\r
419 diff --git a/lib/notmuch.h b/lib/notmuch.h\r
420 index 0d9cb0f..4f4cc8b 100644\r
421 --- a/lib/notmuch.h\r
422 +++ b/lib/notmuch.h\r
423 @@ -32,6 +32,9 @@\r
424  NOTMUCH_BEGIN_DECLS\r
425  \r
426  #include <time.h>\r
427 +#include <sys/time.h>          /* For struct timeval */\r
428 +#include <signal.h>            /* For sig_atomic_t */\r
429 +#include <stdio.h>             /* For FILE */\r
430  \r
431  #ifndef FALSE\r
432  #define FALSE 0\r
433 @@ -119,6 +122,8 @@ typedef struct _notmuch_message notmuch_message_t;\r
434  typedef struct _notmuch_tags notmuch_tags_t;\r
435  typedef struct _notmuch_directory notmuch_directory_t;\r
436  typedef struct _notmuch_filenames notmuch_filenames_t;\r
437 +typedef struct _notmuch_mailstore notmuch_mailstore_t;\r
438 +\r
439  \r
440  /* Create a new, empty notmuch database located at 'path'.\r
441   *\r
442 @@ -127,6 +132,8 @@ typedef struct _notmuch_filenames notmuch_filenames_t;\r
443   * create a new ".notmuch" directory within 'path' where notmuch will\r
444   * store its data.\r
445   *\r
446 + * FIXME: Mailstore...\r
447 + *\r
448   * After a successful call to notmuch_database_create, the returned\r
449   * database will be open so the caller should call\r
450   * notmuch_database_close when finished with it.\r
451 @@ -140,7 +147,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t;\r
452   * an error message on stderr).\r
453   */\r
454  notmuch_database_t *\r
455 -notmuch_database_create (const char *path);\r
456 +notmuch_database_create (const char *path, notmuch_mailstore_t *mailstore);\r
457  \r
458  typedef enum {\r
459      NOTMUCH_DATABASE_MODE_READ_ONLY = 0,\r
460 @@ -152,6 +159,8 @@ typedef enum {\r
461  \r
462  /* Open an existing notmuch database located at 'path'.\r
463   *\r
464 + * The database will index mails stored in 'mailstore'.\r
465 + *\r
466   * The database should have been created at some time in the past,\r
467   * (not necessarily by this process), by calling\r
468   * notmuch_database_create with 'path'. By default the database should be\r
469 @@ -169,7 +178,8 @@ typedef enum {\r
470   */\r
471  notmuch_database_t *\r
472  notmuch_database_open (const char *path,\r
473 -                      notmuch_database_mode_t mode);\r
474 +                      notmuch_database_mode_t mode,\r
475 +                      notmuch_mailstore_t *mailstore);\r
476  \r
477  /* Close the given notmuch database, freeing all associated\r
478   * resources. See notmuch_database_open. */\r
479 @@ -236,7 +246,8 @@ notmuch_database_get_directory (notmuch_database_t *database,\r
480   * notmuch database will reference the filename, and will not copy the\r
481   * entire contents of the file.\r
482   *\r
483 - * If 'message' is not NULL, then, on successful return '*message'\r
484 + * If 'message' is not NULL, then, on successful return\r
485 + * (NOTMUCH_STATUS_SUCCESS or NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) '*message'\r
486   * will be initialized to a message object that can be used for things\r
487   * such as adding tags to the just-added message. The user should call\r
488   * notmuch_message_destroy when done with the message. On any failure\r
489 @@ -495,7 +506,7 @@ notmuch_threads_destroy (notmuch_threads_t *threads);\r
490   */\r
491  unsigned\r
492  notmuch_query_count_messages (notmuch_query_t *query);\r
493\r
494 +\r
495  /* Get the thread ID of 'thread'.\r
496   *\r
497   * The returned string belongs to 'thread' and as such, should not be\r
498 @@ -1104,6 +1115,72 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);\r
499  void\r
500  notmuch_filenames_destroy (notmuch_filenames_t *filenames);\r
501  \r
502 +/* Returns notmuch_mailstore_t object of a given 'type'.\r
503 + *\r
504 + * The 'type' is case insensitive. If 'type' is NULL, a default\r
505 + * mailstore is returned.\r
506 + *\r
507 + * When no available mailstore matches 'type', NULL is returned.\r
508 + */\r
509 +notmuch_mailstore_t *\r
510 +notmuch_mailstore_get_by_type (const char *type);\r
511 +\r
512 +/* Returns the type of a mailstore.\r
513 + *\r
514 + * The returned string is owned by mailstore so should not be modified\r
515 + * nor freed by the caller.\r
516 + */\r
517 +const char *\r
518 +notmuch_mailstore_get_type (notmuch_mailstore_t *mailstore);\r
519 +\r
520 +/* Count emails in mailstore.\r
521 + *\r
522 + * This function returns when interrupted is set to non-zero value.\r
523 + */\r
524 +void\r
525 +notmuch_mailstore_count_files (notmuch_mailstore_t *mailstore,\r
526 +                             const char *path, int *count,\r
527 +                             volatile sig_atomic_t *interrupted);\r
528 +\r
529 +typedef struct notmuch_indexing_context {\r
530 +    int output_is_a_tty;\r
531 +    int verbose;\r
532 +\r
533 +    int total_files;\r
534 +    int processed_files;\r
535 +    int added_messages;\r
536 +    int renamed_files;\r
537 +    int removed_files;\r
538 +    struct timeval tv_start;\r
539 +\r
540 +    void *priv;\r
541 +\r
542 +    volatile sig_atomic_t interrupted;\r
543 +    volatile sig_atomic_t print_progress;\r
544 +    void (*print_progress_cb)(struct notmuch_indexing_context *ctx);\r
545 +\r
546 +} notmuch_indexing_context_t;\r
547 +\r
548 +\r
549 +/* Index new mails in the mailstore.\r
550 + *\r
551 + * Mailstore is responsible for detecting new emails, adding them to\r
552 + * the database and tagging them with tags stored in the mailstore.\r
553 + */\r
554 +notmuch_status_t\r
555 +notmuch_mailstore_index_new (notmuch_mailstore_t *mailstore,\r
556 +                           const char *path,\r
557 +                           notmuch_indexing_context_t *ctx);\r
558 +\r
559 +/* Returns file handle to the file in the mailstore.\r
560 + *\r
561 + * TODO: This function is currently not used and access to mails is\r
562 + * hardcoded in other parts of notmuch.\r
563 + */\r
564 +FILE *\r
565 +notmuch_mailstore_open_file (notmuch_mailstore_t *mailstore,\r
566 +                            const char *filename);\r
567 +\r
568  NOTMUCH_END_DECLS\r
569  \r
570  #endif\r
571 diff --git a/notmuch-client.h b/notmuch-client.h\r
572 index c80b39c..4794b8e 100644\r
573 --- a/notmuch-client.h\r
574 +++ b/notmuch-client.h\r
575 @@ -171,6 +171,13 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,\r
576                                      const char *other_email[],\r
577                                      size_t length);\r
578  \r
579 +notmuch_mailstore_t *\r
580 +notmuch_config_get_mailstore(notmuch_config_t *config);\r
581 +\r
582 +void\r
583 +notmuch_config_set_mailstore(notmuch_config_t *config,\r
584 +                            notmuch_mailstore_t *mailstore);\r
585 +\r
586  notmuch_bool_t\r
587  debugger_is_active (void);\r
588  \r
589 diff --git a/notmuch-config.c b/notmuch-config.c\r
590 index 95430db..299423a 100644\r
591 --- a/notmuch-config.c\r
592 +++ b/notmuch-config.c\r
593 @@ -62,6 +62,7 @@ struct _notmuch_config {\r
594      char *user_primary_email;\r
595      char **user_other_email;\r
596      size_t user_other_email_length;\r
597 +    notmuch_mailstore_t *mailstore;\r
598  };\r
599  \r
600  static int\r
601 @@ -199,6 +200,7 @@ notmuch_config_open (void *ctx,\r
602      config->user_primary_email = NULL;\r
603      config->user_other_email = NULL;\r
604      config->user_other_email_length = 0;\r
605 +    config->mailstore = NULL;\r
606  \r
607      if (! g_key_file_load_from_file (config->key_file,\r
608                                      config->filename,\r
609 @@ -264,6 +266,10 @@ notmuch_config_open (void *ctx,\r
610         }\r
611      }\r
612  \r
613 +    if (notmuch_config_get_mailstore (config) == NULL) {\r
614 +       notmuch_config_set_mailstore(config, notmuch_mailstore_get_by_type(NULL));\r
615 +    }\r
616 +\r
617      /* When we create a new configuration file here, we  add some\r
618       * comments to help the user understand what can be done. */\r
619      if (is_new) {\r
620 @@ -452,3 +458,31 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,\r
621      talloc_free (config->user_other_email);\r
622      config->user_other_email = NULL;\r
623  }\r
624 +\r
625 +notmuch_mailstore_t *\r
626 +notmuch_config_get_mailstore(notmuch_config_t *config)\r
627 +{\r
628 +    char *type;\r
629 +\r
630 +    if (config->mailstore == NULL) {\r
631 +       type = g_key_file_get_string (config->key_file,\r
632 +                                     "mailstore", "type", NULL);\r
633 +       if (type) {\r
634 +           config->mailstore = notmuch_mailstore_get_by_type(type);\r
635 +           free (type);\r
636 +       }\r
637 +    }\r
638 +\r
639 +    return config->mailstore;\r
640 +}\r
641 +\r
642 +void\r
643 +notmuch_config_set_mailstore(notmuch_config_t *config,\r
644 +                            notmuch_mailstore_t *mailstore)\r
645 +{\r
646 +    g_key_file_set_string (config->key_file,\r
647 +                          "mailstore", "type",\r
648 +                          notmuch_mailstore_get_type(mailstore));\r
649 +\r
650 +    config->mailstore = NULL;\r
651 +}\r
652 diff --git a/notmuch-count.c b/notmuch-count.c\r
653 index 77aa433..631b8f8 100644\r
654 --- a/notmuch-count.c\r
655 +++ b/notmuch-count.c\r
656 @@ -81,7 +81,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[])\r
657         return 1;\r
658  \r
659      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
660 -                                    NOTMUCH_DATABASE_MODE_READ_ONLY);\r
661 +                                    NOTMUCH_DATABASE_MODE_READ_ONLY,\r
662 +                                    notmuch_config_get_mailstore(config));\r
663      if (notmuch == NULL)\r
664         return 1;\r
665  \r
666 diff --git a/notmuch-dump.c b/notmuch-dump.c\r
667 index 7e7bc17..e74dfcb 100644\r
668 --- a/notmuch-dump.c\r
669 +++ b/notmuch-dump.c\r
670 @@ -36,7 +36,8 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[])\r
671         return 1;\r
672  \r
673      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
674 -                                    NOTMUCH_DATABASE_MODE_READ_ONLY);\r
675 +                                    NOTMUCH_DATABASE_MODE_READ_ONLY,\r
676 +                                    notmuch_config_get_mailstore (config));\r
677      if (notmuch == NULL)\r
678         return 1;\r
679  \r
680 diff --git a/notmuch-new.c b/notmuch-new.c\r
681 index 44b50aa..2d0ba6c 100644\r
682 --- a/notmuch-new.c\r
683 +++ b/notmuch-new.c\r
684 @@ -749,11 +749,13 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
685             return 1;\r
686  \r
687         printf ("Found %d total files (that's not much mail).\n", count);\r
688 -       notmuch = notmuch_database_create (db_path);\r
689 +       notmuch = notmuch_database_create (db_path,\r
690 +                                          notmuch_config_get_mailstore (config));\r
691         add_files_state.total_files = count;\r
692      } else {\r
693         notmuch = notmuch_database_open (db_path,\r
694 -                                        NOTMUCH_DATABASE_MODE_READ_WRITE);\r
695 +                                        NOTMUCH_DATABASE_MODE_READ_WRITE,\r
696 +                                        notmuch_config_get_mailstore (config));\r
697         if (notmuch == NULL)\r
698             return 1;\r
699  \r
700 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
701 index 6c15536..0d6b7cf 100644\r
702 --- a/notmuch-reply.c\r
703 +++ b/notmuch-reply.c\r
704 @@ -468,7 +468,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
705      }\r
706  \r
707      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
708 -                                    NOTMUCH_DATABASE_MODE_READ_ONLY);\r
709 +                                    NOTMUCH_DATABASE_MODE_READ_ONLY,\r
710 +                                    notmuch_config_get_mailstore (config));\r
711      if (notmuch == NULL)\r
712         return 1;\r
713  \r
714 diff --git a/notmuch-restore.c b/notmuch-restore.c\r
715 index b0a4e1c..97d817b 100644\r
716 --- a/notmuch-restore.c\r
717 +++ b/notmuch-restore.c\r
718 @@ -37,7 +37,8 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
719         return 1;\r
720  \r
721      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
722 -                                    NOTMUCH_DATABASE_MODE_READ_WRITE);\r
723 +                                    NOTMUCH_DATABASE_MODE_READ_WRITE,\r
724 +                                    notmuch_config_get_mailstore (config));\r
725      if (notmuch == NULL)\r
726         return 1;\r
727  \r
728 diff --git a/notmuch-search-tags.c b/notmuch-search-tags.c\r
729 index 6f3cfcc..323f416 100644\r
730 --- a/notmuch-search-tags.c\r
731 +++ b/notmuch-search-tags.c\r
732 @@ -52,7 +52,8 @@ notmuch_search_tags_command (void *ctx, int argc, char *argv[])\r
733      }\r
734  \r
735      db = notmuch_database_open (notmuch_config_get_database_path (config),\r
736 -                               NOTMUCH_DATABASE_MODE_READ_ONLY);\r
737 +                               NOTMUCH_DATABASE_MODE_READ_ONLY,\r
738 +                               notmuch_config_get_mailstore (config));\r
739      if (db == NULL) {\r
740         goto error;\r
741      }\r
742 diff --git a/notmuch-search.c b/notmuch-search.c\r
743 index 4e3514b..d57479d 100644\r
744 --- a/notmuch-search.c\r
745 +++ b/notmuch-search.c\r
746 @@ -245,7 +245,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])\r
747         return 1;\r
748  \r
749      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
750 -                                    NOTMUCH_DATABASE_MODE_READ_ONLY);\r
751 +                                    NOTMUCH_DATABASE_MODE_READ_ONLY,\r
752 +                                    notmuch_config_get_mailstore (config));\r
753      if (notmuch == NULL)\r
754         return 1;\r
755  \r
756 diff --git a/notmuch-show.c b/notmuch-show.c\r
757 index ff1fecb..26581c1 100644\r
758 --- a/notmuch-show.c\r
759 +++ b/notmuch-show.c\r
760 @@ -458,7 +458,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
761      }\r
762  \r
763      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
764 -                                    NOTMUCH_DATABASE_MODE_READ_ONLY);\r
765 +                                    NOTMUCH_DATABASE_MODE_READ_ONLY,\r
766 +                                    notmuch_config_get_mailstore (config));\r
767      if (notmuch == NULL)\r
768         return 1;\r
769  \r
770 diff --git a/notmuch-tag.c b/notmuch-tag.c\r
771 index 8b6f7dc..5e1a5c3 100644\r
772 --- a/notmuch-tag.c\r
773 +++ b/notmuch-tag.c\r
774 @@ -97,7 +97,8 @@ notmuch_tag_command (void *ctx, unused (int argc), unused (char *argv[]))\r
775         return 1;\r
776  \r
777      notmuch = notmuch_database_open (notmuch_config_get_database_path (config),\r
778 -                                    NOTMUCH_DATABASE_MODE_READ_WRITE);\r
779 +                                    NOTMUCH_DATABASE_MODE_READ_WRITE,\r
780 +                                    notmuch_config_get_mailstore (config));\r
781      if (notmuch == NULL)\r
782         return 1;\r
783  \r
784 -- \r
785 1.7.0\r
786 \r