aboutsummaryrefslogtreecommitdiff
path: root/lib/regexp-fields.cc
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2017-08-27 15:54:50 -0300
committerDavid Bremner <david@tethera.net>2017-08-27 15:54:50 -0300
commita565f71e1c160431ff99f088bc8fc08d367603a2 (patch)
tree2f7c33d7296e15b2c33f6ede436d412c812c3f15 /lib/regexp-fields.cc
parent00f87faf4bc19e90e19b8b27c13845efb6a68152 (diff)
parent6354745dcd6505c5f12c185a29c25a8d1c240595 (diff)
Merge tag 'debian/0.25-6' into debian/stretch-backports
Diffstat (limited to 'lib/regexp-fields.cc')
-rw-r--r--lib/regexp-fields.cc68
1 files changed, 51 insertions, 17 deletions
diff --git a/lib/regexp-fields.cc b/lib/regexp-fields.cc
index 1651677c..084bc8c0 100644
--- a/lib/regexp-fields.cc
+++ b/lib/regexp-fields.cc
@@ -135,42 +135,76 @@ static inline Xapian::valueno _find_slot (std::string prefix)
return NOTMUCH_VALUE_FROM;
else if (prefix == "subject")
return NOTMUCH_VALUE_SUBJECT;
+ else if (prefix == "mid")
+ return NOTMUCH_VALUE_MESSAGE_ID;
else
- throw Xapian::QueryParserError ("unsupported regexp field '" + prefix + "'");
+ return Xapian::BAD_VALUENO;
}
-RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix, Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
- : slot (_find_slot (prefix)), term_prefix (_find_prefix (prefix.c_str ())),
- parser (parser_), notmuch (notmuch_)
+RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix,
+ notmuch_field_flag_t options_,
+ Xapian::QueryParser &parser_,
+ notmuch_database_t *notmuch_)
+ : slot (_find_slot (prefix)),
+ term_prefix (_find_prefix (prefix.c_str ())),
+ options (options_),
+ parser (parser_),
+ notmuch (notmuch_)
{
};
Xapian::Query
RegexpFieldProcessor::operator() (const std::string & str)
{
- if (str.size () == 0)
- return Xapian::Query(Xapian::Query::OP_AND_NOT,
+ if (str.empty ()) {
+ if (options & NOTMUCH_FIELD_PROBABILISTIC) {
+ return Xapian::Query(Xapian::Query::OP_AND_NOT,
Xapian::Query::MatchAll,
Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
+ } else {
+ return Xapian::Query (term_prefix);
+ }
+ }
if (str.at (0) == '/') {
- if (str.at (str.size () - 1) == '/'){
- RegexpPostingSource *postings = new RegexpPostingSource (slot, str.substr(1,str.size () - 2));
- return Xapian::Query (postings->release ());
+ if (str.length() > 1 && str.at (str.size () - 1) == '/'){
+ std::string regexp_str = str.substr(1,str.size () - 2);
+ if (slot != Xapian::BAD_VALUENO) {
+ RegexpPostingSource *postings = new RegexpPostingSource (slot, regexp_str);
+ return Xapian::Query (postings->release ());
+ } else {
+ std::vector<std::string> terms;
+ regex_t regexp;
+
+ compile_regex(regexp, regexp_str.c_str ());
+ for (Xapian::TermIterator it = notmuch->xapian_db->allterms_begin (term_prefix);
+ it != notmuch->xapian_db->allterms_end (); ++it) {
+ if (regexec (&regexp, (*it).c_str () + term_prefix.size(),
+ 0, NULL, 0) == 0)
+ terms.push_back(*it);
+ }
+ return Xapian::Query (Xapian::Query::OP_OR, terms.begin(), terms.end());
+ }
} else {
throw Xapian::QueryParserError ("unmatched regex delimiter in '" + str + "'");
}
} else {
- /* TODO replace this with a nicer API level triggering of
- * phrase parsing, when possible */
- std::string query_str;
+ if (options & NOTMUCH_FIELD_PROBABILISTIC) {
+ /* TODO replace this with a nicer API level triggering of
+ * phrase parsing, when possible */
+ std::string query_str;
- if (str.find (' ') != std::string::npos)
- query_str = '"' + str + '"';
- else
- query_str = str;
+ if (str.find (' ') != std::string::npos)
+ query_str = '"' + str + '"';
+ else
+ query_str = str;
- return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);
+ return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);
+ } else {
+ /* Boolean prefix */
+ std::string term = term_prefix + str;
+ return Xapian::Query (term);
+ }
}
}
#endif