]> git.notmuchmail.org Git - notmuch/blob - lib/notmuch.h
7d9e0921f0c17e9f442f46e57dcc33e152c13329
[notmuch] / lib / notmuch.h
1 /* notmuch - Not much of an email library, (just index and search)
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see http://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 #ifndef NOTMUCH_H
22 #define NOTMUCH_H
23
24 #ifdef  __cplusplus
25 # define NOTMUCH_BEGIN_DECLS  extern "C" {
26 # define NOTMUCH_END_DECLS    }
27 #else
28 # define NOTMUCH_BEGIN_DECLS
29 # define NOTMUCH_END_DECLS
30 #endif
31
32 NOTMUCH_BEGIN_DECLS
33
34 #include <time.h>
35
36 #ifndef FALSE
37 #define FALSE 0
38 #endif
39
40 #ifndef TRUE
41 #define TRUE 1
42 #endif
43
44 typedef int notmuch_bool_t;
45
46 /* Status codes used for the return values of most functions.
47  *
48  * A zero value (NOTMUCH_STATUS_SUCCESS) indicates that the function
49  * completed without error. Any other value indicates an error as
50  * follows:
51  *
52  * NOTMUCH_STATUS_SUCCESS: No error occurred.
53  *
54  * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory
55  *
56  * XXX: We don't really want to expose this lame XAPIAN_EXCEPTION
57  * value. Instead we should map to things like DATABASE_LOCKED or
58  * whatever.
59  *
60  * NOTMUCH_STATUS_READ_ONLY_DATABASE: An attempt was made to write to
61  *      a database opened in read-only mode.
62  *
63  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
64  *
65  * NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to read or
66  *      write to a file (this could be file not found, permission
67  *      denied, etc.)
68  *
69  * NOTMUCH_STATUS_FILE_NOT_EMAIL: A file was presented that doesn't
70  *      appear to be an email message.
71  *
72  * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: A file contains a message ID
73  *      that is identical to a message already in the database.
74  *
75  * NOTMUCH_STATUS_NULL_POINTER: The user erroneously passed a NULL
76  *      pointer to a notmuch function.
77  *
78  * NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long (exceeds
79  *      NOTMUCH_TAG_MAX)
80  *
81  * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw
82  *      function has been called more times than notmuch_message_freeze.
83  *
84  * NOTMUCH_STATUS_UNBALANCED_ATOMIC: notmuch_database_end_atomic has
85  *      been called more times than notmuch_database_begin_atomic.
86  *
87  * And finally:
88  *
89  * NOTMUCH_STATUS_LAST_STATUS: Not an actual status value. Just a way
90  *      to find out how many valid status values there are.
91  */
92 typedef enum _notmuch_status {
93     NOTMUCH_STATUS_SUCCESS = 0,
94     NOTMUCH_STATUS_OUT_OF_MEMORY,
95     NOTMUCH_STATUS_READ_ONLY_DATABASE,
96     NOTMUCH_STATUS_XAPIAN_EXCEPTION,
97     NOTMUCH_STATUS_FILE_ERROR,
98     NOTMUCH_STATUS_FILE_NOT_EMAIL,
99     NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID,
100     NOTMUCH_STATUS_NULL_POINTER,
101     NOTMUCH_STATUS_TAG_TOO_LONG,
102     NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
103     NOTMUCH_STATUS_UNBALANCED_ATOMIC,
104
105     NOTMUCH_STATUS_LAST_STATUS
106 } notmuch_status_t;
107
108 /* Get a string representation of a notmuch_status_t value.
109  *
110  * The result is read-only.
111  */
112 const char *
113 notmuch_status_to_string (notmuch_status_t status);
114
115 /* Various opaque data types. For each notmuch_<foo>_t see the various
116  * notmuch_<foo> functions below. */
117 typedef struct _notmuch_database notmuch_database_t;
118 typedef struct _notmuch_query notmuch_query_t;
119 typedef struct _notmuch_threads notmuch_threads_t;
120 typedef struct _notmuch_thread notmuch_thread_t;
121 typedef struct _notmuch_messages notmuch_messages_t;
122 typedef struct _notmuch_message notmuch_message_t;
123 typedef struct _notmuch_tags notmuch_tags_t;
124 typedef struct _notmuch_directory notmuch_directory_t;
125 typedef struct _notmuch_filenames notmuch_filenames_t;
126
127 /* Create a new, empty notmuch database located at 'path'.
128  *
129  * The path should be a top-level directory to a collection of
130  * plain-text email messages (one message per file). This call will
131  * create a new ".notmuch" directory within 'path' where notmuch will
132  * store its data.
133  *
134  * After a successful call to notmuch_database_create, the returned
135  * database will be open so the caller should call
136  * notmuch_database_destroy when finished with it.
137  *
138  * The database will not yet have any data in it
139  * (notmuch_database_create itself is a very cheap function). Messages
140  * contained within 'path' can be added to the database by calling
141  * notmuch_database_add_message.
142  *
143  * In case of any failure, this function returns NULL, (after printing
144  * an error message on stderr).
145  */
146 notmuch_database_t *
147 notmuch_database_create (const char *path);
148
149 typedef enum {
150     NOTMUCH_DATABASE_MODE_READ_ONLY = 0,
151     NOTMUCH_DATABASE_MODE_READ_WRITE
152 } notmuch_database_mode_t;
153
154 /* XXX: I think I'd like this to take an extra argument of
155  * notmuch_status_t* for returning a status value on failure. */
156
157 /* Open an existing notmuch database located at 'path'.
158  *
159  * The database should have been created at some time in the past,
160  * (not necessarily by this process), by calling
161  * notmuch_database_create with 'path'. By default the database should be
162  * opened for reading only. In order to write to the database you need to
163  * pass the NOTMUCH_DATABASE_MODE_READ_WRITE mode.
164  *
165  * An existing notmuch database can be identified by the presence of a
166  * directory named ".notmuch" below 'path'.
167  *
168  * The caller should call notmuch_database_destroy when finished with
169  * this database.
170  *
171  * In case of any failure, this function returns NULL, (after printing
172  * an error message on stderr).
173  */
174 notmuch_database_t *
175 notmuch_database_open (const char *path,
176                        notmuch_database_mode_t mode);
177
178 /* Close the given notmuch database.
179  *
180  * After notmuch_database_close has been called, calls to other
181  * functions on objects derived from this database may either behave
182  * as if the database had not been closed (e.g., if the required data
183  * has been cached) or may fail with a
184  * NOTMUCH_STATUS_XAPIAN_EXCEPTION.
185  *
186  * notmuch_database_close can be called multiple times.  Later calls
187  * have no effect.
188  */
189 void
190 notmuch_database_close (notmuch_database_t *database);
191
192 /* Destroy the notmuch database, closing it if necessary and freeing
193 * all associated resources. */
194 void
195 notmuch_database_destroy (notmuch_database_t *database);
196
197 /* Return the database path of the given database.
198  *
199  * The return value is a string owned by notmuch so should not be
200  * modified nor freed by the caller. */
201 const char *
202 notmuch_database_get_path (notmuch_database_t *database);
203
204 /* Return the database format version of the given database. */
205 unsigned int
206 notmuch_database_get_version (notmuch_database_t *database);
207
208 /* Does this database need to be upgraded before writing to it?
209  *
210  * If this function returns TRUE then no functions that modify the
211  * database (notmuch_database_add_message, notmuch_message_add_tag,
212  * notmuch_directory_set_mtime, etc.) will work unless the function
213  * notmuch_database_upgrade is called successfully first. */
214 notmuch_bool_t
215 notmuch_database_needs_upgrade (notmuch_database_t *database);
216
217 /* Upgrade the current database.
218  *
219  * After opening a database in read-write mode, the client should
220  * check if an upgrade is needed (notmuch_database_needs_upgrade) and
221  * if so, upgrade with this function before making any modifications.
222  *
223  * The optional progress_notify callback can be used by the caller to
224  * provide progress indication to the user. If non-NULL it will be
225  * called periodically with 'progress' as a floating-point value in
226  * the range of [0.0 .. 1.0] indicating the progress made so far in
227  * the upgrade process.
228  */
229 notmuch_status_t
230 notmuch_database_upgrade (notmuch_database_t *database,
231                           void (*progress_notify) (void *closure,
232                                                    double progress),
233                           void *closure);
234
235 /* Begin an atomic database operation.
236  *
237  * Any modifications performed between a successful begin and a
238  * notmuch_database_end_atomic will be applied to the database
239  * atomically.  Note that, unlike a typical database transaction, this
240  * only ensures atomicity, not durability; neither begin nor end
241  * necessarily flush modifications to disk.
242  *
243  * Atomic sections may be nested.  begin_atomic and end_atomic must
244  * always be called in pairs.
245  *
246  * Return value:
247  *
248  * NOTMUCH_STATUS_SUCCESS: Successfully entered atomic section.
249  *
250  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred;
251  *      atomic section not entered.
252  */
253 notmuch_status_t
254 notmuch_database_begin_atomic (notmuch_database_t *notmuch);
255
256 /* Indicate the end of an atomic database operation.
257  *
258  * Return value:
259  *
260  * NOTMUCH_STATUS_SUCCESS: Successfully completed atomic section.
261  *
262  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred;
263  *      atomic section not ended.
264  *
265  * NOTMUCH_STATUS_UNBALANCED_ATOMIC: The database is not currently in
266  *      an atomic section.
267  */
268 notmuch_status_t
269 notmuch_database_end_atomic (notmuch_database_t *notmuch);
270
271 /* Retrieve a directory object from the database for 'path'.
272  *
273  * Here, 'path' should be a path relative to the path of 'database'
274  * (see notmuch_database_get_path), or else should be an absolute path
275  * with initial components that match the path of 'database'.
276  *
277  * Can return NULL if a Xapian exception occurs.
278  */
279 notmuch_directory_t *
280 notmuch_database_get_directory (notmuch_database_t *database,
281                                 const char *path);
282
283 /* Add a new message to the given notmuch database or associate an
284  * additional filename with an existing message.
285  *
286  * Here, 'filename' should be a path relative to the path of
287  * 'database' (see notmuch_database_get_path), or else should be an
288  * absolute filename with initial components that match the path of
289  * 'database'.
290  *
291  * The file should be a single mail message (not a multi-message mbox)
292  * that is expected to remain at its current location, (since the
293  * notmuch database will reference the filename, and will not copy the
294  * entire contents of the file.
295  *
296  * If another message with the same message ID already exists in the
297  * database, rather than creating a new message, this adds 'filename'
298  * to the list of the filenames for the existing message.
299  *
300  * If 'message' is not NULL, then, on successful return
301  * (NOTMUCH_STATUS_SUCCESS or NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) '*message'
302  * will be initialized to a message object that can be used for things
303  * such as adding tags to the just-added message. The user should call
304  * notmuch_message_destroy when done with the message. On any failure
305  * '*message' will be set to NULL.
306  *
307  * Return value:
308  *
309  * NOTMUCH_STATUS_SUCCESS: Message successfully added to database.
310  *
311  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred,
312  *      message not added.
313  *
314  * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: Message has the same message
315  *      ID as another message already in the database. The new
316  *      filename was successfully added to the message in the database
317  *      (if not already present) and the existing message is returned.
318  *
319  * NOTMUCH_STATUS_FILE_ERROR: an error occurred trying to open the
320  *      file, (such as permission denied, or file not found,
321  *      etc.). Nothing added to the database.
322  *
323  * NOTMUCH_STATUS_FILE_NOT_EMAIL: the contents of filename don't look
324  *      like an email message. Nothing added to the database.
325  *
326  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
327  *      mode so no message can be added.
328  */
329 notmuch_status_t
330 notmuch_database_add_message (notmuch_database_t *database,
331                               const char *filename,
332                               notmuch_message_t **message);
333
334 /* Remove a message filename from the given notmuch database. If the
335  * message has no more filenames, remove the message.
336  *
337  * If the same message (as determined by the message ID) is still
338  * available via other filenames, then the message will persist in the
339  * database for those filenames. When the last filename is removed for
340  * a particular message, the database content for that message will be
341  * entirely removed.
342  *
343  * Return value:
344  *
345  * NOTMUCH_STATUS_SUCCESS: The last filename was removed and the
346  *      message was removed from the database.
347  *
348  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred,
349  *      message not removed.
350  *
351  * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: This filename was removed but
352  *      the message persists in the database with at least one other
353  *      filename.
354  *
355  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
356  *      mode so no message can be removed.
357  */
358 notmuch_status_t
359 notmuch_database_remove_message (notmuch_database_t *database,
360                                  const char *filename);
361
362 /* Find a message with the given message_id.
363  *
364  * If a message with the given message_id is found then, on successful return
365  * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message
366  * object.  The caller should call notmuch_message_destroy when done with the
367  * message.
368  *
369  * On any failure or when the message is not found, this function initializes
370  * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the
371  * caller is supposed to check '*message' for NULL to find out whether the
372  * message with the given message_id was found.
373  *
374  * Return value:
375  *
376  * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'.
377  *
378  * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL
379  *
380  * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating message object
381  *
382  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
383  */
384 notmuch_status_t
385 notmuch_database_find_message (notmuch_database_t *database,
386                                const char *message_id,
387                                notmuch_message_t **message);
388
389 /* Find a message with the given filename.
390  *
391  * If the database contains a message with the given filename then, on
392  * successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to
393  * a message object. The caller should call notmuch_message_destroy when done
394  * with the message.
395  *
396  * On any failure or when the message is not found, this function initializes
397  * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the
398  * caller is supposed to check '*message' for NULL to find out whether the
399  * message with the given filename is found.
400  *
401  * Return value:
402  *
403  * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'
404  *
405  * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL
406  *
407  * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object
408  *
409  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
410  */
411 notmuch_status_t
412 notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
413                                            const char *filename,
414                                            notmuch_message_t **message);
415
416 /* Return a list of all tags found in the database.
417  *
418  * This function creates a list of all tags found in the database. The
419  * resulting list contains all tags from all messages found in the database.
420  *
421  * On error this function returns NULL.
422  */
423 notmuch_tags_t *
424 notmuch_database_get_all_tags (notmuch_database_t *db);
425
426 /* Create a new query for 'database'.
427  *
428  * Here, 'database' should be an open database, (see
429  * notmuch_database_open and notmuch_database_create).
430  *
431  * For the query string, we'll document the syntax here more
432  * completely in the future, but it's likely to be a specialized
433  * version of the general Xapian query syntax:
434  *
435  * http://xapian.org/docs/queryparser.html
436  *
437  * As a special case, passing either a length-zero string, (that is ""),
438  * or a string consisting of a single asterisk (that is "*"), will
439  * result in a query that returns all messages in the database.
440  *
441  * See notmuch_query_set_sort for controlling the order of results.
442  * See notmuch_query_search_messages and notmuch_query_search_threads
443  * to actually execute the query.
444  *
445  * User should call notmuch_query_destroy when finished with this
446  * query.
447  *
448  * Will return NULL if insufficient memory is available.
449  */
450 notmuch_query_t *
451 notmuch_query_create (notmuch_database_t *database,
452                       const char *query_string);
453
454 /* Sort values for notmuch_query_set_sort */
455 typedef enum {
456     NOTMUCH_SORT_OLDEST_FIRST,
457     NOTMUCH_SORT_NEWEST_FIRST,
458     NOTMUCH_SORT_MESSAGE_ID,
459     NOTMUCH_SORT_UNSORTED
460 } notmuch_sort_t;
461
462 /* Return the query_string of this query. See notmuch_query_create. */
463 const char *
464 notmuch_query_get_query_string (notmuch_query_t *query);
465
466 /* Specify whether to omit excluded results or simply flag them.  By
467  * default, this is set to TRUE.
468  *
469  * If this is TRUE, notmuch_query_search_messages will omit excluded
470  * messages from the results.  notmuch_query_search_threads will omit
471  * threads that match only in excluded messages, but will include all
472  * messages in threads that match in at least one non-excluded
473  * message.
474  *
475  * The performance difference when calling
476  * notmuch_query_search_messages should be relatively small (and both
477  * should be very fast).  However, in some cases,
478  * notmuch_query_search_threads is very much faster when omitting
479  * excluded messages as it does not need to construct the threads that
480  * only match in excluded messages.
481  */
482
483 void
484 notmuch_query_set_omit_excluded (notmuch_query_t *query, notmuch_bool_t omit_excluded);
485
486 /* Specify the sorting desired for this query. */
487 void
488 notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
489
490 /* Return the sort specified for this query. See notmuch_query_set_sort. */
491 notmuch_sort_t
492 notmuch_query_get_sort (notmuch_query_t *query);
493
494 /* Add a tag that will be excluded from the query results by default.
495  * This exclusion will be overridden if this tag appears explicitly in
496  * the query. */
497 void
498 notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag);
499
500 /* Execute a query for threads, returning a notmuch_threads_t object
501  * which can be used to iterate over the results. The returned threads
502  * object is owned by the query and as such, will only be valid until
503  * notmuch_query_destroy.
504  *
505  * Typical usage might be:
506  *
507  *     notmuch_query_t *query;
508  *     notmuch_threads_t *threads;
509  *     notmuch_thread_t *thread;
510  *
511  *     query = notmuch_query_create (database, query_string);
512  *
513  *     for (threads = notmuch_query_search_threads (query);
514  *          notmuch_threads_valid (threads);
515  *          notmuch_threads_move_to_next (threads))
516  *     {
517  *         thread = notmuch_threads_get (threads);
518  *         ....
519  *         notmuch_thread_destroy (thread);
520  *     }
521  *
522  *     notmuch_query_destroy (query);
523  *
524  * Note: If you are finished with a thread before its containing
525  * query, you can call notmuch_thread_destroy to clean up some memory
526  * sooner (as in the above example). Otherwise, if your thread objects
527  * are long-lived, then you don't need to call notmuch_thread_destroy
528  * and all the memory will still be reclaimed when the query is
529  * destroyed.
530  *
531  * Note that there's no explicit destructor needed for the
532  * notmuch_threads_t object. (For consistency, we do provide a
533  * notmuch_threads_destroy function, but there's no good reason
534  * to call it if the query is about to be destroyed).
535  *
536  * If a Xapian exception occurs this function will return NULL.
537  */
538 notmuch_threads_t *
539 notmuch_query_search_threads (notmuch_query_t *query);
540
541 /* Execute a query for messages, returning a notmuch_messages_t object
542  * which can be used to iterate over the results. The returned
543  * messages object is owned by the query and as such, will only be
544  * valid until notmuch_query_destroy.
545  *
546  * Typical usage might be:
547  *
548  *     notmuch_query_t *query;
549  *     notmuch_messages_t *messages;
550  *     notmuch_message_t *message;
551  *
552  *     query = notmuch_query_create (database, query_string);
553  *
554  *     for (messages = notmuch_query_search_messages (query);
555  *          notmuch_messages_valid (messages);
556  *          notmuch_messages_move_to_next (messages))
557  *     {
558  *         message = notmuch_messages_get (messages);
559  *         ....
560  *         notmuch_message_destroy (message);
561  *     }
562  *
563  *     notmuch_query_destroy (query);
564  *
565  * Note: If you are finished with a message before its containing
566  * query, you can call notmuch_message_destroy to clean up some memory
567  * sooner (as in the above example). Otherwise, if your message
568  * objects are long-lived, then you don't need to call
569  * notmuch_message_destroy and all the memory will still be reclaimed
570  * when the query is destroyed.
571  *
572  * Note that there's no explicit destructor needed for the
573  * notmuch_messages_t object. (For consistency, we do provide a
574  * notmuch_messages_destroy function, but there's no good
575  * reason to call it if the query is about to be destroyed).
576  *
577  * If a Xapian exception occurs this function will return NULL.
578  */
579 notmuch_messages_t *
580 notmuch_query_search_messages (notmuch_query_t *query);
581
582 /* Destroy a notmuch_query_t along with any associated resources.
583  *
584  * This will in turn destroy any notmuch_threads_t and
585  * notmuch_messages_t objects generated by this query, (and in
586  * turn any notmuch_thread_t and notmuch_message_t objects generated
587  * from those results, etc.), if such objects haven't already been
588  * destroyed.
589  */
590 void
591 notmuch_query_destroy (notmuch_query_t *query);
592
593 /* Is the given 'threads' iterator pointing at a valid thread.
594  *
595  * When this function returns TRUE, notmuch_threads_get will return a
596  * valid object. Whereas when this function returns FALSE,
597  * notmuch_threads_get will return NULL.
598  *
599  * See the documentation of notmuch_query_search_threads for example
600  * code showing how to iterate over a notmuch_threads_t object.
601  */
602 notmuch_bool_t
603 notmuch_threads_valid (notmuch_threads_t *threads);
604
605 /* Get the current thread from 'threads' as a notmuch_thread_t.
606  *
607  * Note: The returned thread belongs to 'threads' and has a lifetime
608  * identical to it (and the query to which it belongs).
609  *
610  * See the documentation of notmuch_query_search_threads for example
611  * code showing how to iterate over a notmuch_threads_t object.
612  *
613  * If an out-of-memory situation occurs, this function will return
614  * NULL.
615  */
616 notmuch_thread_t *
617 notmuch_threads_get (notmuch_threads_t *threads);
618
619 /* Move the 'threads' iterator to the next thread.
620  *
621  * If 'threads' is already pointing at the last thread then the
622  * iterator will be moved to a point just beyond that last thread,
623  * (where notmuch_threads_valid will return FALSE and
624  * notmuch_threads_get will return NULL).
625  *
626  * See the documentation of notmuch_query_search_threads for example
627  * code showing how to iterate over a notmuch_threads_t object.
628  */
629 void
630 notmuch_threads_move_to_next (notmuch_threads_t *threads);
631
632 /* Destroy a notmuch_threads_t object.
633  *
634  * It's not strictly necessary to call this function. All memory from
635  * the notmuch_threads_t object will be reclaimed when the
636  * containing query object is destroyed.
637  */
638 void
639 notmuch_threads_destroy (notmuch_threads_t *threads);
640
641 /* Return an estimate of the number of messages matching a search
642  *
643  * This function performs a search and returns Xapian's best
644  * guess as to number of matching messages.
645  *
646  * If a Xapian exception occurs, this function may return 0 (after
647  * printing a message).
648  */
649 unsigned
650 notmuch_query_count_messages (notmuch_query_t *query);
651  
652 /* Return the number of threads matching a search.
653  *
654  * This function performs a search and returns the number of unique thread IDs
655  * in the matching messages. This is the same as number of threads matching a
656  * search.
657  *
658  * Note that this is a significantly heavier operation than
659  * notmuch_query_count_messages().
660  *
661  * If an error occurs, this function may return 0.
662  */
663 unsigned
664 notmuch_query_count_threads (notmuch_query_t *query);
665
666 /* Get the thread ID of 'thread'.
667  *
668  * The returned string belongs to 'thread' and as such, should not be
669  * modified by the caller and will only be valid for as long as the
670  * thread is valid, (which is until notmuch_thread_destroy or until
671  * the query from which it derived is destroyed).
672  */
673 const char *
674 notmuch_thread_get_thread_id (notmuch_thread_t *thread);
675
676 /* Get the total number of messages in 'thread'.
677  *
678  * This count consists of all messages in the database belonging to
679  * this thread. Contrast with notmuch_thread_get_matched_messages() .
680  */
681 int
682 notmuch_thread_get_total_messages (notmuch_thread_t *thread);
683
684 /* Get a notmuch_messages_t iterator for the top-level messages in
685  * 'thread'.
686  *
687  * This iterator will not necessarily iterate over all of the messages
688  * in the thread. It will only iterate over the messages in the thread
689  * which are not replies to other messages in the thread.
690  *
691  * To iterate over all messages in the thread, the caller will need to
692  * iterate over the result of notmuch_message_get_replies for each
693  * top-level message (and do that recursively for the resulting
694  * messages, etc.).
695  */
696 notmuch_messages_t *
697 notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread);
698
699 /* Get the number of messages in 'thread' that matched the search.
700  *
701  * This count includes only the messages in this thread that were
702  * matched by the search from which the thread was created and were
703  * not excluded by any exclude tags passed in with the query (see
704  * notmuch_query_add_tag_exclude). Contrast with
705  * notmuch_thread_get_total_messages() .
706  */
707 int
708 notmuch_thread_get_matched_messages (notmuch_thread_t *thread);
709
710 /* Get the authors of 'thread'
711  *
712  * The returned string is a comma-separated list of the names of the
713  * authors of mail messages in the query results that belong to this
714  * thread.
715  *
716  * The returned string belongs to 'thread' and as such, should not be
717  * modified by the caller and will only be valid for as long as the
718  * thread is valid, (which is until notmuch_thread_destroy or until
719  * the query from which it derived is destroyed).
720  */
721 const char *
722 notmuch_thread_get_authors (notmuch_thread_t *thread);
723
724 /* Get the subject of 'thread'
725  *
726  * The subject is taken from the first message (according to the query
727  * order---see notmuch_query_set_sort) in the query results that
728  * belongs to this thread.
729  *
730  * The returned string belongs to 'thread' and as such, should not be
731  * modified by the caller and will only be valid for as long as the
732  * thread is valid, (which is until notmuch_thread_destroy or until
733  * the query from which it derived is destroyed).
734  */
735 const char *
736 notmuch_thread_get_subject (notmuch_thread_t *thread);
737
738 /* Get the date of the oldest message in 'thread' as a time_t value.
739  */
740 time_t
741 notmuch_thread_get_oldest_date (notmuch_thread_t *thread);
742
743 /* Get the date of the newest message in 'thread' as a time_t value.
744  */
745 time_t
746 notmuch_thread_get_newest_date (notmuch_thread_t *thread);
747
748 /* Get the tags for 'thread', returning a notmuch_tags_t object which
749  * can be used to iterate over all tags.
750  *
751  * Note: In the Notmuch database, tags are stored on individual
752  * messages, not on threads. So the tags returned here will be all
753  * tags of the messages which matched the search and which belong to
754  * this thread.
755  *
756  * The tags object is owned by the thread and as such, will only be
757  * valid for as long as the thread is valid, (for example, until
758  * notmuch_thread_destroy or until the query from which it derived is
759  * destroyed).
760  *
761  * Typical usage might be:
762  *
763  *     notmuch_thread_t *thread;
764  *     notmuch_tags_t *tags;
765  *     const char *tag;
766  *
767  *     thread = notmuch_threads_get (threads);
768  *
769  *     for (tags = notmuch_thread_get_tags (thread);
770  *          notmuch_tags_valid (tags);
771  *          notmuch_result_move_to_next (tags))
772  *     {
773  *         tag = notmuch_tags_get (tags);
774  *         ....
775  *     }
776  *
777  *     notmuch_thread_destroy (thread);
778  *
779  * Note that there's no explicit destructor needed for the
780  * notmuch_tags_t object. (For consistency, we do provide a
781  * notmuch_tags_destroy function, but there's no good reason to call
782  * it if the message is about to be destroyed).
783  */
784 notmuch_tags_t *
785 notmuch_thread_get_tags (notmuch_thread_t *thread);
786
787 /* Destroy a notmuch_thread_t object. */
788 void
789 notmuch_thread_destroy (notmuch_thread_t *thread);
790
791 /* Is the given 'messages' iterator pointing at a valid message.
792  *
793  * When this function returns TRUE, notmuch_messages_get will return a
794  * valid object. Whereas when this function returns FALSE,
795  * notmuch_messages_get will return NULL.
796  *
797  * See the documentation of notmuch_query_search_messages for example
798  * code showing how to iterate over a notmuch_messages_t object.
799  */
800 notmuch_bool_t
801 notmuch_messages_valid (notmuch_messages_t *messages);
802
803 /* Get the current message from 'messages' as a notmuch_message_t.
804  *
805  * Note: The returned message belongs to 'messages' and has a lifetime
806  * identical to it (and the query to which it belongs).
807  *
808  * See the documentation of notmuch_query_search_messages for example
809  * code showing how to iterate over a notmuch_messages_t object.
810  *
811  * If an out-of-memory situation occurs, this function will return
812  * NULL.
813  */
814 notmuch_message_t *
815 notmuch_messages_get (notmuch_messages_t *messages);
816
817 /* Move the 'messages' iterator to the next message.
818  *
819  * If 'messages' is already pointing at the last message then the
820  * iterator will be moved to a point just beyond that last message,
821  * (where notmuch_messages_valid will return FALSE and
822  * notmuch_messages_get will return NULL).
823  *
824  * See the documentation of notmuch_query_search_messages for example
825  * code showing how to iterate over a notmuch_messages_t object.
826  */
827 void
828 notmuch_messages_move_to_next (notmuch_messages_t *messages);
829
830 /* Destroy a notmuch_messages_t object.
831  *
832  * It's not strictly necessary to call this function. All memory from
833  * the notmuch_messages_t object will be reclaimed when the containing
834  * query object is destroyed.
835  */
836 void
837 notmuch_messages_destroy (notmuch_messages_t *messages);
838
839 /* Return a list of tags from all messages.
840  *
841  * The resulting list is guaranteed not to contain duplicated tags.
842  *
843  * WARNING: You can no longer iterate over messages after calling this
844  * function, because the iterator will point at the end of the list.
845  * We do not have a function to reset the iterator yet and the only
846  * way how you can iterate over the list again is to recreate the
847  * message list.
848  *
849  * The function returns NULL on error.
850  */
851 notmuch_tags_t *
852 notmuch_messages_collect_tags (notmuch_messages_t *messages);
853
854 /* Get the message ID of 'message'.
855  *
856  * The returned string belongs to 'message' and as such, should not be
857  * modified by the caller and will only be valid for as long as the
858  * message is valid, (which is until the query from which it derived
859  * is destroyed).
860  *
861  * This function will not return NULL since Notmuch ensures that every
862  * message has a unique message ID, (Notmuch will generate an ID for a
863  * message if the original file does not contain one).
864  */
865 const char *
866 notmuch_message_get_message_id (notmuch_message_t *message);
867
868 /* Get the thread ID of 'message'.
869  *
870  * The returned string belongs to 'message' and as such, should not be
871  * modified by the caller and will only be valid for as long as the
872  * message is valid, (for example, until the user calls
873  * notmuch_message_destroy on 'message' or until a query from which it
874  * derived is destroyed).
875  *
876  * This function will not return NULL since Notmuch ensures that every
877  * message belongs to a single thread.
878  */
879 const char *
880 notmuch_message_get_thread_id (notmuch_message_t *message);
881
882 /* Get a notmuch_messages_t iterator for all of the replies to
883  * 'message'.
884  *
885  * Note: This call only makes sense if 'message' was ultimately
886  * obtained from a notmuch_thread_t object, (such as by coming
887  * directly from the result of calling notmuch_thread_get_
888  * toplevel_messages or by any number of subsequent
889  * calls to notmuch_message_get_replies).
890  *
891  * If 'message' was obtained through some non-thread means, (such as
892  * by a call to notmuch_query_search_messages), then this function
893  * will return NULL.
894  *
895  * If there are no replies to 'message', this function will return
896  * NULL. (Note that notmuch_messages_valid will accept that NULL
897  * value as legitimate, and simply return FALSE for it.)
898  */
899 notmuch_messages_t *
900 notmuch_message_get_replies (notmuch_message_t *message);
901
902 /* Get a filename for the email corresponding to 'message'.
903  *
904  * The returned filename is an absolute filename, (the initial
905  * component will match notmuch_database_get_path() ).
906  *
907  * The returned string belongs to the message so should not be
908  * modified or freed by the caller (nor should it be referenced after
909  * the message is destroyed).
910  *
911  * Note: If this message corresponds to multiple files in the mail
912  * store, (that is, multiple files contain identical message IDs),
913  * this function will arbitrarily return a single one of those
914  * filenames. See notmuch_message_get_filenames for returning the
915  * complete list of filenames.
916  */
917 const char *
918 notmuch_message_get_filename (notmuch_message_t *message);
919
920 /* Get all filenames for the email corresponding to 'message'.
921  *
922  * Returns a notmuch_filenames_t iterator listing all the filenames
923  * associated with 'message'. These files may not have identical
924  * content, but each will have the identical Message-ID.
925  *
926  * Each filename in the iterator is an absolute filename, (the initial
927  * component will match notmuch_database_get_path() ).
928  */
929 notmuch_filenames_t *
930 notmuch_message_get_filenames (notmuch_message_t *message);
931
932 /* Message flags */
933 typedef enum _notmuch_message_flag {
934     NOTMUCH_MESSAGE_FLAG_MATCH,
935     NOTMUCH_MESSAGE_FLAG_EXCLUDED
936 } notmuch_message_flag_t;
937
938 /* Get a value of a flag for the email corresponding to 'message'. */
939 notmuch_bool_t
940 notmuch_message_get_flag (notmuch_message_t *message,
941                           notmuch_message_flag_t flag);
942
943 /* Set a value of a flag for the email corresponding to 'message'. */
944 void
945 notmuch_message_set_flag (notmuch_message_t *message,
946                           notmuch_message_flag_t flag, notmuch_bool_t value);
947
948 /* Get the date of 'message' as a time_t value.
949  *
950  * For the original textual representation of the Date header from the
951  * message call notmuch_message_get_header() with a header value of
952  * "date". */
953 time_t
954 notmuch_message_get_date  (notmuch_message_t *message);
955
956 /* Get the value of the specified header from 'message'.
957  *
958  * The value will be read from the actual message file, not from the
959  * notmuch database. The header name is case insensitive.
960  *
961  * The returned string belongs to the message so should not be
962  * modified or freed by the caller (nor should it be referenced after
963  * the message is destroyed).
964  *
965  * Returns an empty string ("") if the message does not contain a
966  * header line matching 'header'. Returns NULL if any error occurs.
967  */
968 const char *
969 notmuch_message_get_header (notmuch_message_t *message, const char *header);
970
971 /* Get the tags for 'message', returning a notmuch_tags_t object which
972  * can be used to iterate over all tags.
973  *
974  * The tags object is owned by the message and as such, will only be
975  * valid for as long as the message is valid, (which is until the
976  * query from which it derived is destroyed).
977  *
978  * Typical usage might be:
979  *
980  *     notmuch_message_t *message;
981  *     notmuch_tags_t *tags;
982  *     const char *tag;
983  *
984  *     message = notmuch_database_find_message (database, message_id);
985  *
986  *     for (tags = notmuch_message_get_tags (message);
987  *          notmuch_tags_valid (tags);
988  *          notmuch_result_move_to_next (tags))
989  *     {
990  *         tag = notmuch_tags_get (tags);
991  *         ....
992  *     }
993  *
994  *     notmuch_message_destroy (message);
995  *
996  * Note that there's no explicit destructor needed for the
997  * notmuch_tags_t object. (For consistency, we do provide a
998  * notmuch_tags_destroy function, but there's no good reason to call
999  * it if the message is about to be destroyed).
1000  */
1001 notmuch_tags_t *
1002 notmuch_message_get_tags (notmuch_message_t *message);
1003
1004 /* The longest possible tag value. */
1005 #define NOTMUCH_TAG_MAX 200
1006
1007 /* Add a tag to the given message.
1008  *
1009  * Return value:
1010  *
1011  * NOTMUCH_STATUS_SUCCESS: Tag successfully added to message
1012  *
1013  * NOTMUCH_STATUS_NULL_POINTER: The 'tag' argument is NULL
1014  *
1015  * NOTMUCH_STATUS_TAG_TOO_LONG: The length of 'tag' is too long
1016  *      (exceeds NOTMUCH_TAG_MAX)
1017  *
1018  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
1019  *      mode so message cannot be modified.
1020  */
1021 notmuch_status_t
1022 notmuch_message_add_tag (notmuch_message_t *message, const char *tag);
1023
1024 /* Remove a tag from the given message.
1025  *
1026  * Return value:
1027  *
1028  * NOTMUCH_STATUS_SUCCESS: Tag successfully removed from message
1029  *
1030  * NOTMUCH_STATUS_NULL_POINTER: The 'tag' argument is NULL
1031  *
1032  * NOTMUCH_STATUS_TAG_TOO_LONG: The length of 'tag' is too long
1033  *      (exceeds NOTMUCH_TAG_MAX)
1034  *
1035  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
1036  *      mode so message cannot be modified.
1037  */
1038 notmuch_status_t
1039 notmuch_message_remove_tag (notmuch_message_t *message, const char *tag);
1040
1041 /* Remove all tags from the given message.
1042  *
1043  * See notmuch_message_freeze for an example showing how to safely
1044  * replace tag values.
1045  *
1046  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
1047  *      mode so message cannot be modified.
1048  */
1049 notmuch_status_t
1050 notmuch_message_remove_all_tags (notmuch_message_t *message);
1051
1052 /* Add/remove tags according to maildir flags in the message filename(s)
1053  *
1054  * This function examines the filenames of 'message' for maildir
1055  * flags, and adds or removes tags on 'message' as follows when these
1056  * flags are present:
1057  *
1058  *      Flag    Action if present
1059  *      ----    -----------------
1060  *      'D'     Adds the "draft" tag to the message
1061  *      'F'     Adds the "flagged" tag to the message
1062  *      'P'     Adds the "passed" tag to the message
1063  *      'R'     Adds the "replied" tag to the message
1064  *      'S'     Removes the "unread" tag from the message
1065  *
1066  * For each flag that is not present, the opposite action (add/remove)
1067  * is performed for the corresponding tags.
1068  *
1069  * Flags are identified as trailing components of the filename after a
1070  * sequence of ":2,".
1071  *
1072  * If there are multiple filenames associated with this message, the
1073  * flag is considered present if it appears in one or more
1074  * filenames. (That is, the flags from the multiple filenames are
1075  * combined with the logical OR operator.)
1076  *
1077  * A client can ensure that notmuch database tags remain synchronized
1078  * with maildir flags by calling this function after each call to
1079  * notmuch_database_add_message. See also
1080  * notmuch_message_tags_to_maildir_flags for synchronizing tag changes
1081  * back to maildir flags.
1082  */
1083 notmuch_status_t
1084 notmuch_message_maildir_flags_to_tags (notmuch_message_t *message);
1085
1086 /* Rename message filename(s) to encode tags as maildir flags
1087  *
1088  * Specifically, for each filename corresponding to this message:
1089  *
1090  * If the filename is not in a maildir directory, do nothing.  (A
1091  * maildir directory is determined as a directory named "new" or
1092  * "cur".) Similarly, if the filename has invalid maildir info,
1093  * (repeated or outof-ASCII-order flag characters after ":2,"), then
1094  * do nothing.
1095  *
1096  * If the filename is in a maildir directory, rename the file so that
1097  * its filename ends with the sequence ":2," followed by zero or more
1098  * of the following single-character flags (in ASCII order):
1099  *
1100  *   'D' iff the message has the "draft" tag
1101  *   'F' iff the message has the "flagged" tag
1102  *   'P' iff the message has the "passed" tag
1103  *   'R' iff the message has the "replied" tag
1104  *   'S' iff the message does not have the "unread" tag
1105  *
1106  * Any existing flags unmentioned in the list above will be preserved
1107  * in the renaming.
1108  *
1109  * Also, if this filename is in a directory named "new", rename it to
1110  * be within the neighboring directory named "cur".
1111  *
1112  * A client can ensure that maildir filename flags remain synchronized
1113  * with notmuch database tags by calling this function after changing
1114  * tags, (after calls to notmuch_message_add_tag,
1115  * notmuch_message_remove_tag, or notmuch_message_freeze/
1116  * notmuch_message_thaw). See also notmuch_message_maildir_flags_to_tags
1117  * for synchronizing maildir flag changes back to tags.
1118  */
1119 notmuch_status_t
1120 notmuch_message_tags_to_maildir_flags (notmuch_message_t *message);
1121
1122 /* Freeze the current state of 'message' within the database.
1123  *
1124  * This means that changes to the message state, (via
1125  * notmuch_message_add_tag, notmuch_message_remove_tag, and
1126  * notmuch_message_remove_all_tags), will not be committed to the
1127  * database until the message is thawed with notmuch_message_thaw.
1128  *
1129  * Multiple calls to freeze/thaw are valid and these calls will
1130  * "stack". That is there must be as many calls to thaw as to freeze
1131  * before a message is actually thawed.
1132  *
1133  * The ability to do freeze/thaw allows for safe transactions to
1134  * change tag values. For example, explicitly setting a message to
1135  * have a given set of tags might look like this:
1136  *
1137  *    notmuch_message_freeze (message);
1138  *
1139  *    notmuch_message_remove_all_tags (message);
1140  *
1141  *    for (i = 0; i < NUM_TAGS; i++)
1142  *        notmuch_message_add_tag (message, tags[i]);
1143  *
1144  *    notmuch_message_thaw (message);
1145  *
1146  * With freeze/thaw used like this, the message in the database is
1147  * guaranteed to have either the full set of original tag values, or
1148  * the full set of new tag values, but nothing in between.
1149  *
1150  * Imagine the example above without freeze/thaw and the operation
1151  * somehow getting interrupted. This could result in the message being
1152  * left with no tags if the interruption happened after
1153  * notmuch_message_remove_all_tags but before notmuch_message_add_tag.
1154  *
1155  * Return value:
1156  *
1157  * NOTMUCH_STATUS_SUCCESS: Message successfully frozen.
1158  *
1159  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
1160  *      mode so message cannot be modified.
1161  */
1162 notmuch_status_t
1163 notmuch_message_freeze (notmuch_message_t *message);
1164
1165 /* Thaw the current 'message', synchronizing any changes that may have
1166  * occurred while 'message' was frozen into the notmuch database.
1167  *
1168  * See notmuch_message_freeze for an example of how to use this
1169  * function to safely provide tag changes.
1170  *
1171  * Multiple calls to freeze/thaw are valid and these calls with
1172  * "stack". That is there must be as many calls to thaw as to freeze
1173  * before a message is actually thawed.
1174  *
1175  * Return value:
1176  *
1177  * NOTMUCH_STATUS_SUCCESS: Message successfully thawed, (or at least
1178  *      its frozen count has successfully been reduced by 1).
1179  *
1180  * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: An attempt was made to thaw
1181  *      an unfrozen message. That is, there have been an unbalanced
1182  *      number of calls to notmuch_message_freeze and
1183  *      notmuch_message_thaw.
1184  */
1185 notmuch_status_t
1186 notmuch_message_thaw (notmuch_message_t *message);
1187
1188 /* Destroy a notmuch_message_t object.
1189  *
1190  * It can be useful to call this function in the case of a single
1191  * query object with many messages in the result, (such as iterating
1192  * over the entire database). Otherwise, it's fine to never call this
1193  * function and there will still be no memory leaks. (The memory from
1194  * the messages get reclaimed when the containing query is destroyed.)
1195  */
1196 void
1197 notmuch_message_destroy (notmuch_message_t *message);
1198
1199 /* Is the given 'tags' iterator pointing at a valid tag.
1200  *
1201  * When this function returns TRUE, notmuch_tags_get will return a
1202  * valid string. Whereas when this function returns FALSE,
1203  * notmuch_tags_get will return NULL.
1204  *
1205  * See the documentation of notmuch_message_get_tags for example code
1206  * showing how to iterate over a notmuch_tags_t object.
1207  */
1208 notmuch_bool_t
1209 notmuch_tags_valid (notmuch_tags_t *tags);
1210
1211 /* Get the current tag from 'tags' as a string.
1212  *
1213  * Note: The returned string belongs to 'tags' and has a lifetime
1214  * identical to it (and the query to which it ultimately belongs).
1215  *
1216  * See the documentation of notmuch_message_get_tags for example code
1217  * showing how to iterate over a notmuch_tags_t object.
1218  */
1219 const char *
1220 notmuch_tags_get (notmuch_tags_t *tags);
1221
1222 /* Move the 'tags' iterator to the next tag.
1223  *
1224  * If 'tags' is already pointing at the last tag then the iterator
1225  * will be moved to a point just beyond that last tag, (where
1226  * notmuch_tags_valid will return FALSE and notmuch_tags_get will
1227  * return NULL).
1228  *
1229  * See the documentation of notmuch_message_get_tags for example code
1230  * showing how to iterate over a notmuch_tags_t object.
1231  */
1232 void
1233 notmuch_tags_move_to_next (notmuch_tags_t *tags);
1234
1235 /* Destroy a notmuch_tags_t object.
1236  *
1237  * It's not strictly necessary to call this function. All memory from
1238  * the notmuch_tags_t object will be reclaimed when the containing
1239  * message or query objects are destroyed.
1240  */
1241 void
1242 notmuch_tags_destroy (notmuch_tags_t *tags);
1243
1244 /* Store an mtime within the database for 'directory'.
1245  *
1246  * The 'directory' should be an object retrieved from the database
1247  * with notmuch_database_get_directory for a particular path.
1248  *
1249  * The intention is for the caller to use the mtime to allow efficient
1250  * identification of new messages to be added to the database. The
1251  * recommended usage is as follows:
1252  *
1253  *   o Read the mtime of a directory from the filesystem
1254  *
1255  *   o Call add_message for all mail files in the directory
1256  *
1257  *   o Call notmuch_directory_set_mtime with the mtime read from the
1258  *     filesystem.
1259  *
1260  * Then, when wanting to check for updates to the directory in the
1261  * future, the client can call notmuch_directory_get_mtime and know
1262  * that it only needs to add files if the mtime of the directory and
1263  * files are newer than the stored timestamp.
1264  *
1265  * Note: The notmuch_directory_get_mtime function does not allow the
1266  * caller to distinguish a timestamp of 0 from a non-existent
1267  * timestamp. So don't store a timestamp of 0 unless you are
1268  * comfortable with that.
1269  *
1270  * Return value:
1271  *
1272  * NOTMUCH_STATUS_SUCCESS: mtime successfully stored in database.
1273  *
1274  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception
1275  *      occurred, mtime not stored.
1276  *
1277  * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only
1278  *      mode so directory mtime cannot be modified.
1279  */
1280 notmuch_status_t
1281 notmuch_directory_set_mtime (notmuch_directory_t *directory,
1282                              time_t mtime);
1283
1284 /* Get the mtime of a directory, (as previously stored with
1285  * notmuch_directory_set_mtime).
1286  *
1287  * Returns 0 if no mtime has previously been stored for this
1288  * directory.*/
1289 time_t
1290 notmuch_directory_get_mtime (notmuch_directory_t *directory);
1291
1292 /* Get a notmuch_filenames_t iterator listing all the filenames of
1293  * messages in the database within the given directory.
1294  *
1295  * The returned filenames will be the basename-entries only (not
1296  * complete paths). */
1297 notmuch_filenames_t *
1298 notmuch_directory_get_child_files (notmuch_directory_t *directory);
1299
1300 /* Get a notmuch_filenams_t iterator listing all the filenames of
1301  * sub-directories in the database within the given directory.
1302  *
1303  * The returned filenames will be the basename-entries only (not
1304  * complete paths). */
1305 notmuch_filenames_t *
1306 notmuch_directory_get_child_directories (notmuch_directory_t *directory);
1307
1308 /* Destroy a notmuch_directory_t object. */
1309 void
1310 notmuch_directory_destroy (notmuch_directory_t *directory);
1311
1312 /* Is the given 'filenames' iterator pointing at a valid filename.
1313  *
1314  * When this function returns TRUE, notmuch_filenames_get will return
1315  * a valid string. Whereas when this function returns FALSE,
1316  * notmuch_filenames_get will return NULL.
1317  *
1318  * It is acceptable to pass NULL for 'filenames', in which case this
1319  * function will always return FALSE.
1320  */
1321 notmuch_bool_t
1322 notmuch_filenames_valid (notmuch_filenames_t *filenames);
1323
1324 /* Get the current filename from 'filenames' as a string.
1325  *
1326  * Note: The returned string belongs to 'filenames' and has a lifetime
1327  * identical to it (and the directory to which it ultimately belongs).
1328  *
1329  * It is acceptable to pass NULL for 'filenames', in which case this
1330  * function will always return NULL.
1331  */
1332 const char *
1333 notmuch_filenames_get (notmuch_filenames_t *filenames);
1334
1335 /* Move the 'filenames' iterator to the next filename.
1336  *
1337  * If 'filenames' is already pointing at the last filename then the
1338  * iterator will be moved to a point just beyond that last filename,
1339  * (where notmuch_filenames_valid will return FALSE and
1340  * notmuch_filenames_get will return NULL).
1341  *
1342  * It is acceptable to pass NULL for 'filenames', in which case this
1343  * function will do nothing.
1344  */
1345 void
1346 notmuch_filenames_move_to_next (notmuch_filenames_t *filenames);
1347
1348 /* Destroy a notmuch_filenames_t object.
1349  *
1350  * It's not strictly necessary to call this function. All memory from
1351  * the notmuch_filenames_t object will be reclaimed when the
1352  * containing directory object is destroyed.
1353  *
1354  * It is acceptable to pass NULL for 'filenames', in which case this
1355  * function will do nothing.
1356  */
1357 void
1358 notmuch_filenames_destroy (notmuch_filenames_t *filenames);
1359
1360 NOTMUCH_END_DECLS
1361
1362 #endif