return "No error occurred";
case NOTMUCH_STATUS_XAPIAN_EXCEPTION:
return "A Xapian exception occurred";
+ case NOTMUCH_STATUS_FILE_ERROR:
+ return "Something went wrong trying to read or write a file";
case NOTMUCH_STATUS_FILE_NOT_EMAIL:
return "File is not an email";
case NOTMUCH_STATUS_NULL_POINTER:
return db->get_document (docid);
}
+static void
+insert_thread_id (GHashTable *thread_ids, Xapian::Document doc)
+{
+ string value_string;
+ const char *value, *id, *comma;
+
+ value_string = doc.get_value (NOTMUCH_VALUE_THREAD);
+ value = value_string.c_str();
+ if (strlen (value)) {
+ id = value;
+ while (*id) {
+ comma = strchr (id, ',');
+ if (comma == NULL)
+ comma = id + strlen (id);
+ g_hash_table_insert (thread_ids,
+ strndup (id, comma - id), NULL);
+ id = comma;
+ if (*id)
+ id++;
+ }
+ }
+}
+
notmuch_message_t *
notmuch_database_find_message (notmuch_database_t *notmuch,
const char *message_id)
find_messages_by_term (db, "ref", message_id, &child, &children_end);
for ( ; child != children_end; child++) {
- const char *thread_id;
doc = find_message_by_docid (db, *child);
-
- thread_id = doc.get_value (NOTMUCH_VALUE_THREAD).c_str ();
- if (strlen (thread_id) == 0) {
- fprintf (stderr, "Database error: Message with doc_id %u has empty thread-id value (value index %d)\n",
- *child, NOTMUCH_VALUE_THREAD);
- } else {
- g_hash_table_insert (thread_ids, strdup (thread_id), NULL);
- }
+ insert_thread_id (thread_ids, doc);
}
for (i = 0; i < parents->len; i++) {
{
Xapian::WritableDatabase *db = notmuch->xapian_db;
Xapian::Document doc;
- notmuch_message_file_t *message;
+ notmuch_message_file_t *message_file;
+ notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
GPtrArray *parents, *thread_ids;
time_t time_value;
unsigned int i;
- message = notmuch_message_file_open (filename);
+ message_file = notmuch_message_file_open (filename);
+ if (message_file == NULL) {
+ ret = NOTMUCH_STATUS_FILE_ERROR;
+ goto DONE;
+ }
- notmuch_message_file_restrict_headers (message,
+ notmuch_message_file_restrict_headers (message_file,
"date",
"from",
"in-reply-to",
"message-id",
"references",
"subject",
+ "to",
(char *) NULL);
try {
parents = g_ptr_array_new ();
- refs = notmuch_message_file_get_header (message, "references");
+ refs = notmuch_message_file_get_header (message_file, "references");
parse_references (parents, refs);
- in_reply_to = notmuch_message_file_get_header (message, "in-reply-to");
+ in_reply_to = notmuch_message_file_get_header (message_file, "in-reply-to");
parse_references (parents, in_reply_to);
for (i = 0; i < parents->len; i++)
add_term (doc, "ref", (char *) g_ptr_array_index (parents, i));
- header = notmuch_message_file_get_header (message, "message-id");
+ header = notmuch_message_file_get_header (message_file, "message-id");
if (header) {
message_id = parse_message_id (header, NULL);
/* So the header value isn't RFC-compliant, but it's
if (message_id == NULL)
message_id = xstrdup (header);
} else {
- /* XXX: Should generate a message_id here, (such as a SHA1
- * sum of the message itself) */
- message_id = NULL;
+ /* No message-id at all, let's generate one by taking a
+ * hash over the file's contents. */
+ char *sha1 = notmuch_sha1_of_file (filename);
+
+ /* If that failed too, something is really wrong. Give up. */
+ if (sha1 == NULL) {
+ ret = NOTMUCH_STATUS_FILE_ERROR;
+ goto DONE;
+ }
+
+ message_id = g_strdup_printf ("notmuch-sha1-%s", sha1);
+ free (sha1);
}
thread_ids = find_thread_ids (notmuch, parents, message_id);
for (i = 0; i < parents->len; i++)
g_free (g_ptr_array_index (parents, i));
g_ptr_array_free (parents, TRUE);
- if (message_id) {
- add_term (doc, "msgid", message_id);
- doc.add_value (NOTMUCH_VALUE_MESSAGE_ID, message_id);
- }
+
+ add_term (doc, "msgid", message_id);
+ doc.add_value (NOTMUCH_VALUE_MESSAGE_ID, message_id);
+
+ free (message_id);
if (thread_ids->len) {
unsigned int i;
}
doc.add_value (NOTMUCH_VALUE_THREAD, thread_id->str);
g_string_free (thread_id, TRUE);
- } else if (message_id) {
+ } else {
/* If not part of any existing thread, generate a new thread_id. */
thread_id_t thread_id;
g_ptr_array_free (thread_ids, TRUE);
- free (message_id);
-
- date = notmuch_message_file_get_header (message, "date");
+ date = notmuch_message_file_get_header (message_file, "date");
time_value = notmuch_parse_date (date, NULL);
doc.add_value (NOTMUCH_VALUE_DATE,
Xapian::sortable_serialise (time_value));
- from = notmuch_message_file_get_header (message, "from");
- subject = notmuch_message_file_get_header (message, "subject");
- to = notmuch_message_file_get_header (message, "to");
+ from = notmuch_message_file_get_header (message_file, "from");
+ subject = notmuch_message_file_get_header (message_file, "subject");
+ to = notmuch_message_file_get_header (message_file, "to");
if (from == NULL &&
subject == NULL &&
to == NULL)
{
- notmuch_message_file_close (message);
- return NOTMUCH_STATUS_FILE_NOT_EMAIL;
+ ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
+ goto DONE;
} else {
db->add_document (doc);
}
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred: %s.\n",
error.get_msg().c_str());
- return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ goto DONE;
}
- notmuch_message_file_close (message);
+ DONE:
+ if (message_file)
+ notmuch_message_file_close (message_file);
- return NOTMUCH_STATUS_SUCCESS;
+ return ret;
}