return 0;
}
+#define LOG_XAPIAN_EXCEPTION(message, error) _log_xapian_exception (__location__, message, error)
+
+static void
+_log_xapian_exception (const char *where, notmuch_message_t *message, const Xapian::Error error) {
+ notmuch_database_t *notmuch = notmuch_message_get_database (message);
+ _notmuch_database_log (notmuch,
+ "A Xapian exception occurred at %s: %s\n",
+ where,
+ error.get_msg ().c_str ());
+ notmuch->exception_reported = true;
+}
+
static notmuch_message_t *
_notmuch_message_create_for_document (const void *talloc_owner,
notmuch_database_t *notmuch,
return NULL;
}
- if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
+ if (_notmuch_database_mode (notmuch) == NOTMUCH_DATABASE_MODE_READ_ONLY)
INTERNAL_ERROR ("Failure to ensure database is writable.");
try {
if (status != NOTMUCH_STATUS_SUCCESS)
INTERNAL_ERROR ("unhandled error from notmuch_database_reopen: %s\n",
notmuch_status_to_string (status));
- } catch (const Xapian::Error &error) {
- INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
- error.get_msg ().c_str ());
}
}
message->last_view = message->notmuch->view;
const char *
notmuch_message_get_message_id (notmuch_message_t *message)
{
- _notmuch_message_ensure_metadata (message, message->message_id);
+ try {
+ _notmuch_message_ensure_metadata (message, message->message_id);
+ } catch (const Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NULL;
+ }
+
if (! message->message_id)
INTERNAL_ERROR ("Message with document ID of %u has no message ID.\n",
message->doc_id);
return talloc_strdup (message, value.c_str ());
} catch (Xapian::Error &error) {
- _notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading header: %s\n",
- error.get_msg ().c_str ());
- message->notmuch->exception_reported = true;
+ LOG_XAPIAN_EXCEPTION (message, error);
return NULL;
}
}
const char *
notmuch_message_get_thread_id (notmuch_message_t *message)
{
- _notmuch_message_ensure_metadata (message, message->thread_id);
+ try {
+ _notmuch_message_ensure_metadata (message, message->thread_id);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NULL;
+ }
if (! message->thread_id)
INTERNAL_ERROR ("Message with document ID of %u has no thread ID.\n",
message->doc_id);
const char *tag = notmuch_tags_get (tags);
- if (STRNCMP_LITERAL (tag, "encrypted") != 0 &&
- STRNCMP_LITERAL (tag, "signed") != 0 &&
- STRNCMP_LITERAL (tag, "attachment") != 0) {
+ if (strcmp (tag, "encrypted") != 0 &&
+ strcmp (tag, "signed") != 0 &&
+ strcmp (tag, "attachment") != 0) {
std::string term = tag_prefix + tag;
message->doc.add_term (term);
}
const char *
notmuch_message_get_filename (notmuch_message_t *message)
{
- _notmuch_message_ensure_filename_list (message);
+ try {
+ _notmuch_message_ensure_filename_list (message);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NULL;
+ }
if (message->filename_list == NULL)
return NULL;
notmuch_filenames_t *
notmuch_message_get_filenames (notmuch_message_t *message)
{
- _notmuch_message_ensure_filename_list (message);
+ try {
+ _notmuch_message_ensure_filename_list (message);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NULL;
+ }
return _notmuch_filenames_create (message, message->filename_list);
}
int
notmuch_message_count_files (notmuch_message_t *message)
{
- _notmuch_message_ensure_filename_list (message);
+ try {
+ _notmuch_message_ensure_filename_list (message);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return -1;
+ }
return _notmuch_string_list_length (message->filename_list);
}
+notmuch_status_t
+notmuch_message_get_flag_st (notmuch_message_t *message,
+ notmuch_message_flag_t flag,
+ notmuch_bool_t *is_set)
+{
+ if (! is_set)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ try {
+ if (flag == NOTMUCH_MESSAGE_FLAG_GHOST &&
+ ! NOTMUCH_TEST_BIT (message->lazy_flags, flag))
+ _notmuch_message_ensure_metadata (message, NULL);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
+
+ *is_set = NOTMUCH_TEST_BIT (message->flags, flag);
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
notmuch_bool_t
notmuch_message_get_flag (notmuch_message_t *message,
notmuch_message_flag_t flag)
{
- if (flag == NOTMUCH_MESSAGE_FLAG_GHOST &&
- ! NOTMUCH_TEST_BIT (message->lazy_flags, flag))
- _notmuch_message_ensure_metadata (message, NULL);
+ notmuch_bool_t is_set;
+ notmuch_status_t status;
+
+ status = notmuch_message_get_flag_st (message, flag, &is_set);
- return NOTMUCH_TEST_BIT (message->flags, flag);
+ if (status)
+ return FALSE;
+ else
+ return is_set;
}
void
try {
value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
} catch (Xapian::Error &error) {
- _notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading date: %s\n",
- error.get_msg ().c_str ());
- message->notmuch->exception_reported = true;
+ LOG_XAPIAN_EXCEPTION (message, error);
return 0;
}
{
notmuch_tags_t *tags;
- _notmuch_message_ensure_metadata (message, message->tag_list);
+ try {
+ _notmuch_message_ensure_metadata (message, message->tag_list);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NULL;
+ }
tags = _notmuch_tags_create (message, message->tag_list);
/* _notmuch_tags_create steals the reference to the tag_list, but
void
_notmuch_message_sync (notmuch_message_t *message)
{
- Xapian::WritableDatabase *db;
-
- if (message->notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
+ if (_notmuch_database_mode (message->notmuch) == NOTMUCH_DATABASE_MODE_READ_ONLY)
return;
if (! message->modified)
_notmuch_database_new_revision (
message->notmuch)));
- db = static_cast <Xapian::WritableDatabase *> (message->notmuch->xapian_db);
- db->replace_document (message->doc_id, message->doc);
+ message->notmuch->writable_xapian_db->
+ replace_document (message->doc_id, message->doc);
message->modified = false;
}
_notmuch_message_delete (notmuch_message_t *message)
{
notmuch_status_t status;
- Xapian::WritableDatabase *db;
const char *mid, *tid, *query_string;
notmuch_message_t *ghost;
notmuch_private_status_t private_status;
if (status)
return status;
- db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
- db->delete_document (message->doc_id);
+ message->notmuch->writable_xapian_db->delete_document (message->doc_id);
/* if this was a ghost to begin with, we are done */
private_status = _notmuch_message_has_term (message, "type", "ghost", &is_ghost);
notmuch_private_status_t private_status;
notmuch_status_t status;
- status = _notmuch_database_ensure_writable (message->notmuch);
- if (status)
- return status;
+ try {
+ status = _notmuch_database_ensure_writable (message->notmuch);
+ if (status)
+ return status;
- if (tag == NULL)
- return NOTMUCH_STATUS_NULL_POINTER;
+ if (tag == NULL)
+ return NOTMUCH_STATUS_NULL_POINTER;
- if (strlen (tag) > NOTMUCH_TAG_MAX)
- return NOTMUCH_STATUS_TAG_TOO_LONG;
+ if (strlen (tag) > NOTMUCH_TAG_MAX)
+ return NOTMUCH_STATUS_TAG_TOO_LONG;
- private_status = _notmuch_message_add_term (message, "tag", tag);
- if (private_status) {
- INTERNAL_ERROR ("_notmuch_message_add_term return unexpected value: %d\n",
- private_status);
- }
+ private_status = _notmuch_message_add_term (message, "tag", tag);
+ if (private_status) {
+ return COERCE_STATUS (private_status,
+ "_notmuch_message_remove_term return unexpected value: %d\n",
+ private_status);
+ }
- if (! message->frozen)
- _notmuch_message_sync (message);
+ if (! message->frozen)
+ _notmuch_message_sync (message);
+
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
return NOTMUCH_STATUS_SUCCESS;
}
notmuch_private_status_t private_status;
notmuch_status_t status;
- status = _notmuch_database_ensure_writable (message->notmuch);
- if (status)
- return status;
+ try {
+ status = _notmuch_database_ensure_writable (message->notmuch);
+ if (status)
+ return status;
- if (tag == NULL)
- return NOTMUCH_STATUS_NULL_POINTER;
+ if (tag == NULL)
+ return NOTMUCH_STATUS_NULL_POINTER;
- if (strlen (tag) > NOTMUCH_TAG_MAX)
- return NOTMUCH_STATUS_TAG_TOO_LONG;
+ if (strlen (tag) > NOTMUCH_TAG_MAX)
+ return NOTMUCH_STATUS_TAG_TOO_LONG;
- private_status = _notmuch_message_remove_term (message, "tag", tag);
- if (private_status) {
- INTERNAL_ERROR ("_notmuch_message_remove_term return unexpected value: %d\n",
- private_status);
- }
+ private_status = _notmuch_message_remove_term (message, "tag", tag);
+ if (private_status) {
+ return COERCE_STATUS (private_status,
+ "_notmuch_message_remove_term return unexpected value: %d\n",
+ private_status);
+ }
- if (! message->frozen)
- _notmuch_message_sync (message);
+ if (! message->frozen)
+ _notmuch_message_sync (message);
+ } catch (Xapian::Error &error) {
+ LOG_XAPIAN_EXCEPTION (message, error);
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
return NOTMUCH_STATUS_SUCCESS;
}
return NULL;
}
-static void
+static notmuch_status_t
_ensure_maildir_flags (notmuch_message_t *message, bool force)
{
const char *flags;
message->maildir_flags = NULL;
}
}
-
- for (filenames = notmuch_message_get_filenames (message);
+ filenames = notmuch_message_get_filenames (message);
+ if (! filenames)
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ for (;
notmuch_filenames_valid (filenames);
notmuch_filenames_move_to_next (filenames)) {
filename = notmuch_filenames_get (filenames);
}
if (seen_maildir_info)
message->maildir_flags = combined_flags;
+ return NOTMUCH_STATUS_SUCCESS;
}
notmuch_bool_t
notmuch_message_has_maildir_flag (notmuch_message_t *message, char flag)
{
- _ensure_maildir_flags (message, false);
- return message->maildir_flags && (strchr (message->maildir_flags, flag) != NULL);
+ notmuch_status_t status;
+ notmuch_bool_t ret;
+ status = notmuch_message_has_maildir_flag_st (message, flag, &ret);
+ if (status)
+ return FALSE;
+
+ return ret;
+}
+
+notmuch_status_t
+notmuch_message_has_maildir_flag_st (notmuch_message_t *message,
+ char flag,
+ notmuch_bool_t *is_set)
+{
+ notmuch_status_t status;
+
+ if (! is_set)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ status = _ensure_maildir_flags (message, false);
+ if (status)
+ return status;
+
+ *is_set = message->maildir_flags && (strchr (message->maildir_flags, flag) != NULL);
+ return NOTMUCH_STATUS_SUCCESS;
}
notmuch_status_t
notmuch_status_t status;
unsigned i;
- _ensure_maildir_flags (message, true);
+ status = _ensure_maildir_flags (message, true);
+ if (status)
+ return status;
/* If none of the filenames have any maildir info field (not even
* an empty info with no flags set) then there's no information to
* go on, so do nothing. */
status = _notmuch_database_ensure_writable (message->notmuch);
if (status)
return status;
+ tags = notmuch_message_get_tags (message);
+ if (! tags)
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
- for (tags = notmuch_message_get_tags (message);
+ for (;
notmuch_tags_valid (tags);
notmuch_tags_move_to_next (tags)) {
tag = notmuch_tags_get (tags);
private_status = _notmuch_message_remove_term (message, "tag", tag);
if (private_status) {
- INTERNAL_ERROR ("_notmuch_message_remove_term return unexpected value: %d\n",
- private_status);
+ return COERCE_STATUS (private_status,
+ "_notmuch_message_remove_term return unexpected value: %d\n",
+ private_status);
}
}
/* Save in case we need to delete message */
orig_thread_id = notmuch_message_get_thread_id (message);
if (! orig_thread_id) {
- /* XXX TODO: make up new error return? */
- INTERNAL_ERROR ("message without thread-id");
+ /* the following is correct as long as there is only one reason
+ n_m_get_thread_id returns NULL
+ */
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
/* strdup it because the metadata may be invalidated */