Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id A2FF4431FBC for ; Fri, 22 Jan 2010 07:26:21 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0.432 X-Spam-Level: X-Spam-Status: No, score=0.432 tagged_above=-999 required=5 tests=[AWL=0.431, BAYES_50=0.001] autolearn=ham Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DtnvFv47Uvmj for ; Fri, 22 Jan 2010 07:26:20 -0800 (PST) Received: from homiemail-a19.g.dreamhost.com (caiajhbdcaid.dreamhost.com [208.97.132.83]) by olra.theworths.org (Postfix) with ESMTP id CB17C431FAE for ; Fri, 22 Jan 2010 07:26:20 -0800 (PST) Received: from localhost.localdomain (unknown [84.55.198.58]) by homiemail-a19.g.dreamhost.com (Postfix) with ESMTPA id 696CC604014; Fri, 22 Jan 2010 07:26:18 -0800 (PST) From: Sebastian Spaeth To: notmuch@notmuchmail.org Date: Fri, 22 Jan 2010 16:26:11 +0100 Message-Id: <1264173971-11879-1-git-send-email-Sebastian@SSpaeth.de> X-Mailer: git-send-email 1.6.3.3 Subject: [notmuch] [PATCH] Make the date parser nicer X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 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, 22 Jan 2010 15:26:21 -0000 Currently we have to enter mail dates as timestamps. This approach does 2 things: it requires the prefix 'date:' and it allows timestamps to be specified as YYYY, YYYYMM or YYYYMMDD. So a notmuch show date:2005..20060512 will find all mails from 2005-01-01 until 2006-05-12. The code is probably not in a proper location yet and needs to be shoved around by someone more knowledgable than me. My C++ skills are somewhat,... lacking... Signed-off-by: Sebastian Spaeth --- lib/database.cc | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 93 insertions(+), 1 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 5b12320..102a6ff 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -494,6 +494,97 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch) return NOTMUCH_STATUS_SUCCESS; } +struct MaildateValueRangeProcessor : public Xapian::ValueRangeProcessor { + MaildateValueRangeProcessor() {} + + Xapian::valueno operator()(std::string &begin, std::string &end) { + if (begin.substr(0, 5) != "date:") + return Xapian::BAD_VALUENO; + begin.erase(0, 5); + + // Parse the begin date to time_t + struct tm *timeinfo; + time_t begintime, endtime; + //const char * startptr; + int year, month, day; + + if (begin.size() == 8) { + int no_items; + no_items = sscanf(begin.c_str(), "%4i%2i%2i", &year, &month, &day); + if (no_items != 3) + return Xapian::BAD_VALUENO; + } else if (begin.size() == 6) { + int no_items; + day = 1; + no_items = sscanf(begin.c_str(), "%4i%2i", &year, &month); + if (no_items != 2) + return Xapian::BAD_VALUENO; + } else if (begin.size() == 4) { + int no_items; + day = 1; + month = 1; + no_items = sscanf(begin.c_str(), "%4i", &year); + if (no_items != 1) + return Xapian::BAD_VALUENO; + } else { + // no expected time format + return Xapian::BAD_VALUENO; + } + + begintime = time(NULL); + timeinfo = localtime( &begintime ); + timeinfo -> tm_year = year - 1900; + timeinfo -> tm_mon = month - 1; + fprintf (stderr, "Startdate %d %d %d\n",year,month,day); + timeinfo -> tm_mday = day; + begintime = mktime ( timeinfo ); + + if (begintime == -1) + // no valid time format + return Xapian::BAD_VALUENO; + + if (end.size() == 8) { + int no_items; + no_items = sscanf(end.c_str(), "%4i%2i%2i", &year, &month, &day); + if (no_items != 3) + return Xapian::BAD_VALUENO; + } else if (end.size() == 6) { + int no_items; + day = 31; + no_items = sscanf(end.c_str(), "%4i%2i", &year, &month); + if (no_items != 2) + return Xapian::BAD_VALUENO; + } else if (end.size() == 4) { + int no_items; + day = 31; + month = 12; + no_items = sscanf(end.c_str(), "%4i", &year); + if (no_items != 1) + return Xapian::BAD_VALUENO; + } else { + // no expected time format + return Xapian::BAD_VALUENO; + } + + timeinfo = localtime( &begintime ); + timeinfo -> tm_year = year - 1900; + timeinfo -> tm_mon = month - 1; + fprintf (stderr, "Enddate %d %d %d\n",year,month,day); + timeinfo -> tm_mday = day; + endtime = mktime ( timeinfo ); + //XXX: plus 1 day to make the last day inclusive?? + + if (endtime == -1) + // no valid time format + return Xapian::BAD_VALUENO; + + begin.assign(Xapian::sortable_serialise(begintime)); + end.assign(Xapian::sortable_serialise(endtime)); + + return NOTMUCH_VALUE_TIMESTAMP; + } +}; + notmuch_database_t * notmuch_database_open (const char *path, notmuch_database_mode_t mode) @@ -570,7 +661,8 @@ notmuch_database_open (const char *path, notmuch->query_parser = new Xapian::QueryParser; notmuch->term_gen = new Xapian::TermGenerator; notmuch->term_gen->set_stemmer (Xapian::Stem ("english")); - notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:", true); + notmuch->value_range_processor = new MaildateValueRangeProcessor(); + // (NOTMUCH_VALUE_TIMESTAMP); notmuch->query_parser->set_default_op (Xapian::Query::OP_AND); notmuch->query_parser->set_database (*notmuch->xapian_db); -- 1.6.3.3