* If there is already a document with message ID 'message_id' in the
* database, then the returned message can be used to query/modify the
* document. Otherwise, a new document will be inserted into the
- * database before this function returns.
+ * database before this function returns, (and *status will be set
+ * to NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND).
*
* If an error occurs, this function will return NULL and *status
* will be set as appropriate. (The status pointer argument must
_notmuch_message_create_for_message_id (const void *talloc_owner,
notmuch_database_t *notmuch,
const char *message_id,
- notmuch_status_t *status)
+ notmuch_private_status_t *status_ret)
{
- notmuch_private_status_t private_status;
notmuch_message_t *message;
Xapian::Document doc;
unsigned int doc_id;
char *term;
- *status = NOTMUCH_STATUS_SUCCESS;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_SUCCESS;
message = notmuch_database_find_message (notmuch, message_id);
if (message)
term = talloc_asprintf (NULL, "%s%s",
_find_prefix ("id"), message_id);
if (term == NULL) {
- *status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY;
return NULL;
}
doc_id = notmuch->xapian_db->add_document (doc);
} catch (const Xapian::Error &error) {
- *status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
return NULL;
}
message = _notmuch_message_create (talloc_owner, notmuch,
- doc_id, &private_status);
+ doc_id, status_ret);
- *status = COERCE_STATUS (private_status,
- "Failed to find dcocument after inserting it.");
+ /* We want to inform the caller that we had to create a new
+ * document. */
+ if (*status_ret == NOTMUCH_PRIVATE_STATUS_SUCCESS)
+ *status_ret = NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND;
return message;
}
return message->message_id;
}
+static void
+_notmuch_message_ensure_message_file (notmuch_message_t *message)
+{
+ const char *filename;
+
+ if (message->message_file)
+ return;
+
+ filename = notmuch_message_get_filename (message);
+ if (unlikely (filename == NULL))
+ return;
+
+ message->message_file = _notmuch_message_file_open_ctx (message, filename);
+}
+
+const char *
+notmuch_message_get_header (notmuch_message_t *message, const char *header)
+{
+ _notmuch_message_ensure_message_file (message);
+ if (message->message_file == NULL)
+ return NULL;
+
+ return notmuch_message_file_get_header (message->message_file, header);
+}
+
const char *
-_notmuch_message_get_subject (notmuch_message_t *message)
+notmuch_message_get_all_headers (notmuch_message_t *message)
{
- if (! message->message_file) {
- notmuch_message_file_t *message_file;
- const char *filename;
+ _notmuch_message_ensure_message_file (message);
+ if (message->message_file == NULL)
+ return NULL;
- filename = notmuch_message_get_filename (message);
- if (unlikely (filename == NULL))
- return NULL;
+ return notmuch_message_file_get_all_headers (message->message_file);
+}
- message_file = _notmuch_message_file_open_ctx (message, filename);
- if (unlikely (message_file == NULL))
- return NULL;
+size_t
+notmuch_message_get_header_size (notmuch_message_t *message)
+{
+ _notmuch_message_ensure_message_file (message);
+ if (message->message_file == NULL)
+ return 0;
- message->message_file = message_file;
- }
+ return notmuch_message_file_get_header_size (message->message_file);
- return notmuch_message_file_get_header (message->message_file,
- "subject");
}
const char *
_notmuch_message_set_filename (notmuch_message_t *message,
const char *filename)
{
- if (message->filename)
+ const char *s;
+ const char *db_path;
+ unsigned int db_path_len;
+
+ if (message->filename) {
talloc_free (message->filename);
- message->doc.set_data (filename);
+ message->filename = NULL;
+ }
+
+ if (filename == NULL)
+ INTERNAL_ERROR ("Message filename cannot be NULL.");
+
+ s = filename;
+
+ db_path = notmuch_database_get_path (message->notmuch);
+ db_path_len = strlen (db_path);
+
+ if (*s == '/' && strncmp (s, db_path, db_path_len) == 0
+ && strlen (s) > db_path_len)
+ {
+ s += db_path_len + 1;
+ }
+
+ message->doc.set_data (s);
}
const char *
notmuch_message_get_filename (notmuch_message_t *message)
{
std::string filename_str;
+ const char *db_path;
if (message->filename)
return message->filename;
filename_str = message->doc.get_data ();
- message->filename = talloc_strdup (message, filename_str.c_str ());
+ db_path = notmuch_database_get_path (message->notmuch);
+
+ if (filename_str[0] != '/')
+ message->filename = talloc_asprintf (message, "%s/%s", db_path,
+ filename_str.c_str ());
+ else
+ message->filename = talloc_strdup (message, filename_str.c_str ());
return message->filename;
}
+time_t
+notmuch_message_get_date (notmuch_message_t *message)
+{
+ std::string value;
+
+ try {
+ value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
+ } catch (Xapian::Error &error) {
+ INTERNAL_ERROR ("Failed to read timestamp value from document.");
+ return 0;
+ }
+
+ return Xapian::sortable_unserialise (value);
+}
+
notmuch_tags_t *
notmuch_message_get_tags (notmuch_message_t *message)
{