[PATCH 11/25] lib: factor out date to query conversion

Subject: [PATCH 11/25] lib: factor out date to query conversion

Date: Sat, 17 Jul 2021 23:40:07 -0300

To: notmuch@notmuchmail.org

Cc: David Bremner

From: David Bremner


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

Thread: