X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Fmessage.cc;h=7aff4ae5111a800a4204c0255e2b070c86164fce;hp=1b4637950f8e1a4475a4385db20fd6f4ccf7dd54;hb=4d150eba6775d9c34276547c7ae248a8ec4e6107;hpb=a9b2135c75874f871fa8e97c8fca965654577772 diff --git a/lib/message.cc b/lib/message.cc index 1b463795..7aff4ae5 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -412,19 +412,27 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message) const char * notmuch_message_get_header (notmuch_message_t *message, const char *header) { - std::string value; + try { + std::string value; - /* Fetch header from the appropriate xapian value field if - * available */ - if (strcasecmp (header, "from") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_FROM); - else if (strcasecmp (header, "subject") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT); - else if (strcasecmp (header, "message-id") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID); + /* Fetch header from the appropriate xapian value field if + * available */ + if (strcasecmp (header, "from") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_FROM); + else if (strcasecmp (header, "subject") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT); + else if (strcasecmp (header, "message-id") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID); - if (!value.empty()) - return talloc_strdup (message, value.c_str ()); + if (!value.empty()) + return talloc_strdup (message, value.c_str ()); + + } catch (Xapian::Error &error) { + fprintf (stderr, "A Xapian exception occurred when reading header: %s\n", + error.get_msg().c_str()); + message->notmuch->exception_reported = TRUE; + return NULL; + } /* Otherwise fall back to parsing the file */ _notmuch_message_ensure_message_file (message); @@ -473,6 +481,68 @@ notmuch_message_get_replies (notmuch_message_t *message) return _notmuch_messages_create (message->replies); } +static void +_notmuch_message_remove_terms (notmuch_message_t *message, const char *prefix) +{ + Xapian::TermIterator i; + size_t prefix_len = strlen (prefix); + + while (1) { + i = message->doc.termlist_begin (); + i.skip_to (prefix); + + /* Terminate loop when no terms remain with desired prefix. */ + if (i == message->doc.termlist_end () || + strncmp ((*i).c_str (), prefix, prefix_len)) + break; + + try { + message->doc.remove_term ((*i)); + } catch (const Xapian::InvalidArgumentError) { + /* Ignore failure to remove non-existent term. */ + } + } +} + +/* Add directory based terms for all filenames of the message. */ +static notmuch_status_t +_notmuch_message_add_directory_terms (void *ctx, notmuch_message_t *message) +{ + const char *direntry_prefix = _find_prefix ("file-direntry"); + int direntry_prefix_len = strlen (direntry_prefix); + Xapian::TermIterator i = message->doc.termlist_begin (); + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; + + for (i.skip_to (direntry_prefix); i != message->doc.termlist_end (); i++) { + unsigned int directory_id; + const char *direntry, *directory; + char *colon; + + /* Terminate loop at first term without desired prefix. */ + if (strncmp ((*i).c_str (), direntry_prefix, direntry_prefix_len)) + break; + + /* Indicate that there are filenames remaining. */ + status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; + + direntry = (*i).c_str (); + direntry += direntry_prefix_len; + + directory_id = strtol (direntry, &colon, 10); + + if (colon == NULL || *colon != ':') + INTERNAL_ERROR ("malformed direntry"); + + directory = _notmuch_database_get_directory_path (ctx, + message->notmuch, + directory_id); + if (strlen (directory)) + _notmuch_message_gen_terms (message, "folder", directory); + } + + return status; +} + /* Add an additional 'filename' for 'message'. * * This change will not be reflected in the database until the next @@ -528,17 +598,12 @@ notmuch_status_t _notmuch_message_remove_filename (notmuch_message_t *message, const char *filename) { - const char *direntry_prefix = _find_prefix ("file-direntry"); - int direntry_prefix_len = strlen (direntry_prefix); - const char *folder_prefix = _find_prefix ("folder"); - int folder_prefix_len = strlen (folder_prefix); void *local = talloc_new (message); + const char *folder_prefix = _find_prefix ("folder"); char *zfolder_prefix = talloc_asprintf(local, "Z%s", folder_prefix); - int zfolder_prefix_len = strlen (zfolder_prefix); char *direntry; notmuch_private_status_t private_status; notmuch_status_t status; - Xapian::TermIterator i, last; status = _notmuch_database_filename_to_direntry ( local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry); @@ -559,73 +624,13 @@ _notmuch_message_remove_filename (notmuch_message_t *message, * 3. adding back terms for all remaining filenames of the message. */ /* 1. removing all "folder:" terms */ - while (1) { - i = message->doc.termlist_begin (); - i.skip_to (folder_prefix); - - /* Terminate loop when no terms remain with desired prefix. */ - if (i == message->doc.termlist_end () || - strncmp ((*i).c_str (), folder_prefix, folder_prefix_len)) - { - break; - } - - try { - message->doc.remove_term ((*i)); - } catch (const Xapian::InvalidArgumentError) { - /* Ignore failure to remove non-existent term. */ - } - } + _notmuch_message_remove_terms (message, folder_prefix); /* 2. removing all "folder:" stemmed terms */ - while (1) { - i = message->doc.termlist_begin (); - i.skip_to (zfolder_prefix); - - /* Terminate loop when no terms remain with desired prefix. */ - if (i == message->doc.termlist_end () || - strncmp ((*i).c_str (), zfolder_prefix, zfolder_prefix_len)) - { - break; - } - - try { - message->doc.remove_term ((*i)); - } catch (const Xapian::InvalidArgumentError) { - /* Ignore failure to remove non-existent term. */ - } - } + _notmuch_message_remove_terms (message, zfolder_prefix); /* 3. adding back terms for all remaining filenames of the message. */ - i = message->doc.termlist_begin (); - i.skip_to (direntry_prefix); - - for (; i != message->doc.termlist_end (); i++) { - unsigned int directory_id; - const char *direntry, *directory; - char *colon; - - /* Terminate loop at first term without desired prefix. */ - if (strncmp ((*i).c_str (), direntry_prefix, direntry_prefix_len)) - break; - - /* Indicate that there are filenames remaining. */ - status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; - - direntry = (*i).c_str (); - direntry += direntry_prefix_len; - - directory_id = strtol (direntry, &colon, 10); - - if (colon == NULL || *colon != ':') - INTERNAL_ERROR ("malformed direntry"); - - directory = _notmuch_database_get_directory_path (local, - message->notmuch, - directory_id); - if (strlen (directory)) - _notmuch_message_gen_terms (message, "folder", directory); - } + status = _notmuch_message_add_directory_terms (local, message); talloc_free (local); @@ -766,7 +771,9 @@ notmuch_message_get_date (notmuch_message_t *message) try { value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP); } catch (Xapian::Error &error) { - INTERNAL_ERROR ("Failed to read timestamp value from document."); + fprintf (stderr, "A Xapian exception occurred when reading date: %s\n", + error.get_msg().c_str()); + message->notmuch->exception_reported = TRUE; return 0; }