notmuch_sys/lib.rs
1// Copyright © 2009 Carl Worth, 2015 Steven Allen
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see https://www.gnu.org/licenses/ .
15//
16
17#![allow(non_camel_case_types)]
18
19//! Not much of an email library, just index and search.
20
21extern crate libc;
22use libc::{c_void, c_char, time_t, c_uint, c_double, c_ulong, c_int};
23
24/// The longest possible tag value.
25pub const TAG_MAX: u32 = 200;
26
27/// Status codes used for the return values of most functions.
28///
29/// A zero value (SUCCESS) indicates that the function completed without error. Any other value
30/// indicates an error.
31#[repr(C)]
32#[derive(Debug, Eq, PartialEq, Clone, Copy)]
33pub enum notmuch_status_t {
34 /// No error occurred.
35 SUCCESS = 0,
36 /// Out of memory.
37 OUT_OF_MEMORY,
38 /// An attempt was made to write to a database opened in read-only
39 /// mode.
40 READ_ONLY_DATABASE,
41 /// A Xapian exception occurred.
42 ///
43 /// @todo We don't really want to expose this lame XAPIAN_EXCEPTION
44 /// value. Instead we should map to things like DATABASE_LOCKED or
45 /// whatever.
46 XAPIAN_EXCEPTION,
47 /// An error occurred trying to read or write to a file (this could
48 /// be file not found, permission denied, etc.)
49 FILE_ERROR,
50 /// A file was presented that doesn't appear to be an email
51 /// message.
52 FILE_NOT_EMAIL,
53 /// A file contains a message ID that is identical to a message
54 /// already in the database.
55 DUPLICATE_MESSAGE_ID,
56 /// The user erroneously passed a NULL pointer to a notmuch
57 /// function.
58 NULL_POINTER,
59 /// A tag value is too long (exceeds TAG_MAX).
60 TAG_TOO_LONG,
61 /// The `notmuch_message_thaw` function has been called more times
62 /// than `notmuch_message_freeze`.
63 UNBALANCED_FREEZE_THAW,
64 /// `notmuch_database_end_atomic` has been called more times than
65 /// `notmuch_database_begin_atomic`.
66 UNBALANCED_ATOMIC,
67 /// The operation is not supported.
68 UNSUPPORTED_OPERATION,
69 /// The operation requires a database upgrade.
70 UPGRADE_REQUIRED,
71 /// There is a problem with the proposed path, e.g. a relative path
72 /// passed to a function expecting an absolute path.
73 PATH_ERROR,
74 /// One of the arguments violates the preconditions for the
75 /// function, in a way not covered by a more specific argument.
76 NOTMUCH_STATUS_ILLEGAL_ARGUMENT,
77}
78
79/// Sort values for `notmuch_query_set_sort`.
80#[repr(C)]
81#[derive(Debug, Eq, PartialEq, Clone, Copy)]
82pub enum notmuch_sort_t {
83 /// Oldest first.
84 OLDEST_FIRST = 0,
85 /// Newest first.
86 NEWEST_FIRST,
87 /// Sort by message-id.
88 MESSAGE_ID,
89 /// Do not sort.
90 UNSORTED,
91}
92
93/// Exclude values for `notmuch_query_set_omit_excluded`
94#[repr(C)]
95#[derive(Debug, Eq, PartialEq, Clone, Copy)]
96pub enum notmuch_exclude_t {
97 FLAG = 0,
98 TRUE,
99 FALSE,
100 ALL,
101}
102
103/// Message flags.
104#[repr(C)]
105#[derive(Debug, Eq, PartialEq, Clone, Copy)]
106pub enum notmuch_message_flag_t {
107 MATCH = 0,
108 EXCLUDED,
109 /// This message is a "ghost message", meaning it has no filenames
110 /// or content, but we know it exists because it was referenced by
111 /// some other message. A ghost message has only a message ID and
112 /// thread ID.
113 GHOST,
114}
115
116/// Database open mode for `notmuch_database_open`.
117#[repr(C)]
118#[derive(Debug, Eq, PartialEq, Clone, Copy)]
119pub enum notmuch_database_mode_t {
120 /// Open database for reading only.
121 READ_ONLY = 0,
122 /// Open database for reading and writing.
123 READ_WRITE,
124}
125
126pub enum notmuch_database_t {}
127pub enum notmuch_query_t {}
128pub enum notmuch_threads_t {}
129pub enum notmuch_thread_t {}
130pub enum notmuch_messages_t {}
131pub enum notmuch_message_t {}
132pub enum notmuch_tags_t {}
133pub enum notmuch_message_properties_t {}
134pub enum notmuch_directory_t {}
135pub enum notmuch_filenames_t {}
136pub enum notmuch_config_list_t {}
137pub type notmuch_bool_t = c_int;
138
139pub const TRUE: notmuch_bool_t = 1;
140pub const FALSE: notmuch_bool_t = 0;
141
142
143#[link(name = "notmuch")]
144extern "C" {
145 /// Open an existing notmuch database located at 'path'.
146 ///
147 /// The database should have been created at some time in the past,
148 /// (not necessarily by this process), by calling
149 /// notmuch_database_create with 'path'. By default the database should be
150 /// opened for reading only. In order to write to the database you need to
151 /// pass the `notmuch_database_mode_t::READ_WRITE` mode.
152 ///
153 /// An existing notmuch database can be identified by the presence of a
154 /// directory named ".notmuch" below 'path'.
155 ///
156 /// The caller should call notmuch_database_destroy when finished with
157 /// this database.
158 ///
159 /// In case of any failure, this function returns an error status and
160 /// sets *database to NULL (after printing an error message on stderr).
161 ///
162 /// Return value:
163 ///
164 /// * `notmuch_status_t::SUCCESS`: Successfully opened the database.
165 ///
166 /// * `notmuch_status_t::NULL_POINTER`: The given 'path' argument is NULL.
167 ///
168 /// * `notmuch_status_t::OUT_OF_MEMORY`: Out of memory.
169 ///
170 /// * `notmuch_status_t::FILE_ERROR`: An error occurred trying to open the
171 /// database file (such as permission denied, or file not found,
172 /// etc.), or the database version is unknown.
173 ///
174 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred.
175 pub fn notmuch_database_open(path: *const c_char,
176 mode: notmuch_database_mode_t,
177 database: *mut *mut notmuch_database_t)
178 -> notmuch_status_t;
179
180 /// Like notmuch_database_open, except optionally return an error
181 /// message. This message is allocated by malloc and should be freed by
182 /// the caller.
183 pub fn notmuch_database_open_verbose(path: *const c_char,
184 mode: notmuch_database_mode_t,
185 database: *mut *mut notmuch_database_t,
186 error_message: *mut *mut c_char)
187 -> notmuch_status_t;
188
189 /// Get a string representation of a `notmuch_status_t` value.
190 ///
191 /// The result is read-only.
192 pub fn notmuch_status_to_string(status: notmuch_status_t) -> *const c_char;
193
194 /// Create a new, empty notmuch database located at 'path'.
195 ///
196 /// The path should be a top-level directory to a collection of
197 /// plain-text email messages (one message per file). This call will
198 /// create a new ".notmuch" directory within 'path' where notmuch will
199 /// store its data.
200 ///
201 /// After a successful call to `notmuch_database_create`, the returned
202 /// database will be open so the caller should call
203 /// `notmuch_database_destroy` when finished with it.
204 ///
205 /// The database will not yet have any data in it
206 /// (`notmuch_database_create` itself is a very cheap function). Messages
207 /// contained within 'path' can be added to the database by calling
208 /// `notmuch_database_add_message`.
209 ///
210 /// In case of any failure, this function returns an error status and
211 /// sets *database to NULL (after printing an error message on stderr).
212 ///
213 /// Return value:
214 ///
215 /// * `notmuch_status_t::SUCCESS`: Successfully created the database.
216 ///
217 /// * `notmuch_status_t::NULL_POINTER`: The given 'path' argument is NULL.
218 ///
219 /// * `notmuch_status_t::OUT_OF_MEMORY`: Out of memory.
220 ///
221 /// * `notmuch_status_t::FILE_ERROR`: An error occurred trying to create the
222 /// database file (such as permission denied, or file not found,
223 /// etc.), or the database already exists.
224 ///
225 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred.
226 pub fn notmuch_database_create(path: *const c_char,
227 database: *mut *mut notmuch_database_t)
228 -> notmuch_status_t;
229
230 /// Like `notmuch_database_create`, except optionally return an error
231 /// message. This message is allocated by malloc and should be freed by
232 /// the caller.
233 pub fn notmuch_database_create_verbose(path: *const c_char,
234 database: *mut *mut notmuch_database_t,
235 error_message: *mut *const c_char)
236 -> notmuch_status_t;
237
238
239 /// Retrieve last status string for given database.
240 pub fn notmuch_database_status_string(notmuch: *mut notmuch_database_t) -> *const c_char;
241
242 /// Commit changes and close the given notmuch database.
243 ///
244 /// After `notmuch_database_close` has been called, calls to other
245 /// functions on objects derived from this database may either behave
246 /// as if the database had not been closed (e.g., if the required data
247 /// has been cached) or may fail with a
248 /// `notmuch_status_t::XAPIAN_EXCEPTION`. The only further operation
249 /// permitted on the database itself is to call `notmuch_database_destroy`.
250 ///
251 /// `notmuch_database_close` can be called multiple times. Later calls have
252 /// no effect.
253 ///
254 /// For writable databases, `notmuch_database_close` commits all changes
255 /// to disk before closing the database. If the caller is currently in
256 /// an atomic section (there was a `notmuch_database_begin_atomic`
257 /// without a matching `notmuch_database_end_atomic`), this will discard
258 /// changes made in that atomic section (but still commit changes made
259 /// prior to entering the atomic section).
260 ///
261 /// Return value:
262 ///
263 /// * `notmuch_status_t::SUCCESS`: Successfully closed the database.
264 ///
265 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred; the
266 /// database has been closed but there are no guarantees the
267 /// changes to the database, if any, have been flushed to disk.
268 pub fn notmuch_database_close(database: *mut notmuch_database_t) -> notmuch_status_t;
269
270 /// Compact a notmuch database, backing up the original database to the
271 /// given path.
272 ///
273 /// The database will be opened with notmuch_database_mode_t::READ_WRITE
274 /// during the compaction process to ensure no writes are made.
275 ///
276 /// If the optional callback function 'status_cb' is non-NULL, it will
277 /// be called with diagnostic and informational messages. The argument
278 /// 'closure' is passed verbatim to any callback invoked.
279 pub fn notmuch_database_compact(path: *const c_char,
280 backup_path: *const c_char,
281 status_cb: Option<extern "C" fn(message: *const c_char,
282 closure: *mut c_void)
283 >,
284 closure: *mut c_void)
285 -> notmuch_status_t;
286 /// Destroy the notmuch database, closing it if necessary and freeing
287 /// all associated resources.
288 ///
289 /// Return value as in `notmuch_database_close` if the database was open;
290 /// `notmuch_database_destroy` itself has no failure modes.
291 pub fn notmuch_database_destroy(database: *mut notmuch_database_t) -> notmuch_status_t;
292
293 /// Return the database path of the given database.
294 ///
295 /// The return value is a string owned by notmuch so should not be
296 /// modified nor freed by the caller.
297 pub fn notmuch_database_get_path(database: *mut notmuch_database_t) -> *const c_char;
298
299 /// Return the database format version of the given database.
300 pub fn notmuch_database_get_version(database: *mut notmuch_database_t) -> c_uint;
301
302 /// Can the database be upgraded to a newer database version?
303 ///
304 /// If this function returns TRUE, then the caller may call
305 /// `notmuch_database_upgrade` to upgrade the database. If the caller
306 /// does not upgrade an out-of-date database, then some functions may
307 /// fail with `notmuch_status_t::UPGRADE_REQUIRED`. This always returns
308 /// FALSE for a read-only database because there's no way to upgrade a
309 /// read-only database.
310 pub fn notmuch_database_needs_upgrade(database: *mut notmuch_database_t) -> notmuch_bool_t;
311
312 /// Upgrade the current database to the latest supported version.
313 ///
314 /// This ensures that all current notmuch functionality will be
315 /// available on the database. After opening a database in read-write
316 /// mode, it is recommended that clients check if an upgrade is needed
317 /// (`notmuch_database_needs_upgrade`) and if so, upgrade with this
318 /// function before making any modifications. If
319 /// `notmuch_database_needs_upgrade` returns FALSE, this will be a no-op.
320 ///
321 /// The optional progress_notify callback can be used by the caller to
322 /// provide progress indication to the user. If non-NULL it will be
323 /// called periodically with 'progress' as a floating-point value in
324 /// the range of [0.0 .. 1.0] indicating the progress made so far in
325 /// the upgrade process. The argument 'closure' is passed verbatim to
326 /// any callback invoked.
327 pub fn notmuch_database_upgrade(database: *mut notmuch_database_t,
328 progress_notify: Option<extern "C" fn(closure: *mut c_void,
329 progress: c_double)
330 >,
331 closure: *mut c_void)
332 -> notmuch_status_t;
333
334 /// Begin an atomic database operation.
335 ///
336 /// Any modifications performed between a successful begin and a
337 /// `notmuch_database_end_atomic` will be applied to the database
338 /// atomically. Note that, unlike a typical database transaction, this
339 /// only ensures atomicity, not durability; neither begin nor end
340 /// necessarily flush modifications to disk.
341 ///
342 /// Atomic sections may be nested. begin_atomic and end_atomic must
343 /// always be called in pairs.
344 ///
345 /// Return value:
346 ///
347 /// * `notmuch_status_t::SUCCESS`: Successfully entered atomic section.
348 ///
349 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred;
350 /// atomic section not entered.
351 pub fn notmuch_database_begin_atomic(notmuch: *mut notmuch_database_t) -> notmuch_status_t;
352
353 /// Indicate the end of an atomic database operation.
354 ///
355 /// Return value:
356 ///
357 /// * `notmuch_status_t::SUCCESS`: Successfully completed atomic section.
358 ///
359 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred;
360 /// atomic section not ended.
361 ///
362 /// * `notmuch_status_t::UNBALANCED_ATOMIC`: The database is not currently in
363 /// an atomic section.
364 pub fn notmuch_database_end_atomic(notmuch: *mut notmuch_database_t) -> notmuch_status_t;
365
366 /// Return the committed database revision and UUID.
367 ///
368 /// The database revision number increases monotonically with each
369 /// commit to the database. Hence, all messages and message changes
370 /// committed to the database (that is, visible to readers) have a last
371 /// modification revision <= the committed database revision. Any
372 /// messages committed in the future will be assigned a modification
373 /// revision > the committed database revision.
374 ///
375 /// The UUID is a NUL-terminated opaque string that uniquely identifies
376 /// this database. Two revision numbers are only comparable if they
377 /// have the same database UUID.
378 pub fn notmuch_database_get_revision(notmuch: *mut notmuch_database_t,
379 uuid: *mut *const c_char)
380 -> c_ulong;
381
382 /// Retrieve a directory object from the database for 'path'.
383 ///
384 /// Here, 'path' should be a path relative to the path of 'database'
385 /// (see `notmuch_database_get_path`), or else should be an absolute path
386 /// with initial components that match the path of 'database'.
387 ///
388 /// If this directory object does not exist in the database, this
389 /// returns `notmuch_status_t::SUCCESS` and sets *directory to NULL.
390 ///
391 /// Otherwise the returned directory object is owned by the database
392 /// and as such, will only be valid until `notmuch_database_destroy` is
393 /// called.
394 ///
395 /// Return value:
396 ///
397 /// * `notmuch_status_t::SUCCESS`: Successfully retrieved directory.
398 ///
399 /// * `notmuch_status_t::NULL_POINTER`: The given 'directory' argument is NULL.
400 ///
401 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred;
402 /// directory not retrieved.
403 ///
404 /// * `notmuch_status_t::UPGRADE_REQUIRED`: The caller must upgrade the
405 /// database to use this function.
406 pub fn notmuch_database_get_directory(database: *mut notmuch_database_t,
407 path: *const c_char,
408 directory: *mut *mut notmuch_directory_t)
409 -> notmuch_status_t;
410
411 /// Add a new message to the given notmuch database or associate an
412 /// additional filename with an existing message.
413 ///
414 /// Here, 'filename' should be a path relative to the path of
415 /// 'database' (see `notmuch_database_get_path`), or else should be an
416 /// absolute filename with initial components that match the path of
417 /// 'database'.
418 ///
419 /// The file should be a single mail message (not a multi-message mbox)
420 /// that is expected to remain at its current location, (since the
421 /// notmuch database will reference the filename, and will not copy the
422 /// entire contents of the file.
423 ///
424 /// If another message with the same message ID already exists in the
425 /// database, rather than creating a new message, this adds 'filename'
426 /// to the list of the filenames for the existing message.
427 ///
428 /// If 'message' is not NULL, then, on successful return
429 /// (notmuch_status_t::SUCCESS or `notmuch_status_t::DUPLICATE_MESSAGE_ID`) '*message'
430 /// will be initialized to a message object that can be used for things
431 /// such as adding tags to the just-added message. The user should call
432 /// `notmuch_message_destroy` when done with the message. On any failure
433 /// '*message' will be set to NULL.
434 ///
435 /// Return value:
436 ///
437 /// * `notmuch_status_t::SUCCESS`: Message successfully added to database.
438 ///
439 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred,
440 /// message not added.
441 ///
442 /// * `notmuch_status_t::DUPLICATE_MESSAGE_ID`: Message has the same message
443 /// ID as another message already in the database. The new
444 /// filename was successfully added to the message in the database
445 /// (if not already present) and the existing message is returned.
446 ///
447 /// * `notmuch_status_t::FILE_ERROR`: an error occurred trying to open the
448 /// file, (such as permission denied, or file not found,
449 /// etc.). Nothing added to the database.
450 ///
451 /// * `notmuch_status_t::FILE_NOT_EMAIL`: the contents of filename don't look
452 /// like an email message. Nothing added to the database.
453 ///
454 /// * `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only
455 /// mode so no message can be added.
456 ///
457 /// * `notmuch_status_t::UPGRADE_REQUIRED`: The caller must upgrade the
458 /// database to use this function.
459 pub fn notmuch_database_add_message(database: *mut notmuch_database_t,
460 filename: *const c_char,
461 message: *mut *mut notmuch_message_t)
462 -> notmuch_status_t;
463
464 /// Remove a message filename from the given notmuch database. If the
465 /// message has no more filenames, remove the message.
466 ///
467 /// If the same message (as determined by the message ID) is still
468 /// available via other filenames, then the message will persist in the
469 /// database for those filenames. When the last filename is removed for
470 /// a particular message, the database content for that message will be
471 /// entirely removed.
472 ///
473 /// Return value:
474 ///
475 /// * `notmuch_status_t::SUCCESS`: The last filename was removed and the
476 /// message was removed from the database.
477 ///
478 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred,
479 /// message not removed.
480 ///
481 /// * `notmuch_status_t::DUPLICATE_MESSAGE_ID`: This filename was removed but
482 /// the message persists in the database with at least one other
483 /// filename.
484 ///
485 /// * `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only
486 /// mode so no message can be removed.
487 ///
488 /// * `notmuch_status_t::UPGRADE_REQUIRED`: The caller must upgrade the
489 /// database to use this function.
490 pub fn notmuch_database_remove_message(database: *mut notmuch_database_t,
491 filename: *const c_char)
492 -> notmuch_status_t;
493
494 /// Find a message with the given message_id.
495 ///
496 /// If a message with the given message_id is found then, on successful return
497 /// (`notmuch_status_t::SUCCESS`) '*message' will be initialized to a message
498 /// object. The caller should call `notmuch_message_destroy` when done with the
499 /// message.
500 ///
501 /// On any failure or when the message is not found, this function initializes
502 /// '*message' to NULL. This means, when `notmuch_status_t::SUCCESS` is returned, the
503 /// caller is supposed to check '*message' for NULL to find out whether the
504 /// message with the given message_id was found.
505 ///
506 /// Return value:
507 ///
508 /// * `notmuch_status_t::SUCCESS`: Successful return, check '*message'.
509 ///
510 /// * `notmuch_status_t::NULL_POINTER`: The given 'message' argument is NULL
511 ///
512 /// * `notmuch_status_t::OUT_OF_MEMORY`: Out of memory, creating message object
513 ///
514 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred
515 pub fn notmuch_database_find_message(database: *mut notmuch_database_t,
516 message_id: *const c_char,
517 message: *mut *mut notmuch_message_t)
518 -> notmuch_status_t;
519
520 /// Find a message with the given filename.
521 ///
522 /// If the database contains a message with the given filename then, on
523 /// successful return (`notmuch_status_t::SUCCESS`) '*message' will be initialized to
524 /// a message object. The caller should call `notmuch_message_destroy` when done
525 /// with the message.
526 ///
527 /// On any failure or when the message is not found, this function initializes
528 /// '*message' to NULL. This means, when `notmuch_status_t::SUCCESS` is returned, the
529 /// caller is supposed to check '*message' for NULL to find out whether the
530 /// message with the given filename is found.
531 ///
532 /// Return value:
533 ///
534 /// * `notmuch_status_t::SUCCESS`: Successful return, check '*message'
535 ///
536 /// * `notmuch_status_t::NULL_POINTER`: The given 'message' argument is NULL
537 ///
538 /// * `notmuch_status_t::OUT_OF_MEMORY`: Out of memory, creating the message object
539 ///
540 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred
541 ///
542 /// * `notmuch_status_t::UPGRADE_REQUIRED`: The caller must upgrade the
543 /// database to use this function.
544 pub fn notmuch_database_find_message_by_filename(notmuch: *mut notmuch_database_t,
545 filename: *const c_char,
546 message: *mut *mut notmuch_message_t)
547 -> notmuch_status_t;
548
549 /// Return a list of all tags found in the database.
550 ///
551 /// This function creates a list of all tags found in the database. The
552 /// resulting list contains all tags from all messages found in the database.
553 ///
554 /// On error this function returns NULL.
555 pub fn notmuch_database_get_all_tags(db: *mut notmuch_database_t) -> *mut notmuch_tags_t;
556
557 /// Create a new query for 'database'.
558 ///
559 /// Here, 'database' should be an open database, (see
560 /// notmuch_database_open and `notmuch_database_create`).
561 ///
562 /// For the query string, we'll document the syntax here more
563 /// completely in the future, but it's likely to be a specialized
564 /// version of the general Xapian query syntax:
565 ///
566 /// https://xapian.org/docs/queryparser.html
567 ///
568 /// As a special case, passing either a length-zero string, (that is ""),
569 /// or a string consisting of a single asterisk (that is "*"), will
570 /// result in a query that returns all messages in the database.
571 ///
572 /// See `notmuch_query_set_sort` for controlling the order of results.
573 /// See notmuch_query_search_messages and `notmuch_query_search_threads`
574 /// to actually execute the query.
575 ///
576 /// User should call `notmuch_query_destroy` when finished with this
577 /// query.
578 ///
579 /// Will return NULL if insufficient memory is available.
580 pub fn notmuch_query_create(database: *mut notmuch_database_t,
581 query_string: *const c_char)
582 -> *mut notmuch_query_t;
583
584 /// Return the query_string of this query. See `notmuch_query_create`.
585 pub fn notmuch_query_get_query_string(query: *const notmuch_query_t) -> *const c_char;
586
587 /// Return the notmuch database of this query. See `notmuch_query_create`.
588 pub fn notmuch_query_get_database(query: *const notmuch_query_t) -> *mut notmuch_database_t;
589
590 /// Specify whether to omit excluded results or simply flag them. By
591 /// default, this is set to TRUE.
592 ///
593 /// If set to TRUE or ALL, `notmuch_query_search_messages` will omit excluded
594 /// messages from the results, and `notmuch_query_search_threads` will omit
595 /// threads that match only in excluded messages. If set to TRUE,
596 /// `notmuch_query_search_threads` will include all messages in threads that
597 /// match in at least one non-excluded message. Otherwise, if set to ALL,
598 /// `notmuch_query_search_threads` will omit excluded messages from all threads.
599 ///
600 /// If set to FALSE or FLAG then both `notmuch_query_search_messages` and
601 /// `notmuch_query_search_threads` will return all matching
602 /// messages/threads regardless of exclude status. If set to FLAG then
603 /// the exclude flag will be set for any excluded message that is
604 /// returned by `notmuch_query_search_messages`, and the thread counts
605 /// for threads returned by `notmuch_query_search_threads` will be the
606 /// number of non-excluded messages/matches. Otherwise, if set to
607 /// FALSE, then the exclude status is completely ignored.
608 ///
609 /// The performance difference when calling
610 /// `notmuch_query_search_messages` should be relatively small (and both
611 /// should be very fast). However, in some cases,
612 /// `notmuch_query_search_threads` is very much faster when omitting
613 /// excluded messages as it does not need to construct the threads that
614 /// only match in excluded messages.
615 pub fn notmuch_query_set_omit_excluded(query: *mut notmuch_query_t,
616 omit_excluded: notmuch_exclude_t);
617
618 /// Specify the sorting desired for this query.
619 pub fn notmuch_query_set_sort(query: *mut notmuch_query_t, sort: notmuch_sort_t);
620
621 /// Return the sort specified for this query. See
622 /// `notmuch_query_set_sort`.
623 pub fn notmuch_query_get_sort(query: *const notmuch_query_t) -> notmuch_sort_t;
624
625 /// Add a tag that will be excluded from the query results by default.
626 /// This exclusion will be overridden if this tag appears explicitly in
627 /// the query.
628 pub fn notmuch_query_add_tag_exclude(query: *mut notmuch_query_t, tag: *const c_char);
629
630 /// Execute a query for threads, returning a `notmuch_threads_t` object
631 /// which can be used to iterate over the results. The returned threads
632 /// object is owned by the query and as such, will only be valid until
633 /// `notmuch_query_destroy`.
634 ///
635 /// Typical usage might be:
636 ///
637 /// ```norun
638 /// notmuch_query_t *query;
639 /// notmuch_threads_t *threads;
640 /// notmuch_thread_t *thread;
641 ///
642 /// query = notmuch_query_create (database, query_string);
643 ///
644 /// for (threads = notmuch_query_search_threads (query);
645 /// notmuch_threads_valid (threads);
646 /// notmuch_threads_move_to_next (threads))
647 /// {
648 /// thread = notmuch_threads_get (threads);
649 /// ....
650 /// notmuch_thread_destroy (thread);
651 /// }
652 ///
653 /// notmuch_query_destroy (query);
654 /// ```
655 ///
656 /// Note: If you are finished with a thread before its containing
657 /// query, you can call `notmuch_thread_destroy` to clean up some memory
658 /// sooner (as in the above example). Otherwise, if your thread objects
659 /// are long-lived, then you don't need to call `notmuch_thread_destroy`
660 /// and all the memory will still be reclaimed when the query is
661 /// destroyed.
662 ///
663 /// Note that there's no explicit destructor needed for the
664 /// `notmuch_threads_t` object. (For consistency, we do provide a
665 /// `notmuch_threads_destroy` function, but there's no good reason
666 /// to call it if the query is about to be destroyed).
667 ///
668 /// @since libnotmuch 4.2 (notmuch 0.20)
669 pub fn notmuch_query_search_threads_st(query: *mut notmuch_query_t,
670 out: *mut *mut notmuch_threads_t)
671 -> notmuch_status_t;
672
673 /// Execute a query for messages, returning a `notmuch_messages_t` object
674 /// which can be used to iterate over the results. The returned
675 /// messages object is owned by the query and as such, will only be
676 /// valid until `notmuch_query_destroy`.
677 ///
678 /// Typical usage might be:
679 ///
680 /// ```norun
681 /// notmuch_query_t *query;
682 /// notmuch_messages_t *messages;
683 /// notmuch_message_t *message;
684 ///
685 /// query = notmuch_query_create (database, query_string);
686 ///
687 /// for (messages = notmuch_query_search_messages (query);
688 /// notmuch_messages_valid (messages);
689 /// notmuch_messages_move_to_next (messages))
690 /// {
691 /// message = notmuch_messages_get (messages);
692 /// ....
693 /// notmuch_message_destroy (message);
694 /// }
695 ///
696 /// notmuch_query_destroy (query);
697 /// ```
698 ///
699 /// Note: If you are finished with a message before its containing
700 /// query, you can call `notmuch_message_destroy` to clean up some memory
701 /// sooner (as in the above example). Otherwise, if your message
702 /// objects are long-lived, then you don't need to call
703 /// `notmuch_message_destroy` and all the memory will still be reclaimed
704 /// when the query is destroyed.
705 ///
706 /// Note that there's no explicit destructor needed for the
707 /// `notmuch_messages_t` object. (For consistency, we do provide a
708 /// `notmuch_messages_destroy` function, but there's no good
709 /// reason to call it if the query is about to be destroyed).
710 ///
711 /// If a Xapian exception occurs this function will return NULL.
712 ///
713 /// @since libnotmuch 4.2 (notmuch 0.20)
714 pub fn notmuch_query_search_messages_st(query: *mut notmuch_query_t,
715 out: *mut *mut notmuch_messages_t)
716 -> notmuch_status_t;
717
718 /// Destroy a `notmuch_query_t` along with any associated resources.
719 ///
720 /// This will in turn destroy any `notmuch_threads_t` and
721 /// `notmuch_messages_t` objects generated by this query, (and in
722 /// turn any notmuch_thread_t and `notmuch_message_t` objects generated
723 /// from those results, etc.), if such objects haven't already been
724 /// destroyed.
725 pub fn notmuch_query_destroy(query: *mut notmuch_query_t);
726
727 /// Is the given 'threads' iterator pointing at a valid thread.
728 ///
729 /// When this function returns TRUE, `notmuch_threads_get` will return a
730 /// valid object. Whereas when this function returns FALSE,
731 /// `notmuch_threads_get` will return NULL.
732 ///
733 /// If passed a NULL pointer, this function returns FALSE
734 ///
735 /// See the documentation of `notmuch_query_search_threads` for example
736 /// code showing how to iterate over a `notmuch_threads_t` object.
737 pub fn notmuch_threads_valid(threads: *mut notmuch_threads_t) -> notmuch_bool_t;
738
739 /// Get the current thread from 'threads' as a `notmuch_thread_t`.
740 ///
741 /// Note: The returned thread belongs to 'threads' and has a lifetime
742 /// identical to it (and the query to which it belongs).
743 ///
744 /// See the documentation of `notmuch_query_search_threads` for example
745 /// code showing how to iterate over a `notmuch_threads_t` object.
746 ///
747 /// If an out-of-memory situation occurs, this function will return
748 /// NULL.
749 pub fn notmuch_threads_get(threads: *mut notmuch_threads_t) -> *mut notmuch_thread_t;
750
751 /// Move the 'threads' iterator to the next thread.
752 ///
753 /// If 'threads' is already pointing at the last thread then the
754 /// iterator will be moved to a point just beyond that last thread,
755 /// (where `notmuch_threads_valid` will return FALSE and
756 /// `notmuch_threads_get` will return NULL).
757 ///
758 /// See the documentation of `notmuch_query_search_threads` for example
759 /// code showing how to iterate over a `notmuch_threads_t` object.
760 pub fn notmuch_threads_move_to_next(threads: *const notmuch_threads_t);
761
762 /// Destroy a `notmuch_threads_t` object.
763 ///
764 /// It's not strictly necessary to call this function. All memory from
765 /// the `notmuch_threads_t` object will be reclaimed when the
766 /// containing query object is destroyed.
767 pub fn notmuch_threads_destroy(threads: *mut notmuch_threads_t);
768
769 /// Return the number of messages matching a search.
770 ///
771 /// This function performs a search and returns the number of matching
772 /// messages.
773 ///
774 /// @returns
775 ///
776 /// `notmuch_status_t::SUCCESS`: query completed successfully.
777 ///
778 /// `notmuch_status_t::XAPIAN_EXCEPTION`: a Xapian exception occured. The
779 /// value of *count is not defined.
780 ///
781 /// @since libnotmuch 4.3 (notmuch 0.21)
782 pub fn notmuch_query_count_messages_st(query: *mut notmuch_query_t,
783 count: *mut c_uint)
784 -> notmuch_status_t;
785
786 /// Return the number of threads matching a search.
787 ///
788 /// This function performs a search and returns the number of unique thread IDs
789 /// in the matching messages. This is the same as number of threads matching a
790 /// search.
791 ///
792 /// Note that this is a significantly heavier operation than
793 /// `notmuch_query_count_messages`{_st}().
794 ///
795 /// @returns
796 ///
797 /// * `notmuch_status_t::OUT_OF_MEMORY`: Memory allocation failed. The value
798 /// of *count is not defined
799
800 /// * `notmuch_status_t::SUCCESS`: query completed successfully.
801 ///
802 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: a Xapian exception occured. The
803 /// value of *count is not defined.
804 ///
805 /// @since libnotmuch 4.3 (notmuch 0.21)
806 pub fn notmuch_query_count_threads_st(query: *mut notmuch_query_t,
807 count: *mut c_uint)
808 -> notmuch_status_t;
809
810 /// Get the thread ID of 'thread'.
811 ///
812 /// The returned string belongs to 'thread' and as such, should not be
813 /// modified by the caller and will only be valid for as long as the
814 /// thread is valid, (which is until `notmuch_thread_destroy` or until
815 /// the query from which it derived is destroyed).
816 pub fn notmuch_thread_get_thread_id(thread: *mut notmuch_thread_t) -> *const c_char;
817
818 /// Get the total number of messages in 'thread'.
819 ///
820 /// This count consists of all messages in the database belonging to
821 /// this thread. Contrast with `notmuch_thread_get_matched_messages`().
822 pub fn notmuch_thread_get_total_messages(thread: *mut notmuch_thread_t) -> c_int;
823
824 /// Get a `notmuch_messages_t` iterator for the top-level messages in
825 /// 'thread' in oldest-first order.
826 ///
827 /// This iterator will not necessarily iterate over all of the messages
828 /// in the thread. It will only iterate over the messages in the thread
829 /// which are not replies to other messages in the thread.
830 ///
831 /// The returned list will be destroyed when the thread is destroyed.
832 pub fn notmuch_thread_get_toplevel_messages(thread: *mut notmuch_thread_t)
833 -> *mut notmuch_messages_t;
834
835 /// Get a `notmuch_thread_t` iterator for all messages in 'thread' in
836 /// oldest-first order.
837 ///
838 /// The returned list will be destroyed when the thread is destroyed.
839 pub fn notmuch_thread_get_messages(thread: *mut notmuch_thread_t) -> *mut notmuch_messages_t;
840
841 /// Get the number of messages in 'thread' that matched the search.
842 ///
843 /// This count includes only the messages in this thread that were
844 /// matched by the search from which the thread was created and were
845 /// not excluded by any exclude tags passed in with the query (see
846 /// `notmuch_query_add_tag_exclude`). Contrast with
847 /// `notmuch_thread_get_total_messages`() .
848 pub fn notmuch_thread_get_matched_messages(thread: *mut notmuch_thread_t) -> c_int;
849
850 /// Get the authors of 'thread' as a UTF-8 string.
851 ///
852 /// The returned string is a comma-separated list of the names of the
853 /// authors of mail messages in the query results that belong to this
854 /// thread.
855 ///
856 /// The string contains authors of messages matching the query first, then
857 /// non-matched authors (with the two groups separated by '|'). Within
858 /// each group, authors are ordered by date.
859 ///
860 /// The returned string belongs to 'thread' and as such, should not be
861 /// modified by the caller and will only be valid for as long as the
862 /// thread is valid, (which is until `notmuch_thread_destroy` or until
863 /// the query from which it derived is destroyed).
864 pub fn notmuch_thread_get_authors(thread: *mut notmuch_thread_t) -> *const c_char;
865
866 /// Get the subject of 'thread' as a UTF-8 string.
867 ///
868 /// The subject is taken from the first message (according to the query
869 /// order---see `notmuch_query_set_sort`) in the query results that
870 /// belongs to this thread.
871 ///
872 /// The returned string belongs to 'thread' and as such, should not be
873 /// modified by the caller and will only be valid for as long as the
874 /// thread is valid, (which is until `notmuch_thread_destroy` or until
875 /// the query from which it derived is destroyed).
876 pub fn notmuch_thread_get_subject(thread: *mut notmuch_thread_t) -> *const c_char;
877
878 /// Get the date of the oldest message in 'thread' as a time_t value.
879 pub fn notmuch_thread_get_oldest_date(thread: *mut notmuch_thread_t) -> time_t;
880
881 /// Get the date of the newest message in 'thread' as a time_t value.
882 pub fn notmuch_thread_get_newest_date(thread: *mut notmuch_thread_t) -> time_t;
883
884 /// Get the tags for 'thread', returning a `notmuch_tags_t` object which
885 /// can be used to iterate over all tags.
886 ///
887 /// Note: In the Notmuch database, tags are stored on individual
888 /// messages, not on threads. So the tags returned here will be all
889 /// tags of the messages which matched the search and which belong to
890 /// this thread.
891 ///
892 /// The tags object is owned by the thread and as such, will only be
893 /// valid for as long as the thread is valid, (for example, until
894 /// `notmuch_thread_destroy` or until the query from which it derived is
895 /// destroyed).
896 ///
897 /// Typical usage might be:
898 ///
899 /// ```norun
900 /// notmuch_thread_t *thread;
901 /// notmuch_tags_t *tags;
902 /// const char *tag;
903 ///
904 /// thread = notmuch_threads_get (threads);
905 ///
906 /// for (tags = notmuch_thread_get_tags (thread);
907 /// notmuch_tags_valid (tags);
908 /// notmuch_tags_move_to_next (tags))
909 /// {
910 /// tag = notmuch_tags_get (tags);
911 /// ....
912 /// }
913 ///
914 /// notmuch_thread_destroy (thread);
915 /// ```
916 ///
917 /// Note that there's no explicit destructor needed for the
918 /// `notmuch_tags_t` object. (For consistency, we do provide a
919 /// `notmuch_tags_destroy` function, but there's no good reason to call
920 /// it if the message is about to be destroyed).
921 pub fn notmuch_thread_get_tags(thread: *mut notmuch_thread_t) -> *mut notmuch_tags_t;
922
923 /// Destroy a `notmuch_thread_t` object.
924 pub fn notmuch_thread_destroy(thread: *mut notmuch_thread_t);
925
926 /// Is the given 'messages' iterator pointing at a valid message.
927 ///
928 /// When this function returns TRUE, `notmuch_messages_get` will return a
929 /// valid object. Whereas when this function returns FALSE,
930 /// `notmuch_messages_get` will return NULL.
931 ///
932 /// See the documentation of `notmuch_query_search_messages` for example
933 /// code showing how to iterate over a `notmuch_messages_t` object.
934 pub fn notmuch_messages_valid(messages: *mut notmuch_messages_t) -> notmuch_bool_t;
935
936 /// Get the current message from 'messages' as a `notmuch_message_t`.
937 ///
938 /// Note: The returned message belongs to 'messages' and has a lifetime
939 /// identical to it (and the query to which it belongs).
940 ///
941 /// See the documentation of `notmuch_query_search_messages` for example
942 /// code showing how to iterate over a `notmuch_messages_t` object.
943 ///
944 /// If an out-of-memory situation occurs, this function will return
945 /// NULL.
946 pub fn notmuch_messages_get(messages: *mut notmuch_messages_t) -> *mut notmuch_message_t;
947
948 /// Move the 'messages' iterator to the next message.
949 ///
950 /// If 'messages' is already pointing at the last message then the
951 /// iterator will be moved to a point just beyond that last message,
952 /// (where `notmuch_messages_valid` will return FALSE and
953 /// `notmuch_messages_get` will return NULL).
954 ///
955 /// See the documentation of `notmuch_query_search_messages` for example
956 /// code showing how to iterate over a `notmuch_messages_t` object.
957 pub fn notmuch_messages_move_to_next(messages: *mut notmuch_messages_t);
958
959 /// Destroy a `notmuch_messages_t` object.
960 ///
961 /// It's not strictly necessary to call this function. All memory from
962 /// the `notmuch_messages_t` object will be reclaimed when the containing
963 /// query object is destroyed.
964 pub fn notmuch_messages_destroy(messages: *mut notmuch_messages_t);
965
966 /// Return a list of tags from all messages.
967 ///
968 /// The resulting list is guaranteed not to contain duplicated tags.
969 ///
970 /// WARNING: You can no longer iterate over messages after calling this
971 /// function, because the iterator will point at the end of the list.
972 /// We do not have a function to reset the iterator yet and the only
973 /// way how you can iterate over the list again is to recreate the
974 /// message list.
975 ///
976 /// The function returns NULL on error.
977 pub fn notmuch_messages_collect_tags(messages: *mut notmuch_messages_t) -> *mut notmuch_tags_t;
978
979 /// Get the message ID of 'message'.
980 ///
981 /// The returned string belongs to 'message' and as such, should not be
982 /// modified by the caller and will only be valid for as long as the
983 /// message is valid, (which is until the query from which it derived
984 /// is destroyed).
985 ///
986 /// This function will not return NULL since Notmuch ensures that every
987 /// message has a unique message ID, (Notmuch will generate an ID for a
988 /// message if the original file does not contain one).
989 pub fn notmuch_message_get_message_id(message: *mut notmuch_message_t) -> *const c_char;
990
991 /// Get the thread ID of 'message'.
992 ///
993 /// The returned string belongs to 'message' and as such, should not be
994 /// modified by the caller and will only be valid for as long as the
995 /// message is valid, (for example, until the user calls
996 /// `notmuch_message_destroy` on 'message' or until a query from which it
997 /// derived is destroyed).
998 ///
999 /// This function will not return NULL since Notmuch ensures that every
1000 /// message belongs to a single thread.
1001 pub fn notmuch_message_get_thread_id(message: *mut notmuch_message_t) -> *const c_char;
1002
1003 /// Get a `notmuch_messages_t` iterator for all of the replies to
1004 /// 'message'.
1005 ///
1006 /// Note: This call only makes sense if 'message' was ultimately
1007 /// obtained from a `notmuch_thread_t` object, (such as by coming
1008 /// directly from the result of calling
1009 /// `notmuch_thread_get_toplevel_messages` or by any number of subsequent
1010 /// calls to `notmuch_message_get_replies`).
1011 ///
1012 /// If 'message' was obtained through some non-thread means, (such as
1013 /// by a call to `notmuch_query_search_messages`), then this function
1014 /// will return NULL.
1015 ///
1016 /// If there are no replies to 'message', this function will return
1017 /// NULL. (Note that `notmuch_messages_valid` will accept that NULL
1018 /// value as legitimate, and simply return FALSE for it.)
1019 pub fn notmuch_message_get_replies(message: *mut notmuch_message_t) -> *mut notmuch_messages_t;
1020
1021 /// Get a filename for the email corresponding to 'message'.
1022 ///
1023 /// The returned filename is an absolute filename, (the initial
1024 /// component will match `notmuch_database_get_path`() ).
1025 ///
1026 /// The returned string belongs to the message so should not be
1027 /// modified or freed by the caller (nor should it be referenced after
1028 /// the message is destroyed).
1029 ///
1030 /// Note: If this message corresponds to multiple files in the mail
1031 /// store, (that is, multiple files contain identical message IDs),
1032 /// this function will arbitrarily return a single one of those
1033 /// filenames. See `notmuch_message_get_filenames` for returning the
1034 /// complete list of filenames.
1035 pub fn notmuch_message_get_filename(message: *mut notmuch_message_t) -> *const c_char;
1036
1037 /// Get all filenames for the email corresponding to 'message'.
1038 ///
1039 /// Returns a `notmuch_filenames_t` iterator listing all the filenames
1040 /// associated with 'message'. These files may not have identical
1041 /// content, but each will have the identical Message-ID.
1042 ///
1043 /// Each filename in the iterator is an absolute filename, (the initial
1044 /// component will match `notmuch_database_get_path`() ).
1045 pub fn notmuch_message_get_filenames(message: *mut notmuch_message_t) -> *mut notmuch_filenames_t;
1046
1047 /// Get a value of a flag for the email corresponding to 'message'.
1048 pub fn notmuch_message_get_flag(message: *mut notmuch_message_t,
1049 flag: notmuch_message_flag_t)
1050 -> notmuch_bool_t;
1051
1052 /// Set a value of a flag for the email corresponding to 'message'.
1053 pub fn notmuch_message_set_flag(message: *mut notmuch_message_t,
1054 flag: notmuch_message_flag_t,
1055 value: notmuch_bool_t);
1056
1057 /// Get the date of 'message' as a time_t value.
1058 ///
1059 /// For the original textual representation of the Date header from the
1060 /// message call `notmuch_message_get_header`() with a header value of
1061 /// "date".
1062 pub fn notmuch_message_get_date(message: *mut notmuch_message_t) -> time_t;
1063
1064 /// Get the value of the specified header from 'message' as a UTF-8 string.
1065 ///
1066 /// Common headers are stored in the database when the message is
1067 /// indexed and will be returned from the database. Other headers will
1068 /// be read from the actual message file.
1069 ///
1070 /// The header name is case insensitive.
1071 ///
1072 /// The returned string belongs to the message so should not be
1073 /// modified or freed by the caller (nor should it be referenced after
1074 /// the message is destroyed).
1075 ///
1076 /// Returns an empty string ("") if the message does not contain a
1077 /// header line matching 'header'. Returns NULL if any error occurs.
1078 pub fn notmuch_message_get_header(message: *mut notmuch_message_t,
1079 header: *const c_char)
1080 -> *const c_char;
1081
1082 /// Get the tags for 'message', returning a `notmuch_tags_t` object which
1083 /// can be used to iterate over all tags.
1084 ///
1085 /// The tags object is owned by the message and as such, will only be
1086 /// valid for as long as the message is valid, (which is until the
1087 /// query from which it derived is destroyed).
1088 ///
1089 /// Typical usage might be:
1090 ///
1091 /// ```norun
1092 /// notmuch_message_t *message;
1093 /// notmuch_tags_t *tags;
1094 /// const char *tag;
1095 ///
1096 /// message = notmuch_database_find_message (database, message_id);
1097 ///
1098 /// for (tags = `notmuch_message_get_tags` (message);
1099 /// notmuch_tags_valid (tags);
1100 /// notmuch_tags_move_to_next (tags))
1101 /// {
1102 /// tag = notmuch_tags_get (tags);
1103 /// ....
1104 /// }
1105 ///
1106 /// notmuch_message_destroy (message);
1107 /// ```
1108 ///
1109 /// Note that there's no explicit destructor needed for the
1110 /// `notmuch_tags_t` object. (For consistency, we do provide a
1111 /// `notmuch_tags_destroy` function, but there's no good reason to call
1112 /// it if the message is about to be destroyed).
1113 pub fn notmuch_message_get_tags(message: *mut notmuch_message_t) -> *mut notmuch_tags_t;
1114
1115 /// Add a tag to the given message.
1116 ///
1117 /// Return value:
1118 ///
1119 /// * `notmuch_status_t::SUCCESS`: Tag successfully added to message
1120 ///
1121 /// * `notmuch_status_t::NULL_POINTER`: The 'tag' argument is NULL
1122 ///
1123 /// * `notmuch_status_t::TAG_TOO_LONG`: The length of 'tag' is too long
1124 /// (exceeds TAG_MAX)
1125 ///
1126 /// * `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only
1127 /// mode so message cannot be modified.
1128 pub fn notmuch_message_add_tag(message: *mut notmuch_message_t,
1129 tag: *const c_char)
1130 -> notmuch_status_t;
1131
1132 /// Remove a tag from the given message.
1133 ///
1134 /// Return value:
1135 ///
1136 /// * `notmuch_status_t::SUCCESS`: Tag successfully removed from message
1137 /// * `notmuch_status_t::NULL_POINTER`: The 'tag' argument is NULL
1138 /// * `notmuch_status_t::TAG_TOO_LONG`: The length of 'tag' is too long (exceeds `TAG_MAX`)
1139 /// * `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only mode so message
1140 /// cannot be modified.
1141 pub fn notmuch_message_remove_tag(message: *mut notmuch_message_t,
1142 tag: *const c_char)
1143 -> notmuch_status_t;
1144
1145 /// Remove all tags from the given message.
1146 ///
1147 /// See `notmuch_message_freeze` for an example showing how to safely
1148 /// replace tag values.
1149 ///
1150 /// `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only
1151 /// mode so message cannot be modified.
1152 pub fn notmuch_message_remove_all_tags(message: *mut notmuch_message_t) -> notmuch_status_t;
1153
1154 /// Add/remove tags according to maildir flags in the message filename(s).
1155 ///
1156 /// This function examines the filenames of 'message' for maildir flags, and adds or removes
1157 /// tags on 'message' as follows when these flags are present:
1158 ///
1159 /// ```norun
1160 /// Flag Action if present
1161 /// ---- -----------------
1162 /// 'D' Adds the "draft" tag to the message
1163 /// 'F' Adds the "flagged" tag to the message
1164 /// 'P' Adds the "passed" tag to the message
1165 /// 'R' Adds the "replied" tag to the message
1166 /// 'S' Removes the "unread" tag from the message
1167 /// ```
1168 ///
1169 /// For each flag that is not present, the opposite action (add/remove)
1170 /// is performed for the corresponding tags.
1171 ///
1172 /// Flags are identified as trailing components of the filename after a
1173 /// sequence of ":2,".
1174 ///
1175 /// If there are multiple filenames associated with this message, the
1176 /// flag is considered present if it appears in one or more
1177 /// filenames. (That is, the flags from the multiple filenames are
1178 /// combined with the logical OR operator.)
1179 ///
1180 /// A client can ensure that notmuch database tags remain synchronized
1181 /// with maildir flags by calling this function after each call to
1182 /// `notmuch_database_add_message`. See also
1183 /// `notmuch_message_tags_to_maildir_flags` for synchronizing tag changes
1184 /// back to maildir flags.
1185 pub fn notmuch_message_maildir_flags_to_tags(message: *mut notmuch_message_t) -> notmuch_status_t;
1186
1187 /// Rename message filename(s) to encode tags as maildir flags.
1188 ///
1189 /// Specifically, for each filename corresponding to this message:
1190 ///
1191 /// If the filename is not in a maildir directory, do nothing. (A
1192 /// maildir directory is determined as a directory named "new" or
1193 /// "cur".) Similarly, if the filename has invalid maildir info,
1194 /// (repeated or outof-ASCII-order flag characters after ":2,"), then
1195 /// do nothing.
1196 ///
1197 /// If the filename is in a maildir directory, rename the file so that
1198 /// its filename ends with the sequence ":2," followed by zero or more
1199 /// of the following single-character flags (in ASCII order):
1200 ///
1201 /// 'D' iff the message has the "draft" tag
1202 /// 'F' iff the message has the "flagged" tag
1203 /// 'P' iff the message has the "passed" tag
1204 /// 'R' iff the message has the "replied" tag
1205 /// 'S' iff the message does not have the "unread" tag
1206 ///
1207 /// Any existing flags unmentioned in the list above will be preserved
1208 /// in the renaming.
1209 ///
1210 /// Also, if this filename is in a directory named "new", rename it to
1211 /// be within the neighboring directory named "cur".
1212 ///
1213 /// A client can ensure that maildir filename flags remain synchronized
1214 /// with notmuch database tags by calling this function after changing
1215 /// tags, (after calls to `notmuch_message_add_tag`,
1216 /// notmuch_message_remove_tag, or `notmuch_message_freeze`/
1217 /// notmuch_message_thaw). See also `notmuch_message_maildir_flags_to_tags`
1218 /// for synchronizing maildir flag changes back to tags.
1219 pub fn notmuch_message_tags_to_maildir_flags(message: *mut notmuch_message_t) -> notmuch_status_t;
1220
1221 /// Freeze the current state of 'message' within the database.
1222 ///
1223 /// This means that changes to the message state, (via
1224 /// notmuch_message_add_tag, `notmuch_message_remove_tag`, and
1225 /// `notmuch_message_remove_all_tags`), will not be committed to the
1226 /// database until the message is thawed with `notmuch_message_thaw`.
1227 ///
1228 /// Multiple calls to freeze/thaw are valid and these calls will
1229 /// "stack". That is there must be as many calls to thaw as to freeze
1230 /// before a message is actually thawed.
1231 ///
1232 /// The ability to do freeze/thaw allows for safe transactions to
1233 /// change tag values. For example, explicitly setting a message to
1234 /// have a given set of tags might look like this:
1235 ///
1236 /// ```norun
1237 /// notmuch_message_freeze (message);
1238 ///
1239 /// notmuch_message_remove_all_tags (message);
1240 ///
1241 /// for (i = 0; i < NUM_TAGS; i++)
1242 /// notmuch_message_add_tag (message, tags[i]);
1243 ///
1244 /// notmuch_message_thaw (message);
1245 /// ```
1246 ///
1247 /// With freeze/thaw used like this, the message in the database is
1248 /// guaranteed to have either the full set of original tag values, or
1249 /// the full set of new tag values, but nothing in between.
1250 ///
1251 /// Imagine the example above without freeze/thaw and the operation
1252 /// somehow getting interrupted. This could result in the message being
1253 /// left with no tags if the interruption happened after
1254 /// notmuch_message_remove_all_tags but before `notmuch_message_add_tag`.
1255 ///
1256 /// Return value:
1257 ///
1258 /// `notmuch_status_t::SUCCESS`: Message successfully frozen.
1259 ///
1260 /// `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only
1261 /// mode so message cannot be modified.
1262 pub fn notmuch_message_freeze(message: *mut notmuch_message_t) -> notmuch_status_t;
1263
1264 /// Thaw the current 'message', synchronizing any changes that may have
1265 /// occurred while 'message' was frozen into the notmuch database.
1266 ///
1267 /// See `notmuch_message_freeze` for an example of how to use this
1268 /// function to safely provide tag changes.
1269 ///
1270 /// Multiple calls to freeze/thaw are valid and these calls with
1271 /// "stack". That is there must be as many calls to thaw as to freeze
1272 /// before a message is actually thawed.
1273 ///
1274 /// Return value:
1275 ///
1276 /// `notmuch_status_t::SUCCESS`: Message successfully thawed, (or at least
1277 /// its frozen count has successfully been reduced by 1).
1278 ///
1279 /// `notmuch_status_t::UNBALANCED_FREEZE_THAW`: An attempt was made to thaw
1280 /// an unfrozen message. That is, there have been an unbalanced
1281 /// number of calls to `notmuch_message_freeze` and
1282 /// `notmuch_message_thaw`.
1283 pub fn notmuch_message_thaw(message: *mut notmuch_message_t) -> notmuch_status_t;
1284
1285 /// Destroy a `notmuch_message_t` object.
1286 ///
1287 /// It can be useful to call this function in the case of a single
1288 /// query object with many messages in the result, (such as iterating
1289 /// over the entire database). Otherwise, it's fine to never call this
1290 /// function and there will still be no memory leaks. (The memory from
1291 /// the messages get reclaimed when the containing query is destroyed.)
1292 pub fn notmuch_message_destroy(message: *mut notmuch_message_t);
1293
1294 /// Retrieve the value for a single property key
1295 ///
1296 /// *value* is set to a string owned by the message or NULL if there is
1297 /// no such key. In the case of multiple values for the given key, the
1298 /// first one is retrieved.
1299 ///
1300 /// @returns
1301 /// - `notmuch_status_t::NULL_POINTER`: *value* may not be NULL.
1302 /// - `notmuch_status_t::SUCCESS`: No error occured.
1303 /// @since libnotmuch 4.4 (notmuch 0.23)
1304 pub fn notmuch_message_get_property(message: *mut notmuch_message_t,
1305 key: *const c_char,
1306 value: *mut *const c_char)
1307 -> notmuch_status_t;
1308
1309 /// Add a (key,value) pair to a message
1310 ///
1311 /// @returns
1312 /// - `notmuch_status_t::ILLEGAL_ARGUMENT`: *key* may not contain an '=' character.
1313 /// - `notmuch_status_t::NULL_POINTER`: Neither *key* nor *value* may be NULL.
1314 /// - `notmuch_status_t::SUCCESS`: No error occured.
1315 /// @since libnotmuch 4.4 (notmuch 0.23)
1316 pub fn notmuch_message_add_property(message: *mut notmuch_message_t,
1317 key: *const c_char,
1318 value: *const c_char)
1319 -> notmuch_status_t;
1320
1321 ///
1322 /// Remove a `(key,value)` pair from a message.
1323 ///
1324 /// It is not an error to remove a non-existant `(key,value)` pair
1325 ///
1326 /// @returns
1327 /// - `notmuch_status_t::ILLEGAL_ARGUMENT`: `key` may not contain an '=' character.
1328 /// - `notmuch_status_t::NULL_POINTER`: Neither `key` nor *value* may be NULL.
1329 /// - `notmuch_status_t::SUCCESS`: No error occured.
1330 /// @since libnotmuch 4.4 (notmuch 0.23)
1331 pub fn notmuch_message_remove_property(message: *mut notmuch_message_t,
1332 key: *const c_char,
1333 value: *const c_char)
1334 -> notmuch_status_t;
1335
1336 /// Remove all `(key,value)` pairs from the given message.
1337 ///
1338 /// @param[in,out] message message to operate on.
1339 /// @param[in] key key to delete properties for. If NULL, delete
1340 /// properties for all keys
1341 /// @returns
1342 /// - `notmuch_status_::READ_ONLY_DATABASE`: Database was opened in
1343 /// read-only mode so message cannot be modified.
1344 /// - `notmuch_status_t::SUCCESS`: No error occured.
1345 ///
1346 /// @since libnotmuch 4.4 (notmuch 0.23)
1347 pub fn notmuch_message_remove_all_properties(message: *mut notmuch_message_t,
1348 key: *const c_char)
1349 -> notmuch_status_t;
1350
1351 /// Get the properties for *message*, returning a
1352 /// `notmuch_message_properties_t` object which can be used to iterate over
1353 /// all properties.
1354 ///
1355 /// The `notmuch_message_properties_t` object is owned by the message and as
1356 /// such, will only be valid for as long as the message is valid, (which is
1357 /// until the query from which it derived is destroyed).
1358 ///
1359 /// @param[in] message The message to examine
1360 /// @param[in] key key or key prefix
1361 /// @param[in] exact if TRUE, require exact match with key. Otherwise
1362 /// treat as prefix.
1363 ///
1364 /// Typical usage might be:
1365 ///
1366 /// ```norun
1367 /// notmuch_message_properties_t *list;
1368 ///
1369 /// for (list = notmuch_message_get_properties (message, "testkey1", TRUE);
1370 /// notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
1371 /// printf("%s\n", notmuch_message_properties_value(list));
1372 /// }
1373 ///
1374 /// notmuch_message_properties_destroy (list);
1375 /// ```
1376 ///
1377 /// Note that there's no explicit destructor needed for the
1378 /// `notmuch_message_properties_t` object. (For consistency, we do provide a
1379 /// `notmuch_message_properities_destroy` function, but there's no good
1380 /// reason to call it if the message is about to be destroyed).
1381 ///
1382 /// @since libnotmuch 4.4 (notmuch 0.23)
1383 ///
1384 pub fn notmuch_message_get_properties(message: *mut notmuch_message_t,
1385 key: *const c_char,
1386 exact: notmuch_bool_t)
1387 -> *mut notmuch_message_properties_t;
1388
1389 /// Is the given *properties* iterator pointing at a valid `(key,value)` pair.
1390 ///
1391 /// When this function returns TRUE, `notmuch_message_properties_{key,value}`
1392 /// will return a valid string, and `notmuch_message_properties_move_to_next`
1393 /// will do what it says. Whereas when this function returns FALSE, calling any
1394 /// of these functions results in undefined behaviour.
1395 ///
1396 /// See the documentation of `notmuch_message_properties_get` for example code
1397 /// showing how to iterate over a `notmuch_message_properties_t` object.
1398 ///
1399 /// @since libnotmuch 4.4 (notmuch 0.23)
1400 pub fn notmuch_message_properties_valid(properties: *const notmuch_message_properties_t) -> notmuch_bool_t;
1401
1402 /// Move the *properties* iterator to the next `(key,value)` pair
1403 ///
1404 /// If *properties* is already pointing at the last pair then the iterator
1405 /// will be moved to a point just beyond that last pair, (where
1406 /// `notmuch_message_properties_valid` will return FALSE).
1407 ///
1408 /// See the documentation of `notmuch_message_get_properties` for example
1409 /// code showing how to iterate over a `notmuch_message_properties_t` object.
1410 ///
1411 /// @since libnotmuch 4.4 (notmuch 0.23)
1412 pub fn notmuch_message_properties_move_to_next(properties: *mut notmuch_message_properties_t);
1413
1414 /// Return the `key` from the current `(key,value)` pair.
1415 ///
1416 /// this could be useful if iterating for a prefix
1417 ///
1418 /// @since libnotmuch 4.4 (notmuch 0.23)
1419 ///
1420 pub fn notmuch_message_properties_key(properties: *mut notmuch_message_properties_t) -> *const c_char;
1421
1422 /// Return the `value` from the current `(key,value)` pair.
1423 ///
1424 /// This could be useful if iterating for a prefix.
1425 ///
1426 /// @since libnotmuch 4.4 (notmuch 0.23)
1427 pub fn notmuch_message_properties_value(properties: *const notmuch_message_properties_t) -> *const c_char;
1428
1429
1430 /// Destroy a `notmuch_message_properties_t` object.
1431 ///
1432 /// It's not strictly necessary to call this function. All memory from
1433 /// the `notmuch_message_properties_t` object will be reclaimed when the
1434 /// containing message object is destroyed.
1435 ///
1436 /// @since libnotmuch 4.4 (notmuch 0.23)
1437 pub fn notmuch_message_properties_destroy(properties: *mut notmuch_message_properties_t);
1438
1439 /// Is the given 'tags' iterator pointing at a valid tag.
1440 ///
1441 /// When this function returns TRUE, `notmuch_tags_get` will return a
1442 /// valid string. Whereas when this function returns FALSE,
1443 /// `notmuch_tags_get` will return NULL.
1444 ///
1445 /// See the documentation of `notmuch_message_get_tags` for example code
1446 /// showing how to iterate over a `notmuch_tags_t` object.
1447 pub fn notmuch_tags_valid(tags: *mut notmuch_tags_t) -> notmuch_bool_t;
1448
1449 /// Get the current tag from 'tags' as a string.
1450 ///
1451 /// Note: The returned string belongs to 'tags' and has a lifetime
1452 /// identical to it (and the query to which it ultimately belongs).
1453 ///
1454 /// See the documentation of `notmuch_message_get_tags` for example code
1455 /// showing how to iterate over a `notmuch_tags_t` object.
1456 pub fn notmuch_tags_get(tags: *mut notmuch_tags_t) -> *const c_char;
1457
1458 /// Move the 'tags' iterator to the next tag.
1459 ///
1460 /// If 'tags' is already pointing at the last tag then the iterator
1461 /// will be moved to a point just beyond that last tag, (where
1462 /// notmuch_tags_valid will return FALSE and `notmuch_tags_get` will
1463 /// return NULL).
1464 ///
1465 /// See the documentation of `notmuch_message_get_tags` for example code
1466 /// showing how to iterate over a `notmuch_tags_t` object.
1467 pub fn notmuch_tags_move_to_next(tags: *mut notmuch_tags_t);
1468
1469 /// Destroy a `notmuch_tags_t` object.
1470 ///
1471 /// It's not strictly necessary to call this function. All memory from
1472 /// the `notmuch_tags_t` object will be reclaimed when the containing
1473 /// message or query objects are destroyed.
1474 pub fn notmuch_tags_destroy(tags: *mut notmuch_tags_t);
1475
1476 /// Store an mtime within the database for 'directory'.
1477 ///
1478 /// The 'directory' should be an object retrieved from the database
1479 /// with `notmuch_database_get_directory` for a particular path.
1480 ///
1481 /// The intention is for the caller to use the mtime to allow efficient
1482 /// identification of new messages to be added to the database. The
1483 /// recommended usage is as follows:
1484 ///
1485 /// * Read the mtime of a directory from the filesystem
1486 ///
1487 /// * Call add_message for all mail files in the directory
1488 ///
1489 /// * Call `notmuch_directory_set_mtime` with the mtime read from the filesystem.
1490 ///
1491 /// Then, when wanting to check for updates to the directory in the
1492 /// future, the client can call `notmuch_directory_get_mtime` and know
1493 /// that it only needs to add files if the mtime of the directory and
1494 /// files are newer than the stored timestamp.
1495 ///
1496 /// Note: The `notmuch_directory_get_mtime` function does not allow the
1497 /// caller to distinguish a timestamp of 0 from a non-existent
1498 /// timestamp. So don't store a timestamp of 0 unless you are
1499 /// comfortable with that.
1500 ///
1501 /// Return value:
1502 ///
1503 /// * `notmuch_status_t::SUCCESS`: mtime successfully stored in database.
1504 ///
1505 /// * `notmuch_status_t::XAPIAN_EXCEPTION`: A Xapian exception occurred, mtime not stored.
1506 ///
1507 /// * `notmuch_status_t::READ_ONLY_DATABASE`: Database was opened in read-only mode so
1508 /// directory mtime cannot be modified.
1509 pub fn notmuch_directory_set_mtime(directory: *mut notmuch_directory_t,
1510 mtime: time_t)
1511 -> notmuch_status_t;
1512
1513 /// Get the mtime of a directory, (as previously stored with
1514 /// `notmuch_directory_set_mtime`).
1515 ///
1516 /// Returns 0 if no mtime has previously been stored for this
1517 /// directory.
1518 pub fn notmuch_directory_get_mtime(directory: *mut notmuch_directory_t) -> time_t;
1519
1520 /// Get a `notmuch_filenames_t` iterator listing all the filenames of
1521 /// messages in the database within the given directory.
1522 ///
1523 /// The returned filenames will be the basename-entries only (not
1524 /// complete paths).
1525 pub fn notmuch_directory_get_child_files(directory: *mut notmuch_directory_t)
1526 -> *mut notmuch_filenames_t;
1527
1528 /// Get a `notmuch_filenames_t` iterator listing all the filenames of
1529 /// sub-directories in the database within the given directory.
1530 ///
1531 /// The returned filenames will be the basename-entries only (not
1532 /// complete paths).
1533 pub fn notmuch_directory_get_child_directories(directory: *mut notmuch_directory_t)
1534 -> *mut notmuch_filenames_t;
1535
1536 /// Delete directory document from the database, and destroy the
1537 /// `notmuch_directory_t` object. Assumes any child directories and files
1538 /// have been deleted by the caller.
1539 ///
1540 /// @since libnotmuch 4.3 (notmuch 0.21)
1541 pub fn notmuch_directory_delete(directory: *mut notmuch_directory_t) -> notmuch_status_t;
1542
1543 /// Destroy a `notmuch_directory_t` object.
1544 pub fn notmuch_directory_destroy(directory: *mut notmuch_directory_t);
1545
1546 /// Is the given 'filenames' iterator pointing at a valid filename.
1547 ///
1548 /// When this function returns TRUE, `notmuch_filenames_get` will return
1549 /// a valid string. Whereas when this function returns FALSE,
1550 /// `notmuch_filenames_get` will return NULL.
1551 ///
1552 /// It is acceptable to pass NULL for 'filenames', in which case this
1553 /// function will always return FALSE.
1554 pub fn notmuch_filenames_valid(filenames: *mut notmuch_filenames_t) -> notmuch_bool_t;
1555
1556 /// Get the current filename from 'filenames' as a string.
1557 ///
1558 /// Note: The returned string belongs to 'filenames' and has a lifetime
1559 /// identical to it (and the directory to which it ultimately belongs).
1560 ///
1561 /// It is acceptable to pass NULL for 'filenames', in which case this
1562 /// function will always return NULL.
1563 pub fn notmuch_filenames_get(filenames: *mut notmuch_filenames_t) -> *const c_char;
1564
1565 /// Move the 'filenames' iterator to the next filename.
1566 ///
1567 /// If 'filenames' is already pointing at the last filename then the
1568 /// iterator will be moved to a point just beyond that last filename,
1569 /// (where `notmuch_filenames_valid` will return FALSE and
1570 /// `notmuch_filenames_get` will return NULL).
1571 ///
1572 /// It is acceptable to pass NULL for 'filenames', in which case this
1573 /// function will do nothing.
1574 pub fn notmuch_filenames_move_to_next(filenames: *mut notmuch_filenames_t);
1575
1576 /// Destroy a `notmuch_filenames_t` object.
1577 ///
1578 /// It's not strictly necessary to call this function. All memory from
1579 /// the `notmuch_filenames_t` object will be reclaimed when the
1580 /// containing directory object is destroyed.
1581 ///
1582 /// It is acceptable to pass NULL for 'filenames', in which case this
1583 /// function will do nothing.
1584 pub fn notmuch_filenames_destroy(filenames: *mut notmuch_filenames_t);
1585
1586
1587 /// set config 'key' to 'value'
1588 ///
1589 /// @since libnotmuch 4.4 (notmuch 0.23)
1590 pub fn notmuch_database_set_config(db: *mut notmuch_database_t,
1591 key: *const c_char,
1592 value: *const c_char)
1593 -> notmuch_status_t;
1594
1595 /// retrieve config item 'key', assign to 'value'
1596 ///
1597 /// keys which have not been previously set with n_d_set_config will
1598 /// return an empty string.
1599 ///
1600 /// return value is allocated by malloc and should be freed by the
1601 /// caller.
1602 ///
1603 /// @since libnotmuch 4.4 (notmuch 0.23)
1604 pub fn notmuch_database_get_config(db: *mut notmuch_database_t,
1605 key: *const c_char,
1606 value: *mut *mut c_char)
1607 -> notmuch_status_t;
1608
1609 /// Create an iterator for all config items with keys matching a given prefix
1610 ///
1611 /// @since libnotmuch 4.4 (notmuch 0.23)
1612 pub fn notmuch_database_get_config_list(db: *mut notmuch_database_t,
1613 prefix: *const c_char,
1614 out: *mut *mut notmuch_config_list_t)
1615 -> notmuch_status_t;
1616
1617 /// Is 'config_list' iterator valid (i.e. _key, _value, _move_to_next can be called).
1618 ///
1619 /// @since libnotmuch 4.4 (notmuch 0.23)
1620 pub fn notmuch_config_list_valid(config_list: *mut notmuch_config_list_t)
1621 -> notmuch_bool_t;
1622
1623 /// return key for current config pair
1624 ///
1625 /// return value is owned by the iterator, and will be destroyed by the
1626 /// next call to `notmuch_config_list_key` or `notmuch_config_list_destroy`.
1627 ///
1628 /// @since libnotmuch 4.4 (notmuch 0.23)
1629 pub fn notmuch_config_list_key (config_list: *mut notmuch_config_list_t)
1630 -> *const c_char;
1631
1632 /// return 'value' for current config pair
1633 ///
1634 /// return value is owned by the iterator, and will be destroyed by the
1635 /// next call to `notmuch_config_list_value` or notmuch `config_list_destroy`
1636 ///
1637 /// @since libnotmuch 4.4 (notmuch 0.23)
1638 pub fn notmuch_config_list_value(config_list: *mut notmuch_config_list_t) -> *const c_char;
1639
1640 /// move 'config_list' iterator to the next pair
1641 ///
1642 /// @since libnotmuch 4.4 (notmuch 0.23)
1643 pub fn notmuch_config_list_move_to_next(config_list: *mut notmuch_config_list_t);
1644
1645 /// free any resources held by 'config_list'
1646 ///
1647 /// @since libnotmuch 4.4 (notmuch 0.23)
1648 pub fn notmuch_config_list_destroy(config_list: *mut notmuch_config_list_t);
1649
1650 /// interrogate the library for compile time features
1651 ///
1652 /// @since libnotmuch 4.4 (notmuch 0.23)
1653 pub fn notmuch_built_with(name: *const c_char) -> notmuch_bool_t;
1654}