[PATCH v6 6/9] lib: add date range query support
[notmuch-archives.git] / 31 / 16320400060e375d07428edc2ac0f85f3edfa8
1 Return-Path: <jani@nikula.org>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 57028431FC0\r
6         for <notmuch@notmuchmail.org>; Tue, 30 Oct 2012 13:33:21 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
9 X-Spam-Flag: NO\r
10 X-Spam-Score: -0.7\r
11 X-Spam-Level: \r
12 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
13         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id GaDjFCp5wK7d for <notmuch@notmuchmail.org>;\r
17         Tue, 30 Oct 2012 13:33:18 -0700 (PDT)\r
18 Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com\r
19         [209.85.217.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
20         (No client certificate requested)\r
21         by olra.theworths.org (Postfix) with ESMTPS id 5CDD6429E2F\r
22         for <notmuch@notmuchmail.org>; Tue, 30 Oct 2012 13:33:05 -0700 (PDT)\r
23 Received: by mail-lb0-f181.google.com with SMTP id gg6so567600lbb.26\r
24         for <notmuch@notmuchmail.org>; Tue, 30 Oct 2012 13:33:04 -0700 (PDT)\r
25 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
26         d=google.com; s=20120113;\r
27         h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references\r
28         :in-reply-to:references:mime-version:content-type\r
29         :content-transfer-encoding:x-gm-message-state;\r
30         bh=B8qZH475TewuIO7Z7jhYuIVn+EFJdUqvgsbthY4Ja8c=;\r
31         b=LICiHX5UJRSFGkNW9SPeAjoAKEbuvs2mTQdp37dOnnZ9/U6YL3ZVPB7kc44r3M+iDY\r
32         jDsbAdVgNID7qj/dBoaAIHr/btMZYt+UvL+xHxY2IX82RO+lzxd8qmpg8fuHODyLXWbT\r
33         d+CH5yoEoTHkJdNTsikUamezQ8wW8+KxaQZari90TlPufAp4D1iHAb41p2Xh/h4Q/5S+\r
34         K5VB2R8d/l5ty2iH01fYiTzkfYJBVmssLNfOtiFi4nDyXM++tAIIwC/mFwgekyykXUtO\r
35         GiIcwPY0gem2OAd1h+TzXhpGqlba42QKHKhAbkQfCW4uQcfH3SR6+r31cSuYkmTcgh3F\r
36         DIFQ==\r
37 Received: by 10.112.102.196 with SMTP id fq4mr13550839lbb.125.1351629184822;\r
38         Tue, 30 Oct 2012 13:33:04 -0700 (PDT)\r
39 Received: from localhost (dsl-hkibrasgw4-fe51df00-27.dhcp.inet.fi.\r
40         [80.223.81.27])\r
41         by mx.google.com with ESMTPS id ew2sm764587lbb.2.2012.10.30.13.33.02\r
42         (version=SSLv3 cipher=OTHER); Tue, 30 Oct 2012 13:33:03 -0700 (PDT)\r
43 From: Jani Nikula <jani@nikula.org>\r
44 To: notmuch@notmuchmail.org\r
45 Subject: [PATCH v6 6/9] lib: add date range query support\r
46 Date: Tue, 30 Oct 2012 22:32:37 +0200\r
47 Message-Id:\r
48  <51cbf8eb0e7e1b0e7cedfa8b0443deabe99d0b2b.1351626272.git.jani@nikula.org>\r
49 X-Mailer: git-send-email 1.7.10.4\r
50 In-Reply-To: <cover.1351626272.git.jani@nikula.org>\r
51 References: <cover.1351626272.git.jani@nikula.org>\r
52 In-Reply-To: <cover.1351626272.git.jani@nikula.org>\r
53 References: <cover.1351626272.git.jani@nikula.org>\r
54 MIME-Version: 1.0\r
55 Content-Type: text/plain; charset=UTF-8\r
56 Content-Transfer-Encoding: 8bit\r
57 X-Gm-Message-State:\r
58  ALoCoQnhldJ4QscuOPLBuZUc6zJBDH1AkRws3XpvQxvH2syi71ydXXX6UtWZkMA9x3XtVvEIMbS8\r
59 X-BeenThere: notmuch@notmuchmail.org\r
60 X-Mailman-Version: 2.1.13\r
61 Precedence: list\r
62 List-Id: "Use and development of the notmuch mail system."\r
63         <notmuch.notmuchmail.org>\r
64 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
65         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
66 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
67 List-Post: <mailto:notmuch@notmuchmail.org>\r
68 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
69 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
70         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
71 X-List-Received-Date: Tue, 30 Oct 2012 20:33:21 -0000\r
72 \r
73 Add a custom value range processor to enable date and time searches of\r
74 the form date:since..until, where "since" and "until" are expressions\r
75 understood by the previously added date/time parser, to restrict the\r
76 results to messages within a particular time range (based on the Date:\r
77 header).\r
78 \r
79 If "since" or "until" describes date/time at an accuracy of days or\r
80 less, the values are rounded according to the accuracy, towards past\r
81 for "since" and towards future for "until". For example,\r
82 date:november..yesterday would match from the beginning of November\r
83 until the end of yesterday. Expressions such as date:today..today\r
84 means since the beginning of today until the end of today.\r
85 \r
86 Open-ended ranges are supported (since Xapian 1.2.1), i.e. you can\r
87 specify date:..until or date:since.. to not limit the start or end\r
88 date, respectively.\r
89 \r
90 CAVEATS:\r
91 \r
92 Xapian does not support spaces in range expressions. You can replace\r
93 the spaces with '_', or (in most cases) '-', or (in some cases) leave\r
94 the spaces out altogether.\r
95 \r
96 Entering date:expr without ".." (for example date:yesterday) will not\r
97 work as you might expect. You can achieve the expected result by\r
98 duplicating the expr both sides of ".." (for example\r
99 date:yesterday..yesterday).\r
100 \r
101 Open-ended ranges won't work with pre-1.2.1 Xapian, but they don't\r
102 produce an error either.\r
103 \r
104 Signed-off-by: Jani Nikula <jani@nikula.org>\r
105 ---\r
106  lib/Makefile.local     |    1 +\r
107  lib/database-private.h |    1 +\r
108  lib/database.cc        |    5 ++++\r
109  lib/parse-time-vrp.cc  |   61 ++++++++++++++++++++++++++++++++++++++++++++++++\r
110  lib/parse-time-vrp.h   |   40 +++++++++++++++++++++++++++++++\r
111  5 files changed, 108 insertions(+)\r
112  create mode 100644 lib/parse-time-vrp.cc\r
113  create mode 100644 lib/parse-time-vrp.h\r
114 \r
115 diff --git a/lib/Makefile.local b/lib/Makefile.local\r
116 index 62d76b2..7785944 100644\r
117 --- a/lib/Makefile.local\r
118 +++ b/lib/Makefile.local\r
119 @@ -61,6 +61,7 @@ libnotmuch_c_srcs =           \\r
120  \r
121  libnotmuch_cxx_srcs =          \\r
122         $(dir)/database.cc      \\r
123 +       $(dir)/parse-time-vrp.cc        \\r
124         $(dir)/directory.cc     \\r
125         $(dir)/index.cc         \\r
126         $(dir)/message.cc       \\r
127 diff --git a/lib/database-private.h b/lib/database-private.h\r
128 index 88532d5..d3e65fd 100644\r
129 --- a/lib/database-private.h\r
130 +++ b/lib/database-private.h\r
131 @@ -52,6 +52,7 @@ struct _notmuch_database {\r
132      Xapian::QueryParser *query_parser;\r
133      Xapian::TermGenerator *term_gen;\r
134      Xapian::ValueRangeProcessor *value_range_processor;\r
135 +    Xapian::ValueRangeProcessor *date_range_processor;\r
136  };\r
137  \r
138  /* Return the list of terms from the given iterator matching a prefix.\r
139 diff --git a/lib/database.cc b/lib/database.cc\r
140 index 761dc1a..4df3217 100644\r
141 --- a/lib/database.cc\r
142 +++ b/lib/database.cc\r
143 @@ -19,6 +19,7 @@\r
144   */\r
145  \r
146  #include "database-private.h"\r
147 +#include "parse-time-vrp.h"\r
148  \r
149  #include <iostream>\r
150  \r
151 @@ -710,12 +711,14 @@ notmuch_database_open (const char *path,\r
152         notmuch->term_gen = new Xapian::TermGenerator;\r
153         notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));\r
154         notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);\r
155 +       notmuch->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);\r
156  \r
157         notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);\r
158         notmuch->query_parser->set_database (*notmuch->xapian_db);\r
159         notmuch->query_parser->set_stemmer (Xapian::Stem ("english"));\r
160         notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME);\r
161         notmuch->query_parser->add_valuerangeprocessor (notmuch->value_range_processor);\r
162 +       notmuch->query_parser->add_valuerangeprocessor (notmuch->date_range_processor);\r
163  \r
164         for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {\r
165             prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i];\r
166 @@ -778,6 +781,8 @@ notmuch_database_close (notmuch_database_t *notmuch)\r
167      notmuch->xapian_db = NULL;\r
168      delete notmuch->value_range_processor;\r
169      notmuch->value_range_processor = NULL;\r
170 +    delete notmuch->date_range_processor;\r
171 +    notmuch->date_range_processor = NULL;\r
172  }\r
173  \r
174  void\r
175 diff --git a/lib/parse-time-vrp.cc b/lib/parse-time-vrp.cc\r
176 new file mode 100644\r
177 index 0000000..33f07db\r
178 --- /dev/null\r
179 +++ b/lib/parse-time-vrp.cc\r
180 @@ -0,0 +1,61 @@\r
181 +/* parse-time-vrp.cc - date range query glue\r
182 + *\r
183 + * This file is part of notmuch.\r
184 + *\r
185 + * Copyright © 2012 Jani Nikula\r
186 + *\r
187 + * This program is free software: you can redistribute it and/or modify\r
188 + * it under the terms of the GNU General Public License as published by\r
189 + * the Free Software Foundation, either version 3 of the License, or\r
190 + * (at your option) any later version.\r
191 + *\r
192 + * This program is distributed in the hope that it will be useful,\r
193 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
194 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
195 + * GNU General Public License for more details.\r
196 + *\r
197 + * You should have received a copy of the GNU General Public License\r
198 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
199 + *\r
200 + * Author: Jani Nikula <jani@nikula.org>\r
201 + */\r
202 +\r
203 +#include "database-private.h"\r
204 +#include "parse-time-vrp.h"\r
205 +#include "parse-time-string.h"\r
206 +\r
207 +#define PREFIX "date:"\r
208 +\r
209 +/* See *ValueRangeProcessor in xapian-core/api/valuerangeproc.cc */\r
210 +Xapian::valueno\r
211 +ParseTimeValueRangeProcessor::operator() (std::string &begin, std::string &end)\r
212 +{\r
213 +    time_t t, now;\r
214 +\r
215 +    /* Require date: prefix in start of the range... */\r
216 +    if (STRNCMP_LITERAL (begin.c_str (), PREFIX))\r
217 +       return Xapian::BAD_VALUENO;\r
218 +\r
219 +    /* ...and remove it. */\r
220 +    begin.erase (0, sizeof (PREFIX) - 1);\r
221 +\r
222 +    /* Use the same 'now' for begin and end. */\r
223 +    if (time (&now) == (time_t) -1)\r
224 +       return Xapian::BAD_VALUENO;\r
225 +\r
226 +    if (!begin.empty ()) {\r
227 +       if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN))\r
228 +           return Xapian::BAD_VALUENO;\r
229 +\r
230 +       begin.assign (Xapian::sortable_serialise ((double) t));\r
231 +    }\r
232 +\r
233 +    if (!end.empty ()) {\r
234 +       if (parse_time_string (end.c_str (), &t, &now, PARSE_TIME_ROUND_UP_INCLUSIVE))\r
235 +           return Xapian::BAD_VALUENO;\r
236 +\r
237 +       end.assign (Xapian::sortable_serialise ((double) t));\r
238 +    }\r
239 +\r
240 +    return valno;\r
241 +}\r
242 diff --git a/lib/parse-time-vrp.h b/lib/parse-time-vrp.h\r
243 new file mode 100644\r
244 index 0000000..094c4f8\r
245 --- /dev/null\r
246 +++ b/lib/parse-time-vrp.h\r
247 @@ -0,0 +1,40 @@\r
248 +/* parse-time-vrp.h - date range query glue\r
249 + *\r
250 + * This file is part of notmuch.\r
251 + *\r
252 + * Copyright © 2012 Jani Nikula\r
253 + *\r
254 + * This program is free software: you can redistribute it and/or modify\r
255 + * it under the terms of the GNU General Public License as published by\r
256 + * the Free Software Foundation, either version 3 of the License, or\r
257 + * (at your option) any later version.\r
258 + *\r
259 + * This program is distributed in the hope that it will be useful,\r
260 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
261 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
262 + * GNU General Public License for more details.\r
263 + *\r
264 + * You should have received a copy of the GNU General Public License\r
265 + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
266 + *\r
267 + * Author: Jani Nikula <jani@nikula.org>\r
268 + */\r
269 +\r
270 +#ifndef NOTMUCH_PARSE_TIME_VRP_H\r
271 +#define NOTMUCH_PARSE_TIME_VRP_H\r
272 +\r
273 +#include <xapian.h>\r
274 +\r
275 +/* see *ValueRangeProcessor in xapian-core/include/xapian/queryparser.h */\r
276 +class ParseTimeValueRangeProcessor : public Xapian::ValueRangeProcessor {\r
277 +protected:\r
278 +    Xapian::valueno valno;\r
279 +\r
280 +public:\r
281 +    ParseTimeValueRangeProcessor (Xapian::valueno slot_)\r
282 +       : valno(slot_) { }\r
283 +\r
284 +    Xapian::valueno operator() (std::string &begin, std::string &end);\r
285 +};\r
286 +\r
287 +#endif /* NOTMUCH_PARSE_TIME_VRP_H */\r
288 -- \r
289 1.7.10.4\r
290 \r