sx->list->next, output);
}
+static notmuch_status_t
+maybe_saved_squery (notmuch_database_t *notmuch, const _sexp_prefix_t *parent, const sexp_t *sx,
+ Xapian::Query &output)
+{
+ char *key;
+ char *expansion = NULL;
+ notmuch_status_t status;
+ sexp_t *saved_sexp;
+ void *local = talloc_new (notmuch);
+ char *buf;
+
+ key = talloc_asprintf (local, "squery.%s", sx->list->val);
+ if (! key) {
+ status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+ goto DONE;
+ }
+
+ status = notmuch_database_get_config (notmuch, key, &expansion);
+ if (status)
+ goto DONE;
+ if (EMPTY_STRING (expansion)) {
+ status = NOTMUCH_STATUS_IGNORED;
+ goto DONE;
+ }
+
+ buf = talloc_strdup (local, expansion);
+ /* XXX TODO: free this memory */
+ saved_sexp = parse_sexp (buf, strlen (expansion));
+ if (! saved_sexp) {
+ _notmuch_database_log (notmuch, "invalid saved s-expression query: '%s'\n", expansion);
+ status = NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+ goto DONE;
+ }
+
+ status = _sexp_to_xapian_query (notmuch, parent, saved_sexp, output);
+
+ DONE:
+ if (local)
+ talloc_free (local);
+
+ return status;
+}
+
/* Here we expect the s-expression to be a proper list, with first
* element defining and operation, or as a special case the empty
* list */
_sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent, const sexp_t *sx,
Xapian::Query &output)
{
+ notmuch_status_t status;
+
if (sx->ty == SEXP_VALUE) {
std::string term_prefix = parent ? _notmuch_database_prefix (notmuch, parent->name) : "";
Xapian::Query accumulator;
for (_sexp_prefix_t *prefix = prefixes; prefix->name; prefix++) {
if (prefix->flags & SEXP_FLAG_FIELD) {
- notmuch_status_t status;
Xapian::Query subquery;
term_prefix = _notmuch_database_prefix (notmuch, prefix->name);
status = _sexp_parse_one_term (notmuch, term_prefix, sx, subquery);
return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
}
+ status = maybe_saved_squery (notmuch, parent, sx, output);
+ if (status != NOTMUCH_STATUS_IGNORED)
+ return status;
+
/* Check for user defined field */
if (_notmuch_string_map_get (notmuch->user_prefix, sx->list->val)) {
return _sexp_parse_header (notmuch, parent, sx, output);
output=$(notmuch config get squery.Test)
test_expect_equal "$output" '(subject override subject)'
+test_begin_subtest "unknown saved query"
+notmuch search --query=sexp '(Unknown foo bar)' >OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+unknown prefix 'Unknown'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "syntax error in saved query"
+notmuch config set squery.Bad '(Bad'
+notmuch search --query=sexp '(Bad foo bar)' >OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+invalid saved s-expression query: '(Bad'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "Saved Search by 'tag' and 'subject'"
+notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
+notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
+notmuch search --query=sexp '(TagSubject)' | notmuch_search_sanitize > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "Saved Search: illegal nesting"
+notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
+notmuch search --query=sexp '(subject (TagSubject))' >OUTPUT 2>&1
+cat <<EOF > EXPECTED
+notmuch search: Syntax error in query
+nested field: 'tag' inside 'subject'
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
test_done