From 4d4bff8eb3b82787c6586ab70d40a3402c751de6 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Sat, 14 May 2016 07:38:13 +2100 Subject: [PATCH] [Patch v5 11/11] lib: add support for named queries --- 7d/57180177d9f4b20a673914029fc733263cca5f | 269 ++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 7d/57180177d9f4b20a673914029fc733263cca5f diff --git a/7d/57180177d9f4b20a673914029fc733263cca5f b/7d/57180177d9f4b20a673914029fc733263cca5f new file mode 100644 index 000000000..d50afe835 --- /dev/null +++ b/7d/57180177d9f4b20a673914029fc733263cca5f @@ -0,0 +1,269 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by arlo.cworth.org (Postfix) with ESMTP id 8241B6DE093F + for ; Fri, 13 May 2016 03:38:54 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at cworth.org +X-Spam-Flag: NO +X-Spam-Score: -0.013 +X-Spam-Level: +X-Spam-Status: No, score=-0.013 tagged_above=-999 required=5 + tests=[AWL=-0.002, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] + autolearn=disabled +Received: from arlo.cworth.org ([127.0.0.1]) + by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id W1Lier8cjkMo for ; + Fri, 13 May 2016 03:38:46 -0700 (PDT) +Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) + by arlo.cworth.org (Postfix) with ESMTPS id 7F6D56DE02B0 + for ; Fri, 13 May 2016 03:38:26 -0700 (PDT) +Received: from remotemail by fethera.tethera.net with local (Exim 4.84) + (envelope-from ) + id 1b1AU7-0003P1-FS; Fri, 13 May 2016 06:38:19 -0400 +Received: (nullmailer pid 7566 invoked by uid 1000); + Fri, 13 May 2016 10:38:17 -0000 +From: David Bremner +To: notmuch@notmuchmail.org +Subject: [Patch v5 11/11] lib: add support for named queries +Date: Fri, 13 May 2016 07:38:13 -0300 +Message-Id: <1463135893-7471-12-git-send-email-david@tethera.net> +X-Mailer: git-send-email 2.8.1 +In-Reply-To: <1463135893-7471-1-git-send-email-david@tethera.net> +References: <1463135893-7471-1-git-send-email-david@tethera.net> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.20 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Fri, 13 May 2016 10:38:54 -0000 + +This relies on the optional presense of xapian field processors, and the +library config API. +--- + doc/man7/notmuch-search-terms.rst | 8 +++++++ + lib/Makefile.local | 1 + + lib/database-private.h | 1 + + lib/database.cc | 3 +++ + lib/query-fp.cc | 44 +++++++++++++++++++++++++++++++++++++++ + lib/query-fp.h | 42 +++++++++++++++++++++++++++++++++++++ + test/T600-named-queries.sh | 17 +++++++++++++++ + 7 files changed, 116 insertions(+) + create mode 100644 lib/query-fp.cc + create mode 100644 lib/query-fp.h + +diff --git a/doc/man7/notmuch-search-terms.rst b/doc/man7/notmuch-search-terms.rst +index adedf5a..223031b 100644 +--- a/doc/man7/notmuch-search-terms.rst ++++ b/doc/man7/notmuch-search-terms.rst +@@ -56,6 +56,8 @@ indicate user-supplied values): + + - lastmod:.. + ++- query: ++ + The **from:** prefix is used to match the name or address of the sender + of an email message. + +@@ -132,6 +134,11 @@ were added/removed or filenames changed). This is usually used in + conjunction with the **--uuid** argument to **notmuch search** + to find messages that have changed since an earlier query. + ++The **query:** prefix allows queries to refer to previously saved ++queries added with **notmuch-config(1)**. Named queries are only ++available if notmuch is built with **Xapian Field Processors** (see ++below). ++ + Operators + --------- + +@@ -385,6 +392,7 @@ notmuch was built against a sufficiently recent version of Xapian by running + Currently the following features require field processor support: + + - non-range date queries, e.g. "date:today" ++- named queries e.g. "query:my_special_query" + + SEE ALSO + ======== +diff --git a/lib/Makefile.local b/lib/Makefile.local +index 76b57cb..beb9635 100644 +--- a/lib/Makefile.local ++++ b/lib/Makefile.local +@@ -49,6 +49,7 @@ libnotmuch_cxx_srcs = \ + $(dir)/index.cc \ + $(dir)/message.cc \ + $(dir)/query.cc \ ++ $(dir)/query-fp.cc \ + $(dir)/config.cc \ + $(dir)/thread.cc + +diff --git a/lib/database-private.h b/lib/database-private.h +index d2990b6..1a78b60 100644 +--- a/lib/database-private.h ++++ b/lib/database-private.h +@@ -185,6 +185,7 @@ struct _notmuch_database { + Xapian::ValueRangeProcessor *date_range_processor; + #if HAVE_XAPIAN_FIELD_PROCESSOR + Xapian::FieldProcessor *date_field_processor; ++ Xapian::FieldProcessor *query_field_processor; + #endif + Xapian::ValueRangeProcessor *last_mod_range_processor; + }; +diff --git a/lib/database.cc b/lib/database.cc +index ebe019f..9630000 100644 +--- a/lib/database.cc ++++ b/lib/database.cc +@@ -20,6 +20,7 @@ + + #include "database-private.h" + #include "parse-time-vrp.h" ++#include "query-fp.h" + #include "string-util.h" + + #include +@@ -1005,6 +1006,8 @@ notmuch_database_open_verbose (const char *path, + * with a .. to the range processor */ + notmuch->date_field_processor = new DateFieldProcessor(); + notmuch->query_parser->add_boolean_prefix("date", notmuch->date_field_processor); ++ notmuch->query_field_processor = new QueryFieldProcessor (*notmuch->query_parser, notmuch); ++ notmuch->query_parser->add_boolean_prefix("query", notmuch->query_field_processor); + #endif + notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:"); + +diff --git a/lib/query-fp.cc b/lib/query-fp.cc +new file mode 100644 +index 0000000..73790cd +--- /dev/null ++++ b/lib/query-fp.cc +@@ -0,0 +1,44 @@ ++/* query-fp.cc - "query:" field processor glue ++ * ++ * This file is part of notmuch. ++ * ++ * Copyright © 2016 David Bremner ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/ . ++ * ++ * Author: David Bremner ++ */ ++ ++#include "database-private.h" ++#include "query-fp.h" ++#include ++ ++#if HAVE_XAPIAN_FIELD_PROCESSOR ++ ++Xapian::Query ++QueryFieldProcessor::operator() (const std::string & name) ++{ ++ std::string key = "query." + name; ++ char *expansion; ++ notmuch_status_t status; ++ ++ status = notmuch_database_get_config (notmuch, key.c_str (), &expansion); ++ if (status) { ++ throw Xapian::QueryParserError ("error looking up key" + name); ++ ++ } ++ ++ return parser.parse_query (expansion, NOTMUCH_QUERY_PARSER_FLAGS); ++} ++#endif +diff --git a/lib/query-fp.h b/lib/query-fp.h +new file mode 100644 +index 0000000..67f8705 +--- /dev/null ++++ b/lib/query-fp.h +@@ -0,0 +1,42 @@ ++/* query-fp.h - query field processor glue ++ * ++ * This file is part of notmuch. ++ * ++ * Copyright © 2016 David Bremner ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/ . ++ * ++ * Author: David Bremner ++ */ ++ ++#ifndef NOTMUCH_QUERY_FP_H ++#define NOTMUCH_QUERY_FP_H ++ ++#include ++#include "notmuch.h" ++ ++#if HAVE_XAPIAN_FIELD_PROCESSOR ++class QueryFieldProcessor : public Xapian::FieldProcessor { ++ protected: ++ Xapian::QueryParser &parser; ++ notmuch_database_t *notmuch; ++ ++ public: ++ QueryFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_) ++ : parser(parser_), notmuch(notmuch_) { }; ++ ++ Xapian::Query operator()(const std::string & str); ++}; ++#endif ++#endif /* NOTMUCH_QUERY_FP_H */ +diff --git a/test/T600-named-queries.sh b/test/T600-named-queries.sh +index 0922620..f0ae24f 100755 +--- a/test/T600-named-queries.sh ++++ b/test/T600-named-queries.sh +@@ -50,4 +50,21 @@ notmuch restore < BEFORE + notmuch dump | grep '^#@' > OUTPUT + test_expect_equal_file QUERIES.BEFORE OUTPUT + ++if [ $NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR -eq 1 ]; then ++ test_begin_subtest "search named query" ++ notmuch search query:test > OUTPUT ++ notmuch search $QUERYSTR > EXPECTED ++ test_expect_equal_file EXPECTED OUTPUT ++ ++ test_begin_subtest "search named query with other terms" ++ notmuch search query:test and subject:Maildir > OUTPUT ++ notmuch search $QUERYSTR and subject:Maildir > EXPECTED ++ test_expect_equal_file EXPECTED OUTPUT ++ ++ test_begin_subtest "search nested named query" ++ notmuch search query:test2 > OUTPUT ++ notmuch search $QUERYSTR2 > EXPECTED ++ test_expect_equal_file EXPECTED OUTPUT ++fi ++ + test_done +-- +2.8.1 + -- 2.26.2