query->terms.insert (*t);
}
-static notmuch_status_t
-_notmuch_query_ensure_parsed_xapian (notmuch_query_t *query)
+notmuch_status_t
+_notmuch_query_string_to_xapian_query (notmuch_database_t *notmuch,
+ std::string query_string,
+ Xapian::Query &output,
+ std::string &msg)
{
try {
- if (strcmp (query->query_string, "") == 0 ||
- strcmp (query->query_string, "*") == 0) {
- query->xapian_query = Xapian::Query::MatchAll;
+ if (query_string == "" || query_string == "*") {
+ output = Xapian::Query::MatchAll;
} else {
- query->xapian_query =
- query->notmuch->query_parser->
- parse_query (query->query_string, NOTMUCH_QUERY_PARSER_FLAGS);
-
- _notmuch_query_cache_terms (query);
+ output =
+ notmuch->query_parser->
+ parse_query (query_string, NOTMUCH_QUERY_PARSER_FLAGS);
}
- query->parsed = true;
-
} catch (const Xapian::Error &error) {
- if (! query->notmuch->exception_reported) {
- _notmuch_database_log (query->notmuch,
+ if (! notmuch->exception_reported) {
+ _notmuch_database_log (notmuch,
"A Xapian exception occurred parsing query: %s\n",
error.get_msg ().c_str ());
- _notmuch_database_log_append (query->notmuch,
+ _notmuch_database_log_append (notmuch,
"Query string was: %s\n",
- query->query_string);
- query->notmuch->exception_reported = true;
+ query_string.c_str ());
+ notmuch->exception_reported = true;
}
+ msg = error.get_msg ();
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
return NOTMUCH_STATUS_SUCCESS;
}
+static notmuch_status_t
+_notmuch_query_ensure_parsed_xapian (notmuch_query_t *query)
+{
+ notmuch_status_t status;
+ std::string msg; /* ignored */
+
+ status = _notmuch_query_string_to_xapian_query (query->notmuch, query->query_string,
+ query->xapian_query, msg);
+ if (status)
+ return status;
+
+ query->parsed = true;
+
+ _notmuch_query_cache_terms (query);
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+#if HAVE_SFSEXP
static notmuch_status_t
_notmuch_query_ensure_parsed_sexpr (notmuch_query_t *query)
{
_notmuch_query_cache_terms (query);
return NOTMUCH_STATUS_SUCCESS;
}
+#endif
static notmuch_status_t
_notmuch_query_ensure_parsed (notmuch_query_t *query)
{
return query->notmuch;
}
+
+notmuch_status_t
+_notmuch_query_expand (notmuch_database_t *notmuch, const char *field, Xapian::Query subquery,
+ Xapian::Query &output, std::string &msg)
+{
+ std::set<std::string> terms;
+ const std::string term_prefix = _find_prefix (field);
+
+ if (_debug_query ()) {
+ fprintf (stderr, "Expanding subquery:\n%s\n",
+ subquery.get_description ().c_str ());
+ }
+
+ try {
+ Xapian::Enquire enquire (*notmuch->xapian_db);
+ Xapian::MSet mset;
+
+ enquire.set_weighting_scheme (Xapian::BoolWeight ());
+ enquire.set_query (subquery);
+
+ mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
+
+ for (Xapian::MSetIterator iterator = mset.begin (); iterator != mset.end (); iterator++) {
+ Xapian::docid doc_id = *iterator;
+ Xapian::Document doc = notmuch->xapian_db->get_document (doc_id);
+ Xapian::TermIterator i = doc.termlist_begin ();
+
+ for (i.skip_to (term_prefix);
+ i != doc.termlist_end () && ((*i).rfind (term_prefix, 0) == 0); i++) {
+ terms.insert (*i);
+ }
+ }
+ output = Xapian::Query (Xapian::Query::OP_OR, terms.begin (), terms.end ());
+ if (_debug_query ()) {
+ fprintf (stderr, "Expanded query:\n%s\n",
+ subquery.get_description ().c_str ());
+ }
+
+ } catch (const Xapian::Error &error) {
+ _notmuch_database_log (notmuch,
+ "A Xapian exception occurred expanding query: %s\n",
+ error.get_msg ().c_str ());
+ msg = error.get_msg ();
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
+
+ return NOTMUCH_STATUS_SUCCESS;
+}