X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=lib%2Fnotmuch.h;h=c66e78b1941226617285537338efe4ef7d90f293;hb=HEAD;hp=3c5ec9883b1f0aa4c088717f070d073b8495d9c9;hpb=f92342cb76fa3e1fa2f1c2e727f8ddf1a5c21b7d;p=notmuch diff --git a/lib/notmuch.h b/lib/notmuch.h index 3c5ec988..4e2b0fa4 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/ . + * along with this program. If not, see https://www.gnu.org/licenses/ . * * Author: Carl Worth */ @@ -43,6 +43,8 @@ NOTMUCH_BEGIN_DECLS #include +#pragma GCC visibility push(default) + #ifndef FALSE #define FALSE 0 #endif @@ -55,9 +57,20 @@ NOTMUCH_BEGIN_DECLS * The library version number. This must agree with the soname * version in Makefile.local. */ -#define LIBNOTMUCH_MAJOR_VERSION 3 -#define LIBNOTMUCH_MINOR_VERSION 1 -#define LIBNOTMUCH_MICRO_VERSION 0 +#define LIBNOTMUCH_MAJOR_VERSION 5 +#define LIBNOTMUCH_MINOR_VERSION 6 +#define LIBNOTMUCH_MICRO_VERSION 0 + + +#if defined (__clang_major__) && __clang_major__ >= 3 \ + || defined (__GNUC__) && __GNUC__ >= 5 \ + || defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5 +#define NOTMUCH_DEPRECATED(major, minor) \ + __attribute__ ((deprecated ("function deprecated as of libnotmuch " #major "." #minor))) +#else +#define NOTMUCH_DEPRECATED(major, minor) __attribute__ ((deprecated)) +#endif + #endif /* __DOXYGEN__ */ @@ -82,8 +95,8 @@ NOTMUCH_BEGIN_DECLS * #endif * @endcode */ -#define LIBNOTMUCH_CHECK_VERSION (major, minor, micro) \ - (LIBNOTMUCH_MAJOR_VERSION > (major) || \ +#define LIBNOTMUCH_CHECK_VERSION(major, minor, micro) \ + (LIBNOTMUCH_MAJOR_VERSION > (major) || \ (LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION > (minor)) || \ (LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \ LIBNOTMUCH_MICRO_VERSION >= (micro))) @@ -99,7 +112,7 @@ typedef int notmuch_bool_t; * A zero value (NOTMUCH_STATUS_SUCCESS) indicates that the function * completed without error. Any other value indicates an error. */ -typedef enum _notmuch_status { +typedef enum { /** * No error occurred. */ @@ -115,15 +128,15 @@ typedef enum _notmuch_status { NOTMUCH_STATUS_READ_ONLY_DATABASE, /** * A Xapian exception occurred. + * + * @todo We don't really want to expose this lame XAPIAN_EXCEPTION + * value. Instead we should map to things like DATABASE_LOCKED or + * whatever. */ NOTMUCH_STATUS_XAPIAN_EXCEPTION, /** * An error occurred trying to read or write to a file (this could * be file not found, permission denied, etc.) - * - * @todo We don't really want to expose this lame XAPIAN_EXCEPTION - * value. Instead we should map to things like DATABASE_LOCKED or - * whatever. */ NOTMUCH_STATUS_FILE_ERROR, /** @@ -159,6 +172,66 @@ typedef enum _notmuch_status { * The operation is not supported. */ NOTMUCH_STATUS_UNSUPPORTED_OPERATION, + /** + * The operation requires a database upgrade. + */ + NOTMUCH_STATUS_UPGRADE_REQUIRED, + /** + * There is a problem with the proposed path, e.g. a relative path + * passed to a function expecting an absolute path. + */ + NOTMUCH_STATUS_PATH_ERROR, + /** + * The requested operation was ignored. Depending on the function, + * this may not be an actual error. + */ + NOTMUCH_STATUS_IGNORED, + /** + * One of the arguments violates the preconditions for the + * function, in a way not covered by a more specific argument. + */ + NOTMUCH_STATUS_ILLEGAL_ARGUMENT, + /** + * A MIME object claimed to have cryptographic protection which + * notmuch tried to handle, but the protocol was not specified in + * an intelligible way. + */ + NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL, + /** + * Notmuch attempted to do crypto processing, but could not + * initialize the engine needed to do so. + */ + NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION, + /** + * A MIME object claimed to have cryptographic protection, and + * notmuch attempted to process it, but the specific protocol was + * something that notmuch doesn't know how to handle. + */ + NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL, + /** + * Unable to load a config file + */ + NOTMUCH_STATUS_NO_CONFIG, + /** + * Unable to load a database + */ + NOTMUCH_STATUS_NO_DATABASE, + /** + * Database exists, so not (re)-created + */ + NOTMUCH_STATUS_DATABASE_EXISTS, + /** + * Syntax error in query + */ + NOTMUCH_STATUS_BAD_QUERY_SYNTAX, + /** + * No mail root could be deduced from parameters and environment + */ + NOTMUCH_STATUS_NO_MAIL_ROOT, + /** + * Database is not fully opened, or has been closed + */ + NOTMUCH_STATUS_CLOSED_DATABASE, /** * Not an actual status value. Just a way to find out how many * valid status values there are. @@ -186,6 +259,10 @@ typedef struct _notmuch_message notmuch_message_t; typedef struct _notmuch_tags notmuch_tags_t; typedef struct _notmuch_directory notmuch_directory_t; typedef struct _notmuch_filenames notmuch_filenames_t; +typedef struct _notmuch_config_list notmuch_config_list_t; +typedef struct _notmuch_config_values notmuch_config_values_t; +typedef struct _notmuch_config_pairs notmuch_config_pairs_t; +typedef struct _notmuch_indexopts notmuch_indexopts_t; #endif /* __DOXYGEN__ */ /** @@ -203,7 +280,7 @@ typedef struct _notmuch_filenames notmuch_filenames_t; * The database will not yet have any data in it * (notmuch_database_create itself is a very cheap function). Messages * contained within 'path' can be added to the database by calling - * notmuch_database_add_message. + * notmuch_database_index_file. * * In case of any failure, this function returns an error status and * sets *database to NULL (after printing an error message on stderr). @@ -216,6 +293,8 @@ typedef struct _notmuch_filenames notmuch_filenames_t; * * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory. * + * NOTMUCH_STATUS_PATH_ERROR: filename is too long + * * NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to create the * database file (such as permission denied, or file not found, * etc.), or the database already exists. @@ -225,6 +304,16 @@ typedef struct _notmuch_filenames notmuch_filenames_t; notmuch_status_t notmuch_database_create (const char *path, notmuch_database_t **database); +/** + * Like notmuch_database_create, except optionally return an error + * message. This message is allocated by malloc and should be freed by + * the caller. + */ +notmuch_status_t +notmuch_database_create_verbose (const char *path, + notmuch_database_t **database, + char **error_message); + /** * Database open mode for notmuch_database_open. */ @@ -240,54 +329,234 @@ typedef enum { } notmuch_database_mode_t; /** - * Open an existing notmuch database located at 'path'. + * Deprecated alias for notmuch_database_open_with_config with + * config_path="" and error_message=NULL + * @deprecated Deprecated as of libnotmuch 5.4 (notmuch 0.32) + */ +NOTMUCH_DEPRECATED(5, 4) +notmuch_status_t +notmuch_database_open (const char *path, + notmuch_database_mode_t mode, + notmuch_database_t **database); +/** + * Deprecated alias for notmuch_database_open_with_config with + * config_path="" + * + * @deprecated Deprecated as of libnotmuch 5.4 (notmuch 0.32) + * + */ +NOTMUCH_DEPRECATED(5, 4) +notmuch_status_t +notmuch_database_open_verbose (const char *path, + notmuch_database_mode_t mode, + notmuch_database_t **database, + char **error_message); + +/** + * Open an existing notmuch database located at 'database_path', using + * configuration in 'config_path'. + * + * @param[in] database_path + * @parblock + * Path to existing database. + * + * A notmuch database is a Xapian database containing appropriate + * metadata. * * The database should have been created at some time in the past, * (not necessarily by this process), by calling - * notmuch_database_create with 'path'. By default the database should be - * opened for reading only. In order to write to the database you need to - * pass the NOTMUCH_DATABASE_MODE_READ_WRITE mode. + * notmuch_database_create. + * + * If 'database_path' is NULL, use the location specified + * + * - in the environment variable NOTMUCH_DATABASE, if non-empty + * + * - in a configuration file, located as described under 'config_path' + * + * - by $XDG_DATA_HOME/notmuch/$PROFILE where XDG_DATA_HOME defaults + * to "$HOME/.local/share" and PROFILE as as discussed in + * 'profile' * - * An existing notmuch database can be identified by the presence of a - * directory named ".notmuch" below 'path'. + * If 'database_path' is non-NULL, but does not appear to be a Xapian + * database, check for a directory '.notmuch/xapian' below + * 'database_path' (this is the behavior of + * notmuch_database_open_verbose pre-0.32). + * + * @endparblock + * @param[in] mode + * @parblock + * Mode to open database. Use one of #NOTMUCH_DATABASE_MODE_READ_WRITE + * or #NOTMUCH_DATABASE_MODE_READ_ONLY + * + * @endparblock + * @param[in] config_path + * @parblock + * Path to config file. + * + * Config file is key-value, with mandatory sections. See + * notmuch-config(5) for more information. The key-value pair + * overrides the corresponding configuration data stored in the + * database (see notmuch_database_get_config) + * + * If config_path is NULL use the path specified + * + * - in environment variable NOTMUCH_CONFIG, if non-empty + * + * - by XDG_CONFIG_HOME/notmuch/ where + * XDG_CONFIG_HOME defaults to "$HOME/.config". + * + * - by $HOME/.notmuch-config + * + * If config_path is "" (empty string) then do not + * open any configuration file. + * @endparblock + * @param[in] profile: + * @parblock + * Name of profile (configuration/database variant). + * + * If non-NULL, append to the directory / file path determined for + * config_path and database_path. + * + * If NULL then use + * - environment variable NOTMUCH_PROFILE if defined, + * - otherwise "default" for directories and "" (empty string) for paths. + * + * @endparblock + * @param[out] database + * @parblock + * Pointer to database object. May not be NULL. * * The caller should call notmuch_database_destroy when finished with * this database. * * In case of any failure, this function returns an error status and - * sets *database to NULL (after printing an error message on stderr). + * sets *database to NULL. * - * Return value: + * @endparblock + * @param[out] error_message + * If non-NULL, store error message from opening the database. + * Any such message is allocated by \a malloc(3) and should be freed + * by the caller. * - * NOTMUCH_STATUS_SUCCESS: Successfully opened the database. + * @retval NOTMUCH_STATUS_SUCCESS: Successfully opened the database. * - * NOTMUCH_STATUS_NULL_POINTER: The given 'path' argument is NULL. + * @retval NOTMUCH_STATUS_NULL_POINTER: The given \a database + * argument is NULL. * - * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory. + * @retval NOTMUCH_STATUS_NO_CONFIG: No config file was found. Fatal. * - * NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to open the - * database file (such as permission denied, or file not found, + * @retval NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory. + * + * @retval NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to open the + * database or config file (such as permission denied, or file not found, * etc.), or the database version is unknown. * - * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred. + * @retval NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred. + * + * @since libnotmuch 5.4 (notmuch 0.32) */ + notmuch_status_t -notmuch_database_open (const char *path, - notmuch_database_mode_t mode, - notmuch_database_t **database); +notmuch_database_open_with_config (const char *database_path, + notmuch_database_mode_t mode, + const char *config_path, + const char *profile, + notmuch_database_t **database, + char **error_message); + + +/** + * Loads configuration from config file, database, and/or defaults + * + * For description of arguments, @see notmuch_database_open_with_config + * + * For errors other then NO_DATABASE and NO_CONFIG, *database is set to + * NULL. + * + * @retval NOTMUCH_STATUS_SUCCESS: Successfully loaded configuration. + * + * @retval NOTMUCH_STATUS_NO_CONFIG: No config file was loaded. Not fatal. + * + * @retval NOTMUCH_STATUS_NO_DATABASE: No config information was + * loaded from a database. Not fatal. + * + * @retval NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory. + * + * @retval NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to open the + * database or config file (such as permission denied, or file not found, + * etc.) + * + * @retval NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred. + * + * @since libnotmuch 5.4 (notmuch 0.32) + */ + +notmuch_status_t +notmuch_database_load_config (const char *database_path, + const char *config_path, + const char *profile, + notmuch_database_t **database, + char **error_message); + +/** + * Create a new notmuch database located at 'database_path', using + * configuration in 'config_path'. + * + * For description of arguments, @see notmuch_database_open_with_config + * + * In case of any failure, this function returns an error status and + * sets *database to NULL. + * + * @retval NOTMUCH_STATUS_SUCCESS: Successfully created the database. + * + * @retval NOTMUCH_STATUS_DATABASE_EXISTS: Database already exists, not created + * + * @retval NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory. + * + * @retval NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to open the + * database or config file (such as permission denied, or file not found, + * etc.) + * + * @retval NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred. + * + * @since libnotmuch 5.4 (notmuch 0.32) + */ + +notmuch_status_t +notmuch_database_create_with_config (const char *database_path, + const char *config_path, + const char *profile, + notmuch_database_t **database, + char **error_message); + +/** + * Retrieve last status string for given database. + * + */ +const char * +notmuch_database_status_string (const notmuch_database_t *notmuch); /** - * Close the given notmuch database. + * Commit changes and close the given notmuch database. * * After notmuch_database_close has been called, calls to other * functions on objects derived from this database may either behave * as if the database had not been closed (e.g., if the required data * has been cached) or may fail with a - * NOTMUCH_STATUS_XAPIAN_EXCEPTION. + * NOTMUCH_STATUS_XAPIAN_EXCEPTION. The only further operation + * permitted on the database itself is to call + * notmuch_database_destroy. * * notmuch_database_close can be called multiple times. Later calls * have no effect. * + * For writable databases, notmuch_database_close commits all changes + * to disk before closing the database, unless the caller is currently + * in an atomic section (there was a notmuch_database_begin_atomic + * without a matching notmuch_database_end_atomic). In this case + * changes since the last commit are discarded. @see + * notmuch_database_end_atomic for more information. + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Successfully closed the database. @@ -317,11 +586,23 @@ typedef void (*notmuch_compact_status_cb_t)(const char *message, void *closure); * 'closure' is passed verbatim to any callback invoked. */ notmuch_status_t -notmuch_database_compact (const char* path, - const char* backup_path, +notmuch_database_compact (const char *path, + const char *backup_path, notmuch_compact_status_cb_t status_cb, void *closure); +/** + * Like notmuch_database_compact, but take an open database as a + * parameter. + * + * @since libnnotmuch 5.4 (notmuch 0.32) + */ +notmuch_status_t +notmuch_database_compact_db (notmuch_database_t *database, + const char *backup_path, + notmuch_compact_status_cb_t status_cb, + void *closure); + /** * Destroy the notmuch database, closing it if necessary and freeing * all associated resources. @@ -343,27 +624,37 @@ notmuch_database_get_path (notmuch_database_t *database); /** * Return the database format version of the given database. + * + * @retval 0 on error */ unsigned int notmuch_database_get_version (notmuch_database_t *database); /** - * Does this database need to be upgraded before writing to it? + * Can the database be upgraded to a newer database version? + * + * If this function returns TRUE, then the caller may call + * notmuch_database_upgrade to upgrade the database. If the caller + * does not upgrade an out-of-date database, then some functions may + * fail with NOTMUCH_STATUS_UPGRADE_REQUIRED. This always returns + * FALSE for a read-only database because there's no way to upgrade a + * read-only database. + * + * Also returns FALSE if an error occurs accessing the database. * - * If this function returns TRUE then no functions that modify the - * database (notmuch_database_add_message, notmuch_message_add_tag, - * notmuch_directory_set_mtime, etc.) will work unless the function - * notmuch_database_upgrade is called successfully first. */ notmuch_bool_t notmuch_database_needs_upgrade (notmuch_database_t *database); /** - * Upgrade the current database. + * Upgrade the current database to the latest supported version. * - * After opening a database in read-write mode, the client should - * check if an upgrade is needed (notmuch_database_needs_upgrade) and - * if so, upgrade with this function before making any modifications. + * This ensures that all current notmuch functionality will be + * available on the database. After opening a database in read-write + * mode, it is recommended that clients check if an upgrade is needed + * (notmuch_database_needs_upgrade) and if so, upgrade with this + * function before making any modifications. If + * notmuch_database_needs_upgrade returns FALSE, this will be a no-op. * * The optional progress_notify callback can be used by the caller to * provide progress indication to the user. If non-NULL it will be @@ -374,8 +665,8 @@ notmuch_database_needs_upgrade (notmuch_database_t *database); */ notmuch_status_t notmuch_database_upgrade (notmuch_database_t *database, - void (*progress_notify) (void *closure, - double progress), + void (*progress_notify)(void *closure, + double progress), void *closure); /** @@ -401,7 +692,10 @@ notmuch_status_t notmuch_database_begin_atomic (notmuch_database_t *notmuch); /** - * Indicate the end of an atomic database operation. + * Indicate the end of an atomic database operation. If repeated + * (with matching notmuch_database_begin_atomic) "database.autocommit" + * times, commit the the transaction and all previous (non-cancelled) + * transactions to the database. * * Return value: * @@ -416,6 +710,25 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch); notmuch_status_t notmuch_database_end_atomic (notmuch_database_t *notmuch); +/** + * Return the committed database revision and UUID. + * + * The database revision number increases monotonically with each + * commit to the database. Hence, all messages and message changes + * committed to the database (that is, visible to readers) have a last + * modification revision <= the committed database revision. Any + * messages committed in the future will be assigned a modification + * revision > the committed database revision. + * + * The UUID is a NUL-terminated opaque string that uniquely identifies + * this database. Two revision numbers are only comparable if they + * have the same database UUID. The string 'uuid' is owned by notmuch + * and should not be freed or modified by the user. + */ +unsigned long +notmuch_database_get_revision (notmuch_database_t *notmuch, + const char **uuid); + /** * Retrieve a directory object from the database for 'path'. * @@ -438,6 +751,9 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); * * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred; * directory not retrieved. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_get_directory (notmuch_database_t *database, @@ -445,8 +761,10 @@ notmuch_database_get_directory (notmuch_database_t *database, notmuch_directory_t **directory); /** - * Add a new message to the given notmuch database or associate an - * additional filename with an existing message. + * Add a message file to a database, indexing it for retrieval by + * future searches. If a message already exists with the same message + * ID as the specified file, their indexes will be merged, and this + * new filename will also be associated with the existing message. * * Here, 'filename' should be a path relative to the path of * 'database' (see notmuch_database_get_path), or else should be an @@ -459,8 +777,14 @@ notmuch_database_get_directory (notmuch_database_t *database, * entire contents of the file. * * If another message with the same message ID already exists in the - * database, rather than creating a new message, this adds 'filename' - * to the list of the filenames for the existing message. + * database, rather than creating a new message, this adds the search + * terms from the identified file to the existing message's index, and + * adds 'filename' to the list of filenames known for the message. + * + * The 'indexopts' parameter can be NULL (meaning, use the indexing + * defaults from the database), or can be an explicit choice of + * indexing options that should govern the indexing of this specific + * 'filename'. * * If 'message' is not NULL, then, on successful return * (NOTMUCH_STATUS_SUCCESS or NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) '*message' @@ -490,7 +814,27 @@ notmuch_database_get_directory (notmuch_database_t *database, * * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only * mode so no message can be added. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. + * + * @since libnotmuch 5.1 (notmuch 0.26) + */ +notmuch_status_t +notmuch_database_index_file (notmuch_database_t *database, + const char *filename, + notmuch_indexopts_t *indexopts, + notmuch_message_t **message); + +/** + * Deprecated alias for notmuch_database_index_file called with + * NULL indexopts. + * + * @deprecated Deprecated as of libnotmuch 5.1 (notmuch 0.26). Please + * use notmuch_database_index_file instead. + * */ +NOTMUCH_DEPRECATED (5, 1) notmuch_status_t notmuch_database_add_message (notmuch_database_t *database, const char *filename, @@ -520,6 +864,9 @@ notmuch_database_add_message (notmuch_database_t *database, * * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only * mode so no message can be removed. + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_remove_message (notmuch_database_t *database, @@ -575,6 +922,9 @@ notmuch_database_find_message (notmuch_database_t *database, * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object * * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred + * + * NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the + * database to use this function. */ notmuch_status_t notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, @@ -592,6 +942,19 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, notmuch_tags_t * notmuch_database_get_all_tags (notmuch_database_t *db); +/** + * Reopen an open notmuch database. + * + * @param [in] db open notmuch database + * @param [in] mode mode (read only or read-write) for reopened database. + * + * @retval #NOTMUCH_STATUS_SUCCESS + * @retval #NOTMUCH_STATUS_ILLEGAL_ARGUMENT The passed database was not open. + * @retval #NOTMUCH_STATUS_XAPIAN_EXCEPTION A Xapian exception occured + */ +notmuch_status_t +notmuch_database_reopen (notmuch_database_t *db, notmuch_database_mode_t mode); + /** * Create a new query for 'database'. * @@ -602,7 +965,7 @@ notmuch_database_get_all_tags (notmuch_database_t *db); * completely in the future, but it's likely to be a specialized * version of the general Xapian query syntax: * - * http://xapian.org/docs/queryparser.html + * https://xapian.org/docs/queryparser.html * * As a special case, passing either a length-zero string, (that is ""), * or a string consisting of a single asterisk (that is "*"), will @@ -621,6 +984,16 @@ notmuch_query_t * notmuch_query_create (notmuch_database_t *database, const char *query_string); +typedef enum { + NOTMUCH_QUERY_SYNTAX_XAPIAN, + NOTMUCH_QUERY_SYNTAX_SEXP +} notmuch_query_syntax_t; + +notmuch_status_t +notmuch_query_create_with_syntax (notmuch_database_t *database, + const char *query_string, + notmuch_query_syntax_t syntax, + notmuch_query_t **output); /** * Sort values for notmuch_query_set_sort. */ @@ -647,7 +1020,13 @@ typedef enum { * Return the query_string of this query. See notmuch_query_create. */ const char * -notmuch_query_get_query_string (notmuch_query_t *query); +notmuch_query_get_query_string (const notmuch_query_t *query); + +/** + * Return the notmuch database of this query. See notmuch_query_create. + */ +notmuch_database_t * +notmuch_query_get_database (const notmuch_query_t *query); /** * Exclude values for notmuch_query_set_omit_excluded. The strange @@ -704,14 +1083,24 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); * notmuch_query_set_sort. */ notmuch_sort_t -notmuch_query_get_sort (notmuch_query_t *query); +notmuch_query_get_sort (const notmuch_query_t *query); /** * Add a tag that will be excluded from the query results by default. - * This exclusion will be overridden if this tag appears explicitly in + * This exclusion will be ignored if this tag appears explicitly in * the query. + * + * @returns + * + * NOTMUCH_STATUS_SUCCESS: excluded was added successfully. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. + * Most likely a problem lazily parsing the query string. + * + * NOTMUCH_STATUS_IGNORED: tag is explicitly present in the query, so + * not excluded. */ -void +notmuch_status_t notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); /** @@ -725,10 +1114,12 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); * notmuch_query_t *query; * notmuch_threads_t *threads; * notmuch_thread_t *thread; + * notmuch_status_t stat; * * query = notmuch_query_create (database, query_string); * - * for (threads = notmuch_query_search_threads (query); + * for (stat = notmuch_query_search_threads (query, &threads); + * stat == NOTMUCH_STATUS_SUCCESS && * notmuch_threads_valid (threads); * notmuch_threads_move_to_next (threads)) * { @@ -751,10 +1142,22 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); * notmuch_threads_destroy function, but there's no good reason * to call it if the query is about to be destroyed). * - * If a Xapian exception occurs this function will return NULL. + * @since libnotmuch 5.0 (notmuch 0.25) + */ +notmuch_status_t +notmuch_query_search_threads (notmuch_query_t *query, + notmuch_threads_t **out); + +/** + * Deprecated alias for notmuch_query_search_threads. + * + * @deprecated Deprecated as of libnotmuch 5 (notmuch 0.25). Please + * use notmuch_query_search_threads instead. + * */ -notmuch_threads_t * -notmuch_query_search_threads (notmuch_query_t *query); +NOTMUCH_DEPRECATED (5, 0) +notmuch_status_t +notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out); /** * Execute a query for messages, returning a notmuch_messages_t object @@ -770,7 +1173,10 @@ notmuch_query_search_threads (notmuch_query_t *query); * * query = notmuch_query_create (database, query_string); * - * for (messages = notmuch_query_search_messages (query); + * if (notmuch_query_search_messages (query, &messages) != NOTMUCH_STATUS_SUCCESS) + * return EXIT_FAILURE; + * + * for (; * notmuch_messages_valid (messages); * notmuch_messages_move_to_next (messages)) * { @@ -794,9 +1200,24 @@ notmuch_query_search_threads (notmuch_query_t *query); * reason to call it if the query is about to be destroyed). * * If a Xapian exception occurs this function will return NULL. + * + * @since libnotmuch 5 (notmuch 0.25) */ -notmuch_messages_t * -notmuch_query_search_messages (notmuch_query_t *query); +notmuch_status_t +notmuch_query_search_messages (notmuch_query_t *query, + notmuch_messages_t **out); +/** + * Deprecated alias for notmuch_query_search_messages + * + * @deprecated Deprecated as of libnotmuch 5 (notmuch 0.25). Please use + * notmuch_query_search_messages instead. + * + */ + +NOTMUCH_DEPRECATED (5, 0) +notmuch_status_t +notmuch_query_search_messages_st (notmuch_query_t *query, + notmuch_messages_t **out); /** * Destroy a notmuch_query_t along with any associated resources. @@ -865,16 +1286,33 @@ void notmuch_threads_destroy (notmuch_threads_t *threads); /** - * Return an estimate of the number of messages matching a search. + * Return the number of messages matching a search. + * + * This function performs a search and returns the number of matching + * messages. + * + * @returns + * + * NOTMUCH_STATUS_SUCCESS: query completed successfully. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. The + * value of *count is not defined. + * + * @since libnotmuch 5 (notmuch 0.25) + */ +notmuch_status_t +notmuch_query_count_messages (notmuch_query_t *query, unsigned int *count); + +/** + * Deprecated alias for notmuch_query_count_messages * - * This function performs a search and returns Xapian's best - * guess as to number of matching messages. * - * If a Xapian exception occurs, this function may return 0 (after - * printing a message). + * @deprecated Deprecated since libnotmuch 5.0 (notmuch 0.25). Please + * use notmuch_query_count_messages instead. */ -unsigned -notmuch_query_count_messages (notmuch_query_t *query); +NOTMUCH_DEPRECATED (5, 0) +notmuch_status_t +notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count); /** * Return the number of threads matching a search. @@ -884,12 +1322,32 @@ notmuch_query_count_messages (notmuch_query_t *query); * search. * * Note that this is a significantly heavier operation than - * notmuch_query_count_messages(). + * notmuch_query_count_messages{_st}(). + * + * @returns + * + * NOTMUCH_STATUS_OUT_OF_MEMORY: Memory allocation failed. The value + * of *count is not defined + * + * NOTMUCH_STATUS_SUCCESS: query completed successfully. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. The + * value of *count is not defined. + * + * @since libnotmuch 5 (notmuch 0.25) + */ +notmuch_status_t +notmuch_query_count_threads (notmuch_query_t *query, unsigned *count); + +/** + * Deprecated alias for notmuch_query_count_threads * - * If an error occurs, this function may return 0. + * @deprecated Deprecated as of libnotmuch 5.0 (notmuch 0.25). Please + * use notmuch_query_count_threads_st instead. */ -unsigned -notmuch_query_count_threads (notmuch_query_t *query); +NOTMUCH_DEPRECATED (5, 0) +notmuch_status_t +notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count); /** * Get the thread ID of 'thread'. @@ -911,6 +1369,18 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread); int notmuch_thread_get_total_messages (notmuch_thread_t *thread); +/** + * Get the total number of files in 'thread'. + * + * This sums notmuch_message_count_files over all messages in the + * thread + * @returns Non-negative integer + * @since libnotmuch 5.0 (notmuch 0.25) + */ + +int +notmuch_thread_get_total_files (notmuch_thread_t *thread); + /** * Get a notmuch_messages_t iterator for the top-level messages in * 'thread' in oldest-first order. @@ -952,6 +1422,10 @@ notmuch_thread_get_matched_messages (notmuch_thread_t *thread); * authors of mail messages in the query results that belong to this * thread. * + * The string contains authors of messages matching the query first, then + * non-matched authors (with the two groups separated by '|'). Within + * each group, authors are ordered by date. + * * The returned string belongs to 'thread' and as such, should not be * modified by the caller and will only be valid for as long as the * thread is valid, (which is until notmuch_thread_destroy or until @@ -1101,6 +1575,14 @@ notmuch_messages_destroy (notmuch_messages_t *messages); notmuch_tags_t * notmuch_messages_collect_tags (notmuch_messages_t *messages); +/** + * Get the database associated with this message. + * + * @since libnotmuch 5.2 (notmuch 0.27) + */ +notmuch_database_t * +notmuch_message_get_database (const notmuch_message_t *message); + /** * Get the message ID of 'message'. * @@ -1109,9 +1591,8 @@ notmuch_messages_collect_tags (notmuch_messages_t *messages); * message is valid, (which is until the query from which it derived * is destroyed). * - * This function will not return NULL since Notmuch ensures that every - * message has a unique message ID, (Notmuch will generate an ID for a - * message if the original file does not contain one). + * This function will return NULL if triggers an unhandled Xapian + * exception. */ const char * notmuch_message_get_message_id (notmuch_message_t *message); @@ -1125,8 +1606,8 @@ notmuch_message_get_message_id (notmuch_message_t *message); * notmuch_message_destroy on 'message' or until a query from which it * derived is destroyed). * - * This function will not return NULL since Notmuch ensures that every - * message belongs to a single thread. + * This function will return NULL if triggers an unhandled Xapian + * exception. */ const char * notmuch_message_get_thread_id (notmuch_message_t *message); @@ -1148,10 +1629,24 @@ notmuch_message_get_thread_id (notmuch_message_t *message); * If there are no replies to 'message', this function will return * NULL. (Note that notmuch_messages_valid will accept that NULL * value as legitimate, and simply return FALSE for it.) + * + * This function also returns NULL if it triggers a Xapian exception. + * + * The returned list will be destroyed when the thread is + * destroyed. */ notmuch_messages_t * notmuch_message_get_replies (notmuch_message_t *message); +/** + * Get the total number of files associated with a message. + * @returns Non-negative integer for file count. + * @returns Negative integer for error. + * @since libnotmuch 5.0 (notmuch 0.25) + */ +int +notmuch_message_count_files (notmuch_message_t *message); + /** * Get a filename for the email corresponding to 'message'. * @@ -1167,6 +1662,8 @@ notmuch_message_get_replies (notmuch_message_t *message); * this function will arbitrarily return a single one of those * filenames. See notmuch_message_get_filenames for returning the * complete list of filenames. + * + * This function returns NULL if it triggers a Xapian exception. */ const char * notmuch_message_get_filename (notmuch_message_t *message); @@ -1180,25 +1677,73 @@ notmuch_message_get_filename (notmuch_message_t *message); * * Each filename in the iterator is an absolute filename, (the initial * component will match notmuch_database_get_path() ). + * + * This function returns NULL if it triggers a Xapian exception. */ notmuch_filenames_t * notmuch_message_get_filenames (notmuch_message_t *message); +/** + * Re-index the e-mail corresponding to 'message' using the supplied index options + * + * Returns the status of the re-index operation. (see the return + * codes documented in notmuch_database_index_file) + * + * After reindexing, the user should discard the message object passed + * in here by calling notmuch_message_destroy, since it refers to the + * original message, not to the reindexed message. + */ +notmuch_status_t +notmuch_message_reindex (notmuch_message_t *message, + notmuch_indexopts_t *indexopts); + /** * Message flags. */ -typedef enum _notmuch_message_flag { +typedef enum { NOTMUCH_MESSAGE_FLAG_MATCH, - NOTMUCH_MESSAGE_FLAG_EXCLUDED + NOTMUCH_MESSAGE_FLAG_EXCLUDED, + + /* This message is a "ghost message", meaning it has no filenames + * or content, but we know it exists because it was referenced by + * some other message. A ghost message has only a message ID and + * thread ID. + */ + NOTMUCH_MESSAGE_FLAG_GHOST, } notmuch_message_flag_t; /** * Get a value of a flag for the email corresponding to 'message'. + * + * returns FALSE in case of errors. + * + * @deprecated Deprecated as of libnotmuch 5.3 (notmuch 0.31). Please + * use notmuch_message_get_flag_st instead. */ +NOTMUCH_DEPRECATED (5, 3) notmuch_bool_t notmuch_message_get_flag (notmuch_message_t *message, notmuch_message_flag_t flag); +/** + * Get a value of a flag for the email corresponding to 'message'. + * + * @param message a message object + * @param flag flag to check + * @param is_set pointer to boolean to store flag value. + * + * @retval #NOTMUCH_STATUS_SUCCESS + * @retval #NOTMUCH_STATUS_NULL_POINTER is_set is NULL + * @retval #NOTMUCH_STATUS_XAPIAN_EXCEPTION Accessing the database + * triggered an exception. + * + * @since libnotmuch 5.3 (notmuch 0.31) + */ +notmuch_status_t +notmuch_message_get_flag_st (notmuch_message_t *message, + notmuch_message_flag_t flag, + notmuch_bool_t *is_set); + /** * Set a value of a flag for the email corresponding to 'message'. */ @@ -1212,9 +1757,11 @@ notmuch_message_set_flag (notmuch_message_t *message, * For the original textual representation of the Date header from the * message call notmuch_message_get_header() with a header value of * "date". + * + * Returns 0 in case of error. */ time_t -notmuch_message_get_date (notmuch_message_t *message); +notmuch_message_get_date (notmuch_message_t *message); /** * Get the value of the specified header from 'message' as a UTF-8 string. @@ -1316,8 +1863,10 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag); * See notmuch_message_freeze for an example showing how to safely * replace tag values. * - * NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in read-only - * mode so message cannot be modified. + * @retval #NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in + * read-only mode so message cannot be modified. + * @retval #NOTMUCH_STATUS_XAPIAN_EXCEPTION: an exception was thrown + * accessing the database. */ notmuch_status_t notmuch_message_remove_all_tags (notmuch_message_t *message); @@ -1350,7 +1899,7 @@ notmuch_message_remove_all_tags (notmuch_message_t *message); * * A client can ensure that notmuch database tags remain synchronized * with maildir flags by calling this function after each call to - * notmuch_database_add_message. See also + * notmuch_database_index_file. See also * notmuch_message_tags_to_maildir_flags for synchronizing tag changes * back to maildir flags. */ @@ -1358,25 +1907,55 @@ notmuch_status_t notmuch_message_maildir_flags_to_tags (notmuch_message_t *message); /** - * Rename message filename(s) to encode tags as maildir flags. - * - * Specifically, for each filename corresponding to this message: + * return TRUE if any filename of 'message' has maildir flag 'flag', + * FALSE otherwise. * - * If the filename is not in a maildir directory, do nothing. (A - * maildir directory is determined as a directory named "new" or - * "cur".) Similarly, if the filename has invalid maildir info, - * (repeated or outof-ASCII-order flag characters after ":2,"), then - * do nothing. + * Deprecated wrapper for notmuch_message_has_maildir_flag_st * - * If the filename is in a maildir directory, rename the file so that - * its filename ends with the sequence ":2," followed by zero or more + * @returns FALSE in case of error + * @deprecated libnotmuch 5.3 (notmuch 0.31) + */ +NOTMUCH_DEPRECATED (5, 3) +notmuch_bool_t +notmuch_message_has_maildir_flag (notmuch_message_t *message, char flag); + +/** + * check message for maildir flag + * + * @param [in,out] message message to check + * @param [in] flag flag to check for + * @param [out] is_set pointer to boolean + * + * @retval #NOTMUCH_STATUS_SUCCESS + * @retval #NOTMUCH_STATUS_NULL_POINTER is_set is NULL + * @retval #NOTMUCH_STATUS_XAPIAN_EXCEPTION Accessing the database + * triggered an exception. + */ +notmuch_status_t +notmuch_message_has_maildir_flag_st (notmuch_message_t *message, + char flag, + notmuch_bool_t *is_set); + +/** + * Rename message filename(s) to encode tags as maildir flags. + * + * Specifically, for each filename corresponding to this message: + * + * If the filename is not in a maildir directory, do nothing. (A + * maildir directory is determined as a directory named "new" or + * "cur".) Similarly, if the filename has invalid maildir info, + * (repeated or outof-ASCII-order flag characters after ":2,"), then + * do nothing. + * + * If the filename is in a maildir directory, rename the file so that + * its filename ends with the sequence ":2," followed by zero or more * of the following single-character flags (in ASCII order): * - * 'D' iff the message has the "draft" tag - * 'F' iff the message has the "flagged" tag - * 'P' iff the message has the "passed" tag - * 'R' iff the message has the "replied" tag - * 'S' iff the message does not have the "unread" tag + * * flag 'D' iff the message has the "draft" tag + * * flag 'F' iff the message has the "flagged" tag + * * flag 'P' iff the message has the "passed" tag + * * flag 'R' iff the message has the "replied" tag + * * flag 'S' iff the message does not have the "unread" tag * * Any existing flags unmentioned in the list above will be preserved * in the renaming. @@ -1474,6 +2053,218 @@ notmuch_message_thaw (notmuch_message_t *message); void notmuch_message_destroy (notmuch_message_t *message); +/** + * @name Message Properties + * + * This interface provides the ability to attach arbitrary (key,value) + * string pairs to a message, to remove such pairs, and to iterate + * over them. The caller should take some care as to what keys they + * add or delete values for, as other subsystems or extensions may + * depend on these properties. + * + * Please see notmuch-properties(7) for more details about specific + * properties and conventions around their use. + * + */ +/**@{*/ +/** + * Retrieve the value for a single property key + * + * *value* is set to a string owned by the message or NULL if there is + * no such key. In the case of multiple values for the given key, the + * first one is retrieved. + * + * @returns + * - NOTMUCH_STATUS_NULL_POINTER: *value* may not be NULL. + * - NOTMUCH_STATUS_SUCCESS: No error occurred. + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_status_t +notmuch_message_get_property (notmuch_message_t *message, const char *key, const char **value); + +/** + * Add a (key,value) pair to a message + * + * @returns + * - NOTMUCH_STATUS_ILLEGAL_ARGUMENT: *key* may not contain an '=' character. + * - NOTMUCH_STATUS_NULL_POINTER: Neither *key* nor *value* may be NULL. + * - NOTMUCH_STATUS_SUCCESS: No error occurred. + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_status_t +notmuch_message_add_property (notmuch_message_t *message, const char *key, const char *value); + +/** + * Remove a (key,value) pair from a message. + * + * It is not an error to remove a non-existent (key,value) pair + * + * @returns + * - NOTMUCH_STATUS_ILLEGAL_ARGUMENT: *key* may not contain an '=' character. + * - NOTMUCH_STATUS_NULL_POINTER: Neither *key* nor *value* may be NULL. + * - NOTMUCH_STATUS_SUCCESS: No error occurred. + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_status_t +notmuch_message_remove_property (notmuch_message_t *message, const char *key, const char *value); + +/** + * Remove all (key,value) pairs from the given message. + * + * @param[in,out] message message to operate on. + * @param[in] key key to delete properties for. If NULL, delete + * properties for all keys + * @returns + * - NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in + * read-only mode so message cannot be modified. + * - NOTMUCH_STATUS_SUCCESS: No error occurred. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_status_t +notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key); + +/** + * Remove all (prefix*,value) pairs from the given message + * + * @param[in,out] message message to operate on. + * @param[in] prefix delete properties with keys that start with prefix. + * If NULL, delete all properties + * @returns + * - NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in + * read-only mode so message cannot be modified. + * - NOTMUCH_STATUS_SUCCESS: No error occurred. + * + * @since libnotmuch 5.1 (notmuch 0.26) + */ +notmuch_status_t +notmuch_message_remove_all_properties_with_prefix (notmuch_message_t *message, const char *prefix); + +/** + * Opaque message property iterator + */ +typedef struct _notmuch_string_map_iterator notmuch_message_properties_t; + +/** + * Get the properties for *message*, returning a + * notmuch_message_properties_t object which can be used to iterate + * over all properties. + * + * The notmuch_message_properties_t object is owned by the message and + * as such, will only be valid for as long as the message is valid, + * (which is until the query from which it derived is destroyed). + * + * @param[in] message The message to examine + * @param[in] key key or key prefix + * @param[in] exact if TRUE, require exact match with key. Otherwise + * treat as prefix. + * + * Typical usage might be: + * + * notmuch_message_properties_t *list; + * + * for (list = notmuch_message_get_properties (message, "testkey1", TRUE); + * notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) { + * printf("%s\n", notmuch_message_properties_value(list)); + * } + * + * notmuch_message_properties_destroy (list); + * + * Note that there's no explicit destructor needed for the + * notmuch_message_properties_t object. (For consistency, we do + * provide a notmuch_message_properities_destroy function, but there's + * no good reason to call it if the message is about to be destroyed). + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_message_properties_t * +notmuch_message_get_properties (notmuch_message_t *message, const char *key, notmuch_bool_t exact); + +/** + * Return the number of properties named "key" belonging to the specific message. + * + * @param[in] message The message to examine + * @param[in] key key to count + * @param[out] count The number of matching properties associated with this message. + * + * @returns + * + * NOTMUCH_STATUS_SUCCESS: successful count, possibly some other error. + * + * @since libnotmuch 5.2 (notmuch 0.27) + */ +notmuch_status_t +notmuch_message_count_properties (notmuch_message_t *message, const char *key, unsigned int *count); + +/** + * Is the given *properties* iterator pointing at a valid (key,value) + * pair. + * + * When this function returns TRUE, + * notmuch_message_properties_{key,value} will return a valid string, + * and notmuch_message_properties_move_to_next will do what it + * says. Whereas when this function returns FALSE, calling any of + * these functions results in undefined behaviour. + * + * See the documentation of notmuch_message_get_properties for example + * code showing how to iterate over a notmuch_message_properties_t + * object. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_bool_t +notmuch_message_properties_valid (notmuch_message_properties_t *properties); + +/** + * Move the *properties* iterator to the next (key,value) pair + * + * If *properties* is already pointing at the last pair then the iterator + * will be moved to a point just beyond that last pair, (where + * notmuch_message_properties_valid will return FALSE). + * + * See the documentation of notmuch_message_get_properties for example + * code showing how to iterate over a notmuch_message_properties_t object. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +void +notmuch_message_properties_move_to_next (notmuch_message_properties_t *properties); + +/** + * Return the key from the current (key,value) pair. + * + * this could be useful if iterating for a prefix + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +const char * +notmuch_message_properties_key (notmuch_message_properties_t *properties); + +/** + * Return the value from the current (key,value) pair. + * + * This could be useful if iterating for a prefix. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +const char * +notmuch_message_properties_value (notmuch_message_properties_t *properties); + + +/** + * Destroy a notmuch_message_properties_t object. + * + * It's not strictly necessary to call this function. All memory from + * the notmuch_message_properties_t object will be reclaimed when the + * containing message object is destroyed. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +void +notmuch_message_properties_destroy (notmuch_message_properties_t *properties); + +/**@}*/ + /** * Is the given 'tags' iterator pointing at a valid tag. * @@ -1481,6 +2272,9 @@ notmuch_message_destroy (notmuch_message_t *message); * valid string. Whereas when this function returns FALSE, * notmuch_tags_get will return NULL. * + * It is acceptable to pass NULL for 'tags', in which case this + * function will always return FALSE. + * See the documentation of notmuch_message_get_tags for example code * showing how to iterate over a notmuch_tags_t object. */ @@ -1535,7 +2329,7 @@ notmuch_tags_destroy (notmuch_tags_t *tags); * * o Read the mtime of a directory from the filesystem * - * o Call add_message for all mail files in the directory + * o Call index_file for all mail files in the directory * * o Call notmuch_directory_set_mtime with the mtime read from the * filesystem. @@ -1580,20 +2374,34 @@ notmuch_directory_get_mtime (notmuch_directory_t *directory); * * The returned filenames will be the basename-entries only (not * complete paths). + * + * Returns NULL if it triggers a Xapian exception */ notmuch_filenames_t * notmuch_directory_get_child_files (notmuch_directory_t *directory); /** - * Get a notmuch_filenams_t iterator listing all the filenames of + * Get a notmuch_filenames_t iterator listing all the filenames of * sub-directories in the database within the given directory. * * The returned filenames will be the basename-entries only (not * complete paths). + * + * Returns NULL if it triggers a Xapian exception */ notmuch_filenames_t * notmuch_directory_get_child_directories (notmuch_directory_t *directory); +/** + * Delete directory document from the database, and destroy the + * notmuch_directory_t object. Assumes any child directories and files + * have been deleted by the caller. + * + * @since libnotmuch 4.3 (notmuch 0.21) + */ +notmuch_status_t +notmuch_directory_delete (notmuch_directory_t *directory); + /** * Destroy a notmuch_directory_t object. */ @@ -1652,7 +2460,412 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames); void notmuch_filenames_destroy (notmuch_filenames_t *filenames); -/* @} */ + +/** + * set config 'key' to 'value' + * + * @since libnotmuch 4.4 (notmuch 0.23) + * @retval #NOTMUCH_STATUS_READ_ONLY_DATABASE: Database was opened in + * read-only mode so message cannot be modified. + * @retval #NOTMUCH_STATUS_XAPIAN_EXCEPTION: an exception was thrown + * accessing the database. + * @retval #NOTMUCH_STATUS_SUCCESS + */ +notmuch_status_t +notmuch_database_set_config (notmuch_database_t *db, const char *key, const char *value); + +/** + * retrieve config item 'key', assign to 'value' + * + * keys which have not been previously set with n_d_set_config will + * return an empty string. + * + * return value is allocated by malloc and should be freed by the + * caller. + * + * @since libnotmuch 4.4 (notmuch 0.23) + * + */ +notmuch_status_t +notmuch_database_get_config (notmuch_database_t *db, const char *key, char **value); + +/** + * Create an iterator for all config items with keys matching a given prefix + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_status_t +notmuch_database_get_config_list (notmuch_database_t *db, const char *prefix, + notmuch_config_list_t **out); + +/** + * Is 'config_list' iterator valid (i.e. _key, _value, _move_to_next can be called). + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_bool_t +notmuch_config_list_valid (notmuch_config_list_t *config_list); + +/** + * return key for current config pair + * + * return value is owned by the iterator, and will be destroyed by the + * next call to notmuch_config_list_key or notmuch_config_list_destroy. + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +const char * +notmuch_config_list_key (notmuch_config_list_t *config_list); + +/** + * return 'value' for current config pair + * + * return value is owned by the iterator, and will be destroyed by the + * next call to notmuch_config_list_value or notmuch config_list_destroy + * + * @since libnotmuch 4.4 (notmuch 0.23) + * @retval NULL for errors + */ +const char * +notmuch_config_list_value (notmuch_config_list_t *config_list); + + +/** + * move 'config_list' iterator to the next pair + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +void +notmuch_config_list_move_to_next (notmuch_config_list_t *config_list); + +/** + * free any resources held by 'config_list' + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +void +notmuch_config_list_destroy (notmuch_config_list_t *config_list); + +/** + * Configuration keys known to libnotmuch + */ +typedef enum { + NOTMUCH_CONFIG_FIRST, + NOTMUCH_CONFIG_DATABASE_PATH = NOTMUCH_CONFIG_FIRST, + NOTMUCH_CONFIG_MAIL_ROOT, + NOTMUCH_CONFIG_HOOK_DIR, + NOTMUCH_CONFIG_BACKUP_DIR, + NOTMUCH_CONFIG_EXCLUDE_TAGS, + NOTMUCH_CONFIG_NEW_TAGS, + NOTMUCH_CONFIG_NEW_IGNORE, + NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS, + NOTMUCH_CONFIG_PRIMARY_EMAIL, + NOTMUCH_CONFIG_OTHER_EMAIL, + NOTMUCH_CONFIG_USER_NAME, + NOTMUCH_CONFIG_AUTOCOMMIT, + NOTMUCH_CONFIG_EXTRA_HEADERS, + NOTMUCH_CONFIG_INDEX_AS_TEXT, + NOTMUCH_CONFIG_LAST +} notmuch_config_key_t; + +/** + * get a configuration value from an open database. + * + * This value reflects all configuration information given at the time + * the database was opened. + * + * @param[in] notmuch database + * @param[in] key configuration key + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval NULL if 'key' unknown or if no value is known for + * 'key'. Otherwise returns a string owned by notmuch which should + * not be modified nor freed by the caller. + */ +const char * +notmuch_config_get (notmuch_database_t *notmuch, notmuch_config_key_t key); + +/** + * set a configuration value from in an open database. + * + * This value reflects all configuration information given at the time + * the database was opened. + * + * @param[in,out] notmuch database open read/write + * @param[in] key configuration key + * @param[in] val configuration value + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval returns any return value for notmuch_database_set_config. + */ +notmuch_status_t +notmuch_config_set (notmuch_database_t *notmuch, notmuch_config_key_t key, const char *val); + +/** + * Returns an iterator for a ';'-delimited list of configuration values + * + * These values reflect all configuration information given at the + * time the database was opened. + * + * @param[in] notmuch database + * @param[in] key configuration key + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval NULL in case of error. + */ +notmuch_config_values_t * +notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key); + +/** + * Returns an iterator for a ';'-delimited list of configuration values + * + * These values reflect all configuration information given at the + * time the database was opened. + * + * @param[in] notmuch database + * @param[in] key configuration key + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval NULL in case of error. + */ +notmuch_config_values_t * +notmuch_config_get_values_string (notmuch_database_t *notmuch, const char *key); + +/** + * Is the given 'config_values' iterator pointing at a valid element. + * + * @param[in] values iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval FALSE if passed a NULL pointer, or the iterator is exhausted. + * + */ +notmuch_bool_t +notmuch_config_values_valid (notmuch_config_values_t *values); + +/** + * Get the current value from the 'values' iterator + * + * @param[in] values iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval a string with the same lifetime as the iterator + */ +const char * +notmuch_config_values_get (notmuch_config_values_t *values); + +/** + * Move the 'values' iterator to the next element + * + * @param[in,out] values iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + */ +void +notmuch_config_values_move_to_next (notmuch_config_values_t *values); + + +/** + * reset the 'values' iterator to the first element + * + * @param[in,out] values iterator. A NULL value is ignored. + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + */ +void +notmuch_config_values_start (notmuch_config_values_t *values); + +/** + * Destroy a config values iterator, along with any associated + * resources. + * + * @param[in,out] values iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + */ +void +notmuch_config_values_destroy (notmuch_config_values_t *values); + + +/** + * Returns an iterator for a (key, value) configuration pairs + * + * @param[in] notmuch database + * @param[in] prefix prefix for keys. Pass "" for all keys. + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval NULL in case of error. + */ +notmuch_config_pairs_t * +notmuch_config_get_pairs (notmuch_database_t *notmuch, + const char *prefix); + +/** + * Is the given 'config_pairs' iterator pointing at a valid element. + * + * @param[in] pairs iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval FALSE if passed a NULL pointer, or the iterator is exhausted. + * + */ +notmuch_bool_t +notmuch_config_pairs_valid (notmuch_config_pairs_t *pairs); + +/** + * Move the 'config_pairs' iterator to the next element + * + * @param[in,out] pairs iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + */ +void +notmuch_config_pairs_move_to_next (notmuch_config_pairs_t *pairs); + +/** + * Get the current key from the 'config_pairs' iterator + * + * @param[in] pairs iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval a string with the same lifetime as the iterator + */ +const char * +notmuch_config_pairs_key (notmuch_config_pairs_t *pairs); + +/** + * Get the current value from the 'config_pairs' iterator + * + * @param[in] pairs iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval a string with the same lifetime as the iterator + */ +const char * +notmuch_config_pairs_value (notmuch_config_pairs_t *pairs); + +/** + * Destroy a config_pairs iterator, along with any associated + * resources. + * + * @param[in,out] pairs iterator + * + * @since libnotmuch 5.4 (notmuch 0.32) + */ +void +notmuch_config_pairs_destroy (notmuch_config_pairs_t *pairs); + +/** + * get a configuration value from an open database as Boolean + * + * This value reflects all configuration information given at the time + * the database was opened. + * + * @param[in] notmuch database + * @param[in] key configuration key + * @param[out] val configuration value, converted to Boolean + * + * @since libnotmuch 5.4 (notmuch 0.32) + * + * @retval #NOTMUCH_STATUS_ILLEGAL_ARGUMENT if either key is unknown + * or the corresponding value does not convert to Boolean. + */ +notmuch_status_t +notmuch_config_get_bool (notmuch_database_t *notmuch, + notmuch_config_key_t key, + notmuch_bool_t *val); + +/** + * return the path of the config file loaded, if any + * + * @retval NULL if no config file was loaded + */ +const char * +notmuch_config_path (notmuch_database_t *notmuch); + +/** + * get the current default indexing options for a given database. + * + * This object will survive until the database itself is destroyed, + * but the caller may also release it earlier with + * notmuch_indexopts_destroy. + * + * This object represents a set of options on how a message can be + * added to the index. At the moment it is a featureless stub. + * + * @since libnotmuch 5.1 (notmuch 0.26) + * @retval NULL in case of error + */ +notmuch_indexopts_t * +notmuch_database_get_default_indexopts (notmuch_database_t *db); + +/** + * Stating a policy about how to decrypt messages. + * + * See index.decrypt in notmuch-config(1) for more details. + */ +typedef enum { + NOTMUCH_DECRYPT_FALSE, + NOTMUCH_DECRYPT_TRUE, + NOTMUCH_DECRYPT_AUTO, + NOTMUCH_DECRYPT_NOSTASH, +} notmuch_decryption_policy_t; + +/** + * Specify whether to decrypt encrypted parts while indexing. + * + * Be aware that the index is likely sufficient to reconstruct the + * cleartext of the message itself, so please ensure that the notmuch + * message index is adequately protected. DO NOT SET THIS FLAG TO TRUE + * without considering the security of your index. + * + * @since libnotmuch 5.1 (notmuch 0.26) + */ +notmuch_status_t +notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts, + notmuch_decryption_policy_t decrypt_policy); + +/** + * Return whether to decrypt encrypted parts while indexing. + * see notmuch_indexopts_set_decrypt_policy. + * + * @since libnotmuch 5.1 (notmuch 0.26) + */ +notmuch_decryption_policy_t +notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts); + +/** + * Destroy a notmuch_indexopts_t object. + * + * @since libnotmuch 5.1 (notmuch 0.26) + */ +void +notmuch_indexopts_destroy (notmuch_indexopts_t *options); + + +/** + * interrogate the library for compile time features + * + * @since libnotmuch 4.4 (notmuch 0.23) + */ +notmuch_bool_t +notmuch_built_with (const char *name); +/**@}*/ + +#pragma GCC visibility pop NOTMUCH_END_DECLS