This is a bit messy, but throwing and catching Xapian::QueryParserError exceptions outside of the Xapian query parser seems worse. --- lib/parse-time-vrp.cc | 97 +++++++++++++++++++++++++++++++------------ lib/parse-time-vrp.h | 8 ++++ 2 files changed, 79 insertions(+), 26 deletions(-) diff --git a/lib/parse-time-vrp.cc b/lib/parse-time-vrp.cc index 22bf2ab5..75c67797 100644 --- a/lib/parse-time-vrp.cc +++ b/lib/parse-time-vrp.cc @@ -24,21 +24,26 @@ #include "parse-time-vrp.h" #include "parse-time-string.h" -Xapian::Query -ParseTimeRangeProcessor::operator() (const std::string &begin, const std::string &end) +notmuch_status_t +_notmuch_time_range_to_query (Xapian::valueno slot, const std::string &begin, const std::string &end, + std::string &msg, Xapian::Query &output) { double from = DBL_MIN, to = DBL_MAX; time_t parsed_time, now; std::string str; /* Use the same 'now' for begin and end. */ - if (time (&now) == (time_t) -1) - throw Xapian::QueryParserError ("unable to get current time"); + if (time (&now) == (time_t) -1) { + msg = "unable to get current time"; + /* XXX Give a better status value */ + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } if (! begin.empty ()) { - if (parse_time_string (begin.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) - throw Xapian::QueryParserError ("Didn't understand date specification '" + begin + "'"); - else + if (parse_time_string (begin.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) { + msg = "Didn't understand date specification '" + begin + "'"; + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } else from = (double) parsed_time; } @@ -48,39 +53,79 @@ ParseTimeRangeProcessor::operator() (const std::string &begin, const std::string else str = end; - if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) - throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); - else + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) { + msg = "Didn't understand date specification '" + str + "'"; + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } else to = (double) parsed_time; } - return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, - Xapian::sortable_serialise (from), - Xapian::sortable_serialise (to)); + output = Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise (from), + Xapian::sortable_serialise (to)); + + return NOTMUCH_STATUS_SUCCESS; } -/* XXX TODO: is throwing an exception the right thing to do here? */ Xapian::Query -DateFieldProcessor::operator() (const std::string & str) +ParseTimeRangeProcessor::operator() (const std::string &begin, const std::string &end) +{ + Xapian::Query output; + notmuch_status_t status; + std::string msg; + + status = _notmuch_time_range_to_query (slot, begin, end, msg, output); + if (status) + throw Xapian::QueryParserError (msg); + + return output; +} + +notmuch_status_t +_notmuch_time_string_to_query (Xapian::valueno slot, const std::string &str, + std::string &msg, Xapian::Query &output) { double from = DBL_MIN, to = DBL_MAX; time_t parsed_time, now; /* Use the same 'now' for begin and end. */ - if (time (&now) == (time_t) -1) - throw Xapian::QueryParserError ("Unable to get current time"); + if (time (&now) == (time_t) -1) { + msg = "Unable to get current time"; + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } - if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) - throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); - else + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_DOWN)) { + msg = "Didn't understand date specification '" + str + "'"; + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } else from = (double) parsed_time; - if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) - throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'"); - else + if (parse_time_string (str.c_str (), &parsed_time, &now, PARSE_TIME_ROUND_UP_INCLUSIVE)) { + msg = "Didn't understand date specification '" + str + "'"; + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } else to = (double) parsed_time; - return Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, - Xapian::sortable_serialise (from), - Xapian::sortable_serialise (to)); + output = Xapian::Query (Xapian::Query::OP_VALUE_RANGE, slot, + Xapian::sortable_serialise (from), + Xapian::sortable_serialise (to)); + + return NOTMUCH_STATUS_SUCCESS; + +} + +/* XXX TODO: is throwing an exception the right thing to do here? */ +Xapian::Query +DateFieldProcessor::operator() (const std::string & str) +{ + Xapian::Query output; + notmuch_status_t status; + std::string msg; + + status = _notmuch_time_string_to_query (slot, str, msg, output); + if (status) + throw Xapian::QueryParserError (msg); + + return output; + } diff --git a/lib/parse-time-vrp.h b/lib/parse-time-vrp.h index f495e716..76d16eb2 100644 --- a/lib/parse-time-vrp.h +++ b/lib/parse-time-vrp.h @@ -25,6 +25,14 @@ #include <xapian.h> +/* for use outside the Xapian query parser */ +notmuch_status_t +_notmuch_time_range_to_query (Xapian::valueno slot, const std::string &begin, const std::string &end, + std::string &msg, Xapian::Query &output); +notmuch_status_t +_notmuch_time_string_to_query (Xapian::valueno slot, const std::string &str, + std::string &msg, Xapian::Query &output); + /* see *ValueRangeProcessor in xapian-core/include/xapian/queryparser.h */ class ParseTimeRangeProcessor : public Xapian::RangeProcessor { -- 2.30.2 _______________________________________________ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-leave@notmuchmail.org