This will be mandatory as of Xapian 1.5. The API is also more consistent with the FieldProcessor API, which helps code re-use a bit.
Note that this switches to using the built-in Xapian support for prefixes on ranges (i.e. deleted code at beginning of ParseTimeRangeProcessor::operator(), added prefix to constructor). Another side effect of the migration is that we are generating smaller queries, using one OP_VALUE_RANGE instead of an AND of two OP_VALUE_* queries. --- lib/database-private.h | 6 ++-- lib/database.cc | 23 +++++---------- lib/parse-time-vrp.cc | 64 ++++++++++++++++++++---------------------- lib/parse-time-vrp.h | 17 +++++------ 4 files changed, 50 insertions(+), 60 deletions(-) diff --git a/lib/database-private.h b/lib/database-private.h index a499b259..c3389a7a 100644 --- a/lib/database-private.h +++ b/lib/database-private.h @@ -212,9 +212,9 @@ struct _notmuch_database { unsigned long view; Xapian::QueryParser *query_parser; Xapian::TermGenerator *term_gen; - Xapian::ValueRangeProcessor *value_range_processor; - Xapian::ValueRangeProcessor *date_range_processor; - Xapian::ValueRangeProcessor *last_mod_range_processor; + Xapian::RangeProcessor *value_range_processor; + Xapian::RangeProcessor *date_range_processor; + Xapian::RangeProcessor *last_mod_range_processor; }; /* Prior to database version 3, features were implied by the database diff --git a/lib/database.cc b/lib/database.cc index bad6df5f..f207890f 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -315,7 +315,6 @@ _setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch) notmuch->query_parser->add_boolean_prefix (prefix->name, prefix->prefix); } -#if HAVE_XAPIAN_FIELD_PROCESSOR static void _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) { @@ -323,7 +322,7 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) Xapian::FieldProcessor *fp; if (STRNCMP_LITERAL (prefix->name, "date") == 0) - fp = (new DateFieldProcessor())->release (); + fp = (new DateFieldProcessor(NOTMUCH_VALUE_TIMESTAMP))->release (); else if (STRNCMP_LITERAL(prefix->name, "query") == 0) fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release (); else if (STRNCMP_LITERAL(prefix->name, "thread") == 0) @@ -338,13 +337,6 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) _setup_query_field_default (prefix, notmuch); } } -#else -static inline void -_setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) -{ - _setup_query_field_default (prefix, notmuch); -} -#endif const char * _find_prefix (const char *name) @@ -954,17 +946,16 @@ notmuch_database_open_verbose (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->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); - notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:"); - + notmuch->value_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); + notmuch->date_range_processor = new ParseTimeRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:"); + notmuch->last_mod_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:"); 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); - notmuch->query_parser->add_valuerangeprocessor (notmuch->date_range_processor); - notmuch->query_parser->add_valuerangeprocessor (notmuch->last_mod_range_processor); + notmuch->query_parser->add_rangeprocessor (notmuch->value_range_processor); + notmuch->query_parser->add_rangeprocessor (notmuch->date_range_processor); + notmuch->query_parser->add_rangeprocessor (notmuch->last_mod_range_processor); for (i = 0; i < ARRAY_SIZE (prefix_table); i++) { const prefix_t *prefix = &prefix_table[i]; diff --git a/lib/parse-time-vrp.cc b/lib/parse-time-vrp.cc index dd691494..a64e9461 100644 --- a/lib/parse-time-vrp.cc +++ b/lib/parse-time-vrp.cc @@ -24,48 +24,49 @@ #include "parse-time-vrp.h" #include "parse-time-string.h" -#define PREFIX "date:" +static Xapian::Query _make_query (Xapian::valueno slot, time_t from, time_t to) { + if (to < 0) { + return Xapian::Query (Xapian::Query::OP_VALUE_GE, slot, + Xapian::sortable_serialise ((double) from)); + } else if (from < 0) { + return Xapian::Query (Xapian::Query::OP_VALUE_LE, slot, + Xapian::sortable_serialise ((double) to)); + } else { + return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise ((double) from), + Xapian::sortable_serialise ((double) to)); + } +} -/* See *ValueRangeProcessor in xapian-core/api/valuerangeproc.cc */ -Xapian::valueno -ParseTimeValueRangeProcessor::operator() (std::string &begin, std::string &end) +Xapian::Query +ParseTimeRangeProcessor::operator() (const std::string &begin, const std::string &end) { - time_t t, now; - std::string b; - - /* Require date: prefix in start of the range... */ - if (STRNCMP_LITERAL (begin.c_str (), PREFIX)) - return Xapian::BAD_VALUENO; - - /* ...and remove it. */ - begin.erase (0, sizeof (PREFIX) - 1); - b = begin; + time_t from = -1, to = -1, now = -1; + std::string str; /* Use the same 'now' for begin and end. */ if (time (&now) == (time_t) -1) - return Xapian::BAD_VALUENO; + throw Xapian::QueryParserError ("unable to get current time"); - if (!begin.empty ()) { - if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN)) - return Xapian::BAD_VALUENO; + if (!begin.empty ()) + if (parse_time_string (begin.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + begin + "'"); - begin.assign (Xapian::sortable_serialise ((double) t)); - } if (!end.empty ()) { - if (end == "!" && ! b.empty ()) - end = b; - - if (parse_time_string (end.c_str (), &t, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) - return Xapian::BAD_VALUENO; - - end.assign (Xapian::sortable_serialise ((double) t)); + if (end == "!" && ! begin.empty ()) + str = begin; + else + str = end; + + if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) + throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); } - return valno; + return _make_query (slot, from, to); } -#if HAVE_XAPIAN_FIELD_PROCESSOR /* XXX TODO: is throwing an exception the right thing to do here? */ Xapian::Query DateFieldProcessor::operator()(const std::string & str) { time_t from, to, now; @@ -80,8 +81,5 @@ Xapian::Query DateFieldProcessor::operator()(const std::string & str) { if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); - return Xapian::Query(Xapian::Query::OP_AND, - Xapian::Query(Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)), - Xapian::Query(Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to))); + return _make_query (slot, from, to); } -#endif diff --git a/lib/parse-time-vrp.h b/lib/parse-time-vrp.h index c024dba2..f495e716 100644 --- a/lib/parse-time-vrp.h +++ b/lib/parse-time-vrp.h @@ -26,20 +26,21 @@ #include <xapian.h> /* see *ValueRangeProcessor in xapian-core/include/xapian/queryparser.h */ -class ParseTimeValueRangeProcessor : public Xapian::ValueRangeProcessor { -protected: - Xapian::valueno valno; +class ParseTimeRangeProcessor : public Xapian::RangeProcessor { public: - ParseTimeValueRangeProcessor (Xapian::valueno slot_) - : valno(slot_) { } + ParseTimeRangeProcessor (Xapian::valueno slot_, const std::string prefix_) + : Xapian::RangeProcessor(slot_, prefix_, 0) { } - Xapian::valueno operator() (std::string &begin, std::string &end); + Xapian::Query operator() (const std::string &begin, const std::string &end); }; -#if HAVE_XAPIAN_FIELD_PROCESSOR class DateFieldProcessor : public Xapian::FieldProcessor { +private: + Xapian::valueno slot; +public: + DateFieldProcessor(Xapian::valueno slot_) : slot(slot_) { }; Xapian::Query operator()(const std::string & str); }; -#endif + #endif /* NOTMUCH_PARSE_TIME_VRP_H */ -- 2.20.1 _______________________________________________ notmuch mailing list notmuch@notmuchmail.org https://notmuchmail.org/mailman/listinfo/notmuch