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