unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: David Bremner <david@tethera.net>
To: notmuch@notmuchmail.org
Cc: David Bremner <david@tethera.net>
Subject: [PATCH 34/36] CLI/{count, dump, reindex, reply, show}: enable sexp queries
Date: Tue, 24 Aug 2021 08:17:43 -0700	[thread overview]
Message-ID: <20210824151745.2941868-35-david@tethera.net> (raw)
In-Reply-To: <20210824151745.2941868-1-david@tethera.net>

The change in each case is to call notmuch_query_create_with_syntax,
relying on the already inherited shared options.  As a bonus we get
improved error handling from the new query creation API.

The remaining subcommand is 'tag', which is a bit trickier.
---
 notmuch-count.c           | 10 ++++++----
 notmuch-dump.c            |  9 +++++----
 notmuch-reindex.c         |  8 ++++----
 notmuch-reply.c           |  9 +++++----
 notmuch-show.c            |  8 ++++----
 test/T060-count.sh        | 24 ++++++++++++++++++++++++
 test/T220-reply.sh        | 19 +++++++++++++++----
 test/T240-dump-restore.sh | 13 +++++++++++++
 test/T520-show.sh         | 18 ++++++++++++++++++
 test/T700-reindex.sh      | 29 +++++++++++++++++++++++++++++
 10 files changed, 123 insertions(+), 24 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index e8c545e3..0d9046a8 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -74,10 +74,12 @@ print_count (notmuch_database_t *notmuch, const char *query_str,
     int ret = 0;
     notmuch_status_t status;
 
-    query = notmuch_query_create (notmuch, query_str);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory\n");
-	return -1;
+    status = notmuch_query_create_with_syntax (notmuch, query_str,
+					       shared_option_query_syntax (),
+					       &query);
+    if (print_status_database ("notmuch count", notmuch, status)) {
+	ret = -1;
+	goto DONE;
     }
 
     for (notmuch_config_values_start (exclude_tags);
diff --git a/notmuch-dump.c b/notmuch-dump.c
index 5c8213be..cb82d61f 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -232,11 +232,12 @@ database_dump_file (notmuch_database_t *notmuch, gzFile output,
     if (! query_str)
 	query_str = "";
 
-    query = notmuch_query_create (notmuch, query_str);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory\n");
+    status = notmuch_query_create_with_syntax (notmuch, query_str,
+					       shared_option_query_syntax (),
+					       &query);
+    if (print_status_database ("notmuch dump", notmuch, status))
 	return EXIT_FAILURE;
-    }
+
     /* Don't ask xapian to sort by Message-ID. Xapian optimizes returning the
      * first results quickly at the expense of total time.
      */
diff --git a/notmuch-reindex.c b/notmuch-reindex.c
index b40edbb6..49eacd47 100644
--- a/notmuch-reindex.c
+++ b/notmuch-reindex.c
@@ -49,11 +49,11 @@ reindex_query (notmuch_database_t *notmuch, const char *query_string,
 
     notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
 
-    query = notmuch_query_create (notmuch, query_string);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory.\n");
+    status = notmuch_query_create_with_syntax (notmuch, query_string,
+					       shared_option_query_syntax (),
+					       &query);
+    if (print_status_database ("notmuch reindex", notmuch, status))
 	return 1;
-    }
 
     /* reindexing is not interested in any special sort order */
     notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED);
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 5d5f95a3..2fb26cbc 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -716,6 +716,7 @@ notmuch_reply_command (notmuch_database_t *notmuch, int argc, char *argv[])
     };
     int format = FORMAT_DEFAULT;
     int reply_all = true;
+    notmuch_status_t status;
 
     notmuch_opt_desc_t options[] = {
 	{ .opt_keyword = &format, .name = "format", .keywords =
@@ -758,11 +759,11 @@ notmuch_reply_command (notmuch_database_t *notmuch, int argc, char *argv[])
 	return EXIT_FAILURE;
     }
 
-    query = notmuch_query_create (notmuch, query_string);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory\n");
+    status = notmuch_query_create_with_syntax (notmuch, query_string,
+					       shared_option_query_syntax (),
+					       &query);
+    if (print_status_database ("notmuch reply", notmuch, status))
 	return EXIT_FAILURE;
-    }
 
     if (do_reply (notmuch, query, &params, format, reply_all) != 0)
 	return EXIT_FAILURE;
diff --git a/notmuch-show.c b/notmuch-show.c
index 667fbee8..2848c9c3 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1364,11 +1364,11 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
 	return EXIT_FAILURE;
     }
 
-    query = notmuch_query_create (notmuch, query_string);
-    if (query == NULL) {
-	fprintf (stderr, "Out of memory\n");
+    status = notmuch_query_create_with_syntax (notmuch, query_string,
+					       shared_option_query_syntax (),
+					       &query);
+    if (print_status_database ("notmuch show", notmuch, status))
 	return EXIT_FAILURE;
-    }
 
     notmuch_query_set_sort (query, sort);
 
diff --git a/test/T060-count.sh b/test/T060-count.sh
index a1ebf8ba..6ad80df9 100755
--- a/test/T060-count.sh
+++ b/test/T060-count.sh
@@ -154,4 +154,28 @@ print("4: {} messages".format(query.count_messages()))
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
+
+    test_begin_subtest "and of exact terms (query=sexp)"
+    output=$(notmuch count --query=sexp '(and "wonderful" "wizard")')
+    test_expect_equal "$output" 1
+
+    test_begin_subtest "or of exact terms (query=sexp)"
+    output=$(notmuch count --query=sexp '(or "php" "wizard")')
+    test_expect_equal "$output" 2
+
+    test_begin_subtest "starts-with, case-insensitive (query=sexp)"
+    output=$(notmuch count --query=sexp '(starts-with FreeB)')
+    test_expect_equal "$output" 5
+
+    test_begin_subtest "query that matches no messages (query=sexp)"
+    count=$(notmuch count --query=sexp '(and (from keithp) (to keithp))')
+    test_expect_equal 0 "$count"
+
+    test_begin_subtest "Compound subquery (query=sexp)"
+    output=$(notmuch count --query=sexp '(thread (of (from keithp) (subject Maildir)))')
+    test_expect_equal "$output" 7
+
+fi
+
 test_done
diff --git a/test/T220-reply.sh b/test/T220-reply.sh
index b6d8f42a..6d64cbd7 100755
--- a/test/T220-reply.sh
+++ b/test/T220-reply.sh
@@ -2,15 +2,14 @@
 test_description="\"notmuch reply\" in several variations"
 . $(dirname "$0")/test-lib.sh || exit 1
 
-test_begin_subtest "Basic reply"
 add_message '[from]="Sender <sender@example.com>"' \
 	     [to]=test_suite@notmuchmail.org \
 	     [subject]=notmuch-reply-test \
 	    '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \
 	    '[body]="basic reply test"'
 
-output=$(notmuch reply id:${gen_msg_id} 2>&1 && echo OK)
-test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+cat <<EOF > basic.expected
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
 Subject: Re: notmuch-reply-test
 To: Sender <sender@example.com>
 In-Reply-To: <${gen_msg_id}>
@@ -18,7 +17,19 @@ References: <${gen_msg_id}>
 
 On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > basic reply test
-OK"
+OK
+EOF
+
+test_begin_subtest "Basic reply"
+notmuch reply id:${gen_msg_id} >OUTPUT 2>&1 && echo OK >> OUTPUT
+test_expect_equal_file basic.expected OUTPUT
+
+if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
+
+    test_begin_subtest "Basic reply (query=sexp)"
+    notmuch reply --query=sexp "(id ${gen_msg_id})" >OUTPUT 2>&1 && echo OK >> OUTPUT
+    test_expect_equal_file basic.expected OUTPUT
+fi
 
 test_begin_subtest "Multiple recipients"
 add_message '[from]="Sender <sender@example.com>"' \
diff --git a/test/T240-dump-restore.sh b/test/T240-dump-restore.sh
index 105de130..a86f0fb7 100755
--- a/test/T240-dump-restore.sh
+++ b/test/T240-dump-restore.sh
@@ -117,6 +117,19 @@ test_begin_subtest "dump -- from:cworth"
 notmuch dump -- from:cworth > dump-dash-cworth.actual
 test_expect_equal_file dump-cworth.expected dump-dash-cworth.actual
 
+
+if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
+
+    test_begin_subtest "dump --query=sexp -- '(from cworth)'"
+    notmuch dump --query=sexp -- '(from cworth)' > dump-dash-cworth.actual2
+    test_expect_equal_file_nonempty dump-cworth.expected dump-dash-cworth.actual2
+
+    test_begin_subtest "dump --query=sexp --output=outfile '(from cworth)'"
+    notmuch dump --output=dump-outfile-cworth.actual2 --query=sexp '(from cworth)'
+    test_expect_equal_file dump-cworth.expected dump-outfile-cworth.actual2
+
+fi
+
 test_begin_subtest "dump --output=outfile from:cworth"
 notmuch dump --output=dump-outfile-cworth.actual from:cworth
 test_expect_equal_file dump-cworth.expected dump-outfile-cworth.actual
diff --git a/test/T520-show.sh b/test/T520-show.sh
index 6f42ca12..12bde6c7 100755
--- a/test/T520-show.sh
+++ b/test/T520-show.sh
@@ -3,6 +3,13 @@ test_description='"notmuch show"'
 
 . $(dirname "$0")/test-lib.sh || exit 1
 
+test_query_syntax () {
+    test_begin_subtest "sexpr query: $1"
+    sexp=$(notmuch show --format=json --query=sexp "$1")
+    infix=$(notmuch show --format=json "$2")
+    test_expect_equal_json "$sexp" "$infix"
+}
+
 add_email_corpus
 
 test_begin_subtest "exit code for show invalid query"
@@ -27,4 +34,15 @@ notmuch show --entire-thread=true --sort=newest-first $QUERY > EXPECTED
 notmuch show --entire-thread=true --sort=oldest-first $QUERY > OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
 
+
+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'
+
+fi
+
 test_done
diff --git a/test/T700-reindex.sh b/test/T700-reindex.sh
index bac43dc5..347f8483 100755
--- a/test/T700-reindex.sh
+++ b/test/T700-reindex.sh
@@ -4,6 +4,21 @@ test_description='reindexing messages'
 
 add_email_corpus
 
+
+if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
+
+    count=$(notmuch count --lastmod '*' | cut -f 3)
+    for query in '()' '(not)' '(and)' '(or ())' '(or (not))' '(or (and))' \
+		'(or (and) (or) (not (and)))'; do
+	test_begin_subtest "reindex all messages: $query"
+	notmuch reindex --query=sexp "$query"
+	output=$(notmuch count --lastmod '*' | cut -f 3)
+	count=$((count + 1))
+	test_expect_equal "$output" "$count"
+    done
+
+fi
+
 notmuch tag +usertag1 '*'
 
 notmuch search '*' 2>1 | notmuch_search_sanitize > initial-threads
@@ -41,6 +56,7 @@ notmuch dump > OUTPUT
 notmuch tag -attachment2 -encrypted2 -signed2 '*'
 test_expect_equal_file EXPECTED OUTPUT
 
+backup_database
 test_begin_subtest 'reindex moves a message between threads'
 notmuch search --output=threads id:87iqd9rn3l.fsf@vertex.dottedmag > EXPECTED
 # re-parent
@@ -48,7 +64,19 @@ sed -i 's/1258471718-6781-1-git-send-email-dottedmag@dottedmag.net/87iqd9rn3l.fs
 notmuch reindex id:1258471718-6781-2-git-send-email-dottedmag@dottedmag.net
 notmuch search --output=threads id:1258471718-6781-2-git-send-email-dottedmag@dottedmag.net > OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
+backup_database
+test_begin_subtest 'reindex detects removal of all files'
+notmuch search --output=messages not id:20091117232137.GA7669@griffis1.net> EXPECTED
+# remove both copies
+mv $MAIL_DIR/cur/51:2,* duplicate-message-2.eml
+notmuch reindex id:20091117232137.GA7669@griffis1.net
+notmuch search --output=messages '*' > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
 
+backup_database
 test_begin_subtest 'reindex detects removal of all files'
 notmuch search --output=messages not id:20091117232137.GA7669@griffis1.net> EXPECTED
 # remove both copies
@@ -56,6 +84,7 @@ mv $MAIL_DIR/cur/51:2,* duplicate-message-2.eml
 notmuch reindex id:20091117232137.GA7669@griffis1.net
 notmuch search --output=messages '*' > OUTPUT
 test_expect_equal_file EXPECTED OUTPUT
+restore_database
 
 test_begin_subtest "reindex preserves properties"
 cat <<EOF > prop-dump
-- 
2.32.0

  parent reply	other threads:[~2021-08-24 15:21 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-24 15:17 v5 sexp query parser David Bremner
2021-08-24 15:17 ` [PATCH 01/36] CLI: make variable n_requested_db_uuid file scope David Bremner
2021-08-24 15:17 ` [PATCH 02/36] configure: optional library sfsexp David Bremner
2021-08-24 15:17 ` [PATCH 03/36] lib: split notmuch_query_create David Bremner
2021-08-24 15:17 ` [PATCH 04/36] lib: define notmuch_query_create_with_syntax David Bremner
2021-08-24 15:17 ` [PATCH 05/36] CLI/search+address: support sexpr queries David Bremner
2021-08-24 15:17 ` [PATCH 06/36] lib: add new status code for query syntax errors David Bremner
2021-08-24 15:17 ` [PATCH 07/36] lib/parse-sexp: parse single terms and the empty list David Bremner
2021-08-24 15:17 ` [PATCH 08/36] lib: leave stemmer object accessible David Bremner
2021-08-24 15:17 ` [PATCH 09/36] lib/parse-sexp: stem unquoted atoms David Bremner
2021-08-24 15:17 ` [PATCH 10/36] lib/parse-sexp: support and, not, and or David Bremner
2021-08-24 15:17 ` [PATCH 11/36] lib/parse-sexp: support subject field David Bremner
2021-08-24 15:17 ` [PATCH 12/36] util/unicode: allow calling from C++ David Bremner
2021-08-24 15:17 ` [PATCH 13/36] lib/parse-sexp: support phrase queries David Bremner
2021-08-24 15:17 ` [PATCH 14/36] lib/parse-sexp: add term prefix backed fields David Bremner
2021-08-24 15:17 ` [PATCH 15/36] lib/parse-sexp: 'starts-with' wildcard searches David Bremner
2021-08-24 15:17 ` [PATCH 16/36] lib/parse-sexp: add '*' as syntactic sugar for '(starts-with "")' David Bremner
2021-08-24 15:17 ` [PATCH 17/36] lib/parse-sexp: handle unprefixed terms David Bremner
2021-08-24 15:17 ` [PATCH 18/36] lib/query: generalize exclude handling to s-expression queries David Bremner
2021-08-24 15:17 ` [PATCH 19/36] lib: factor out query construction from regexp David Bremner
2021-08-24 15:17 ` [PATCH 20/36] lib/parse-sexp: support regular expressions David Bremner
2021-08-24 15:17 ` [PATCH 21/36] lib: generate actual Xapian query for "*" and "" David Bremner
2021-08-24 15:17 ` [PATCH 22/36] lib/query: factor out _notmuch_query_string_to_xapian_query David Bremner
2021-08-24 15:17 ` [PATCH 23/36] lib/thread-fp: factor out query expansion, rewrite in Xapian David Bremner
2021-08-24 15:17 ` [PATCH 24/36] lib/parse-sexp: expand queries David Bremner
2021-08-24 15:17 ` [PATCH 25/36] lib/parse-sexp: support infix subqueries David Bremner
2021-08-24 15:17 ` [PATCH 26/36] lib/parse-sexp: parse user headers David Bremner
2021-08-24 15:17 ` [PATCH 27/36] lib: factor out expansion of saved queries David Bremner
2021-08-24 15:17 ` [PATCH 28/36] lib/parse-sexp: handle " David Bremner
2021-08-24 15:17 ` [PATCH 29/36] CLI/config support saving s-expression queries David Bremner
2021-08-24 15:17 ` [PATCH 30/36] lib/parse-sexp: support saved " David Bremner
2021-08-24 15:17 ` [PATCH 31/36] lib/parse-sexp: thread environment argument through parser David Bremner
2021-08-24 15:17 ` [PATCH 32/36] lib/parse-sexp: apply macros David Bremner
2021-08-24 15:17 ` [PATCH 33/36] CLI: move query syntax to shared option David Bremner
2021-08-24 15:17 ` David Bremner [this message]
2021-08-24 15:17 ` [PATCH 35/36] CLI/tag: enable sexp queries David Bremner
2021-08-24 15:17 ` [PATCH 36/36] doc/sexp-queries: update synopsis and description David Bremner
2021-09-05 19:31 ` v5 sexp query parser David Bremner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210824151745.2941868-35-david@tethera.net \
    --to=david@tethera.net \
    --cc=notmuch@notmuchmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).