X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=database.cc;h=aaad710552f9d4c496098ea19945f9f6b8ab1d26;hp=712ab260225658588f0d427888694c74a5728800;hb=5941b91a5eee61ae7d0f6c8f750df9187780e911;hpb=b3cbcea8fdfdc71c5021fac483943a45ace816d3 diff --git a/database.cc b/database.cc index 712ab260..aaad7105 100644 --- a/database.cc +++ b/database.cc @@ -28,6 +28,59 @@ using namespace std; +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0])) + +typedef struct { + const char *name; + const char *prefix; +} prefix_t; + +/* With these prefix values we follow the conventions published here: + * + * http://xapian.org/docs/omega/termprefixes.html + * + * as much as makes sense. Note that I took some liberty in matching + * the reserved prefix values to notmuch concepts, (for example, 'G' + * is documented as "newsGroup (or similar entity - e.g. a web forum + * name)", for which I think the thread is the closest analogue in + * notmuch. This in spite of the fact that we will eventually be + * storing mailing-list messages where 'G' for "mailing list name" + * might be even a closer analogue. I'm treating the single-character + * prefixes preferentially for core notmuch concepts (which will be + * nearly universal to all mail messages). + */ + +prefix_t BOOLEAN_PREFIX_INTERNAL[] = { + { "type", "T" }, + { "thread", "G" }, + { "ref", "XREFERENCE" }, + { "timestamp", "XTIMESTAMP" }, +}; + +prefix_t BOOLEAN_PREFIX_EXTERNAL[] = { + { "tag", "K" }, + { "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) { @@ -169,7 +222,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; @@ -432,6 +485,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 (); @@ -456,6 +510,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()); @@ -505,11 +565,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 @@ -527,7 +588,8 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch, try { status = find_timestamp_document (notmuch, db_key, &doc, &doc_id); - doc.add_value (0, Xapian::sortable_serialise (timestamp)); + doc.add_value (NOTMUCH_VALUE_TIMESTAMP, + Xapian::sortable_serialise (timestamp)); if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) { char *term = talloc_asprintf (NULL, "%s%s", @@ -569,7 +631,7 @@ notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key) if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) goto DONE; - ret = Xapian::sortable_unserialise (doc.get_value (0)); + ret = Xapian::sortable_unserialise (doc.get_value (NOTMUCH_VALUE_TIMESTAMP)); } catch (Xapian::Error &error) { goto DONE; }