mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-28 13:44:12 +01:00
CLI/tag: enable sexp queries
We have to rewrite _optimize_tag_query here because it is generating a query string in the infix Xapian syntax. Luckily this is easy to do with the sexp query syntax.
This commit is contained in:
parent
2944d59133
commit
4595a814c2
2 changed files with 79 additions and 7 deletions
|
@ -39,7 +39,7 @@ handle_sigint (unused (int sig))
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
_optimize_tag_query (void *ctx, const char *orig_query_string,
|
_optimize_tag_query_infix (void *ctx, const char *orig_query_string,
|
||||||
const tag_op_list_t *list)
|
const tag_op_list_t *list)
|
||||||
{
|
{
|
||||||
/* This is subtler than it looks. Xapian ignores the '-' operator
|
/* This is subtler than it looks. Xapian ignores the '-' operator
|
||||||
|
@ -88,6 +88,33 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,
|
||||||
return query_string;
|
return query_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_optimize_tag_query (void *ctx, const char *orig_query_string,
|
||||||
|
notmuch_query_syntax_t stx,
|
||||||
|
const tag_op_list_t *list)
|
||||||
|
{
|
||||||
|
char *query_string;
|
||||||
|
|
||||||
|
if (stx == NOTMUCH_QUERY_SYNTAX_XAPIAN)
|
||||||
|
return _optimize_tag_query_infix (ctx, orig_query_string, list);
|
||||||
|
|
||||||
|
/* Don't optimize if there are no tag changes. */
|
||||||
|
if (tag_op_list_size (list) == 0)
|
||||||
|
return talloc_strdup (ctx, orig_query_string);
|
||||||
|
|
||||||
|
query_string = talloc_asprintf (ctx, "(and %s", orig_query_string);
|
||||||
|
for (size_t i = 0; i < tag_op_list_size (list) && query_string; i++) {
|
||||||
|
query_string = talloc_asprintf_append_buffer (
|
||||||
|
query_string, tag_op_list_isremove (list, i) ? " (tag \"%s\")" : " (not (tag \"%s\"))",
|
||||||
|
tag_op_list_tag (list, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query_string)
|
||||||
|
query_string = talloc_strdup_append_buffer (query_string, ")");
|
||||||
|
|
||||||
|
return query_string;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tag messages matching 'query_string' according to 'tag_ops'
|
/* Tag messages matching 'query_string' according to 'tag_ops'
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
@ -104,7 +131,9 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
|
||||||
if (! (flags & TAG_FLAG_REMOVE_ALL)) {
|
if (! (flags & TAG_FLAG_REMOVE_ALL)) {
|
||||||
/* Optimize the query so it excludes messages that already
|
/* Optimize the query so it excludes messages that already
|
||||||
* have the specified set of tags. */
|
* have the specified set of tags. */
|
||||||
query_string = _optimize_tag_query (ctx, query_string, tag_ops);
|
query_string = _optimize_tag_query (ctx, query_string,
|
||||||
|
shared_option_query_syntax (),
|
||||||
|
tag_ops);
|
||||||
if (query_string == NULL) {
|
if (query_string == NULL) {
|
||||||
fprintf (stderr, "Out of memory.\n");
|
fprintf (stderr, "Out of memory.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -112,11 +141,11 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
|
||||||
flags |= TAG_FLAG_PRE_OPTIMIZED;
|
flags |= TAG_FLAG_PRE_OPTIMIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = notmuch_query_create (notmuch, query_string);
|
status = notmuch_query_create_with_syntax (notmuch, query_string,
|
||||||
if (query == NULL) {
|
shared_option_query_syntax (),
|
||||||
fprintf (stderr, "Out of memory.\n");
|
&query);
|
||||||
|
if (print_status_database ("notmuch tag", notmuch, status))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
/* tagging is not interested in any special sort order */
|
/* tagging is not interested in any special sort order */
|
||||||
notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED);
|
notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED);
|
||||||
|
|
|
@ -2,6 +2,21 @@
|
||||||
test_description='"notmuch tag"'
|
test_description='"notmuch tag"'
|
||||||
. $(dirname "$0")/test-lib.sh || exit 1
|
. $(dirname "$0")/test-lib.sh || exit 1
|
||||||
|
|
||||||
|
test_query_syntax () {
|
||||||
|
# use a tag with a space to stress the query string munging code.
|
||||||
|
local new_tag="${RANDOM} ${RANDOM}"
|
||||||
|
test_begin_subtest "sexpr query: $1"
|
||||||
|
backup_database
|
||||||
|
notmuch tag --query=sexp "+${new_tag}" -- "$1"
|
||||||
|
notmuch dump > OUTPUT
|
||||||
|
restore_database
|
||||||
|
backup_database
|
||||||
|
notmuch tag "+${new_tag}" -- "$2"
|
||||||
|
notmuch dump > EXPECTED
|
||||||
|
restore_database
|
||||||
|
test_expect_equal_file_nonempty EXPECTED OUTPUT
|
||||||
|
}
|
||||||
|
|
||||||
add_message '[subject]=One'
|
add_message '[subject]=One'
|
||||||
add_message '[subject]=Two'
|
add_message '[subject]=Two'
|
||||||
|
|
||||||
|
@ -310,4 +325,32 @@ output=$(notmuch tag +something '*' 2>&1 | sed 's/: .*$//' )
|
||||||
chmod u+w ${MAIL_DIR}/.notmuch/xapian/*.*
|
chmod u+w ${MAIL_DIR}/.notmuch/xapian/*.*
|
||||||
test_expect_equal "$output" "A Xapian exception occurred opening database"
|
test_expect_equal "$output" "A Xapian exception occurred opening database"
|
||||||
|
|
||||||
|
add_email_corpus
|
||||||
|
|
||||||
|
if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
|
||||||
|
|
||||||
|
test_query_syntax '(and "wonderful" "wizard")' 'wonderful and wizard'
|
||||||
|
test_query_syntax '(or "php" "wizard")' 'php or wizard'
|
||||||
|
test_query_syntax 'wizard' 'wizard'
|
||||||
|
test_query_syntax 'Wizard' 'Wizard'
|
||||||
|
test_query_syntax '(attachment notmuch-help.patch)' 'attachment:notmuch-help.patch'
|
||||||
|
test_query_syntax '(mimetype text/html)' 'mimetype:text/html'
|
||||||
|
|
||||||
|
test_begin_subtest "--batch --query=sexp"
|
||||||
|
notmuch dump --format=batch-tag > backup.tags
|
||||||
|
notmuch tag --batch --query=sexp <<EOF
|
||||||
|
+all -- (or One Two)
|
||||||
|
+none -- (and One Two)
|
||||||
|
EOF
|
||||||
|
notmuch dump > OUTPUT
|
||||||
|
cat <<EOF > EXPECTED
|
||||||
|
#notmuch-dump batch-tag:3 config,properties,tags
|
||||||
|
+all +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite
|
||||||
|
+all +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite
|
||||||
|
EOF
|
||||||
|
notmuch restore --format=batch-tag < backup.tags
|
||||||
|
test_expect_equal_file EXPECTED OUTPUT
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue