X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;ds=sidebyside;f=database.cc;h=5b594c024f3e19b8ee0adad3419dfb4e790514e6;hb=0aa355cc8fb46ae049052a913c2f2ab89ccba23c;hp=415040bc7000c4f9cb195e25cb9119d72c15a29d;hpb=5ebb21600e5d4e9441ff82b93ba1691149ccd909;p=notmuch diff --git a/database.cc b/database.cc index 415040bc..5b594c02 100644 --- a/database.cc +++ b/database.cc @@ -28,6 +28,50 @@ using namespace std; +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0])) + +/* These prefix values are specifically chosen to be compatible + * with sup, (http://sup.rubyforge.org), written by + * William Morgan , and released + * under the GNU GPL v2. + */ + +typedef struct { + const char *name; + const char *prefix; +} prefix_t; + +prefix_t BOOLEAN_PREFIX_INTERNAL[] = { + { "type", "K" }, + { "thread", "H" }, + { "ref", "R" }, + { "timestamp", "KTS" }, +}; + +prefix_t BOOLEAN_PREFIX_EXTERNAL[] = { + { "tag", "L" }, + { "id", "Q" } +}; + +const char * +_find_prefix (const char *name) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_INTERNAL); i++) + if (strcmp (name, BOOLEAN_PREFIX_INTERNAL[i].name) == 0) + return BOOLEAN_PREFIX_INTERNAL[i].prefix; + + for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) + if (strcmp (name, BOOLEAN_PREFIX_EXTERNAL[i].name) == 0) + return BOOLEAN_PREFIX_EXTERNAL[i].prefix; + + fprintf (stderr, "Internal error: No prefix exists for '%s'\n", name); + exit (1); + + return ""; +} + const char * notmuch_status_to_string (notmuch_status_t status) { @@ -40,6 +84,8 @@ notmuch_status_to_string (notmuch_status_t status) 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_DUPLICATE_MESSAGE_ID: + return "Message ID is identical to a message in database"; case NOTMUCH_STATUS_NULL_POINTER: return "Erroneous NULL pointer"; case NOTMUCH_STATUS_TAG_TOO_LONG: @@ -167,7 +213,7 @@ notmuch_database_find_message (notmuch_database_t *notmuch, notmuch_private_status_t status; unsigned int doc_id; - status = find_unique_doc_id (notmuch, "msgid", message_id, &doc_id); + status = find_unique_doc_id (notmuch, "id", message_id, &doc_id); if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) return NULL; @@ -430,6 +476,7 @@ notmuch_database_open (const char *path) struct stat st; int err; char *local_path = NULL; + unsigned int i; if (path == NULL) path = local_path = notmuch_database_default_path (); @@ -454,6 +501,12 @@ notmuch_database_open (const char *path) notmuch->query_parser = new Xapian::QueryParser; notmuch->query_parser->set_default_op (Xapian::Query::OP_AND); notmuch->query_parser->set_database (*notmuch->xapian_db); + + for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) { + prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i]; + notmuch->query_parser->add_boolean_prefix (prefix->name, + prefix->prefix); + } } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred: %s\n", error.get_msg().c_str()); @@ -503,11 +556,12 @@ find_timestamp_document (notmuch_database_t *notmuch, const char *db_key, static char * timestamp_db_key (const char *key) { - if (strlen (key) + 1 > NOTMUCH_TERM_MAX) { + int term_len = strlen (_find_prefix ("timestamp")) + strlen (key); + + if (term_len > NOTMUCH_TERM_MAX) return notmuch_sha1_of_string (key); - } else { + else return strdup (key); - } } notmuch_status_t @@ -656,23 +710,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch, /* Has a message previously been added with the same ID? */ old_filename = notmuch_message_get_filename (message); if (old_filename && strlen (old_filename)) { - /* XXX: This is too noisy to actually print, and what do we - * really expect the user to do? Go manually delete a - * redundant message or merge two similar messages? - * Instead we should handle this transparently. - * - * What we likely want to move to is adding both filenames - * to the database so that subsequent indexing will pick up - * terms from both files. - */ -#if 0 - fprintf (stderr, - "Note: Attempting to add a message with a duplicate message ID:\n" - "Old: %s\n" "New: %s\n", - old_filename, filename); - fprintf (stderr, "The old filename will be used, but any new terms\n" - "from the new message will added to the database.\n"); -#endif + ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; + goto DONE; } else { _notmuch_message_set_filename (message, filename); _notmuch_message_add_term (message, "type", "mail");