X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=lib%2Fdatabase.cc;h=23ddd4ae1314b2186b7839364b06cc0d25b5a575;hp=bcea88b029e7a097a7887c7570e5715e7a78fc76;hb=e5316b320a51915fc1dbdd8724643931cd03327f;hpb=e2341cbc09b503f996fd46b68f9d96ae6004025b diff --git a/lib/database.cc b/lib/database.cc index bcea88b0..23ddd4ae 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -147,17 +147,20 @@ _find_prefix (const char *name) { unsigned int i; - for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_INTERNAL); 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++) + 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; + } - for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) + for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) { if (strcmp (name, PROBABILISTIC_PREFIX[i].name) == 0) return PROBABILISTIC_PREFIX[i].prefix; + } INTERNAL_ERROR ("No prefix exists for '%s'\n", name); @@ -295,13 +298,14 @@ skip_space_and_comments (const char **str) int nesting = 1; s++; while (*s && nesting) { - if (*s == '(') + if (*s == '(') { nesting++; - else if (*s == ')') + } else if (*s == ')') { nesting--; - else if (*s == '\\') + } else if (*s == '\\') { if (*(s+1)) s++; + } s++; } } @@ -497,11 +501,13 @@ notmuch_database_open (const char *path, notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; notmuch->term_gen->set_stemmer (Xapian::Stem ("english")); + notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); notmuch->query_parser->set_default_op (Xapian::Query::OP_AND); notmuch->query_parser->set_database (*notmuch->xapian_db); notmuch->query_parser->set_stemmer (Xapian::Stem ("english")); notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME); + notmuch->query_parser->add_valuerangeprocessor (notmuch->value_range_processor); for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) { prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i]; @@ -518,7 +524,7 @@ notmuch_database_open (const char *path, error.get_msg().c_str()); notmuch = NULL; } - + DONE: if (notmuch_path) free (notmuch_path); @@ -544,6 +550,7 @@ notmuch_database_close (notmuch_database_t *notmuch) delete notmuch->term_gen; delete notmuch->query_parser; delete notmuch->xapian_db; + delete notmuch->value_range_processor; talloc_free (notmuch); } @@ -648,6 +655,7 @@ notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key) ret = Xapian::sortable_unserialise (doc.get_value (NOTMUCH_VALUE_TIMESTAMP)); } catch (Xapian::Error &error) { + ret = 0; goto DONE; } @@ -891,7 +899,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch, const char *date, *header; const char *from, *to, *subject; - char *message_id; + char *message_id = NULL; if (message_ret) *message_ret = NULL; @@ -936,11 +944,20 @@ notmuch_database_add_message (notmuch_database_t *notmuch, header = notmuch_message_file_get_header (message_file, "message-id"); if (header && *header != '\0') { message_id = _parse_message_id (message_file, header, NULL); + /* So the header value isn't RFC-compliant, but it's * better than no message-id at all. */ if (message_id == NULL) message_id = talloc_strdup (message_file, header); - } else { + + /* Reject a Message ID that's too long. */ + if (message_id && strlen (message_id) + 1 > NOTMUCH_TERM_MAX) { + talloc_free (message_id); + message_id = NULL; + } + } + + if (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); @@ -1012,3 +1029,46 @@ notmuch_database_add_message (notmuch_database_t *notmuch, return ret; } + +notmuch_tags_t * +_notmuch_convert_tags (void *ctx, Xapian::TermIterator &i, + Xapian::TermIterator &end) +{ + const char *prefix = _find_prefix ("tag"); + notmuch_tags_t *tags; + std::string tag; + + /* Currently this iteration is written with the assumption that + * "tag" has a single-character prefix. */ + assert (strlen (prefix) == 1); + + tags = _notmuch_tags_create (ctx); + if (unlikely (tags == NULL)) + return NULL; + + i.skip_to (prefix); + + while (i != end) { + tag = *i; + + if (tag.empty () || tag[0] != *prefix) + break; + + _notmuch_tags_add_tag (tags, tag.c_str () + 1); + + i++; + } + + _notmuch_tags_prepare_iterator (tags); + + return tags; +} + +notmuch_tags_t * +notmuch_database_get_all_tags (notmuch_database_t *db) +{ + Xapian::TermIterator i, end; + i = db->xapian_db->allterms_begin(); + end = db->xapian_db->allterms_end(); + return _notmuch_convert_tags(db, i, end); +}