mirror of https://github.com/djcb/mu.git
* add date-range searches using date:/d:
This commit is contained in:
parent
c1203dd047
commit
e0cada86d6
|
@ -104,6 +104,7 @@ search fields and their abbreviations:
|
|||
msgid,i Message-ID
|
||||
prio,p Message priority ('low', 'normal' or 'high')
|
||||
flag,g Message Flags
|
||||
date,d Date-Range
|
||||
.fi
|
||||
|
||||
For clarity, this man-page uses the longer versions.
|
||||
|
@ -159,6 +160,16 @@ can do with a single '/':
|
|||
|
||||
(and of course you can use the \fBm:\fR shortcut instead of \fBmaildir:\fR)
|
||||
|
||||
The date:/d: search parameter is 'special' in the fact that it takes a range
|
||||
of dates. For now, these dates are in ISO 8601 format (YYYYMMDD). To get all
|
||||
messages between (inclusive) the 5th of May 2009 and the 2nd of June 2010, you
|
||||
could use:
|
||||
|
||||
.nf
|
||||
mu find date:20090505..20100602
|
||||
.fi
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
Note, some of the important options are described in the \fBmu(1)\fR man-page
|
||||
|
|
|
@ -81,7 +81,7 @@ static const MuMsgField FIELD_DATA[] = {
|
|||
MU_MSG_FIELD_ID_DATE,
|
||||
MU_MSG_FIELD_TYPE_TIME_T,
|
||||
"date", 'd', 'D',
|
||||
FLAG_GMIME | FLAG_XAPIAN_VALUE
|
||||
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
@ -41,12 +41,15 @@ enum _MuMsgFieldId {
|
|||
MU_MSG_FIELD_ID_TO,
|
||||
MU_MSG_FIELD_ID_MSGID,
|
||||
MU_MSG_FIELD_ID_TIMESTAMP,
|
||||
|
||||
|
||||
MU_MSG_FIELD_ID_NUM
|
||||
};
|
||||
typedef enum _MuMsgFieldId MuMsgFieldId;
|
||||
|
||||
static const guint MU_MSG_FIELD_ID_NONE = (guint)-1;
|
||||
typedef guint MuMsgFieldId;
|
||||
/* some specials... */
|
||||
static const MuMsgFieldId MU_MSG_FIELD_ID_NONE = (MuMsgFieldId)-1;
|
||||
static const MuMsgFieldId MU_MSG_FIELD_ID_DATESTR =
|
||||
(MuMsgFieldId) (MU_MSG_FIELD_ID_NUM + 1);
|
||||
|
||||
#define mu_msg_field_id_is_valid(MFID) \
|
||||
((MFID) < MU_MSG_FIELD_ID_NUM)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
make/*
|
||||
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
|
@ -32,12 +32,36 @@
|
|||
#include "mu-util-db.h"
|
||||
#include "mu-msg-str.h"
|
||||
|
||||
|
||||
struct ISODateRangeProcessor : public Xapian::ValueRangeProcessor {
|
||||
ISODateRangeProcessor() {}
|
||||
|
||||
Xapian::valueno operator()(std::string &begin, std::string &end) {
|
||||
static const std::string colon (":");
|
||||
static const std::string name (
|
||||
mu_msg_field_name (MU_MSG_FIELD_ID_DATE) + colon);
|
||||
static const std::string shortcut (
|
||||
std::string(1, mu_msg_field_shortcut
|
||||
(MU_MSG_FIELD_ID_DATE)) + colon);
|
||||
|
||||
if (begin.find (name) == 0)
|
||||
begin.erase (0, name.length());
|
||||
else if (begin.find (shortcut) == 0)
|
||||
begin.erase (0, shortcut.length());
|
||||
else
|
||||
return Xapian::BAD_VALUENO;
|
||||
|
||||
return (Xapian::valueno)MU_MSG_FIELD_ID_DATESTR;
|
||||
}
|
||||
};
|
||||
|
||||
static void add_prefix (MuMsgFieldId field, Xapian::QueryParser* qparser);
|
||||
|
||||
struct _MuQuery {
|
||||
Xapian::Database* _db;
|
||||
Xapian::QueryParser* _qparser;
|
||||
Xapian::Sorter* _sorters[MU_MSG_FIELD_TYPE_NUM];
|
||||
Xapian::Database* _db;
|
||||
Xapian::QueryParser* _qparser;
|
||||
Xapian::Sorter* _sorters[MU_MSG_FIELD_TYPE_NUM];
|
||||
Xapian::ValueRangeProcessor* _range_processor;
|
||||
};
|
||||
|
||||
gboolean
|
||||
|
@ -52,8 +76,11 @@ init_mu_query (MuQuery *mqx, const char* dbpath)
|
|||
|
||||
mqx->_qparser->set_database (*mqx->_db);
|
||||
mqx->_qparser->set_default_op (Xapian::Query::OP_AND);
|
||||
//mqx->_qparser->set_stemming_strategy (Xapian::QueryParser::STEM_NONE);
|
||||
|
||||
mqx->_range_processor = new ISODateRangeProcessor ();
|
||||
mqx->_qparser->add_valuerangeprocessor
|
||||
(mqx->_range_processor);
|
||||
|
||||
memset (mqx->_sorters, 0, sizeof(mqx->_sorters));
|
||||
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_prefix,
|
||||
(gpointer)mqx->_qparser);
|
||||
|
@ -88,7 +115,8 @@ uninit_mu_query (MuQuery *mqx)
|
|||
try {
|
||||
delete mqx->_db;
|
||||
delete mqx->_qparser;
|
||||
|
||||
delete mqx->_range_processor;
|
||||
|
||||
for (int i = 0; i != MU_MSG_FIELD_TYPE_NUM; ++i)
|
||||
delete mqx->_sorters[i];
|
||||
|
||||
|
|
|
@ -266,6 +266,24 @@ mu_store_flush (MuStore *store)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
add_terms_values_date (Xapian::Document& doc, MuMsg *msg,
|
||||
MuMsgFieldId mfid)
|
||||
{
|
||||
char datebuf[9];
|
||||
static const std::string pfx (1, mu_msg_field_xapian_prefix(mfid));
|
||||
gint64 num = mu_msg_get_field_numeric (msg, mfid);
|
||||
|
||||
if (G_UNLIKELY(strftime(datebuf, sizeof(datebuf), "%Y%m%d",
|
||||
gmtime((const time_t*)&num)) == 0))
|
||||
g_return_if_reached();
|
||||
|
||||
const std::string numstr (Xapian::sortable_serialise((double)num));
|
||||
doc.add_value ((Xapian::valueno)mfid, numstr);
|
||||
doc.add_value ((Xapian::valueno)MU_MSG_FIELD_ID_DATESTR, datebuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
|
||||
MuMsgFieldId mfid)
|
||||
|
@ -288,6 +306,7 @@ add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
|
|||
} else if (mfid == MU_MSG_FIELD_ID_PRIO) {
|
||||
doc.add_term (pfx + std::string(1,
|
||||
mu_msg_prio_char((MuMsgPrio)num)));
|
||||
|
||||
} else
|
||||
doc.add_term (pfx + numstr);
|
||||
}
|
||||
|
@ -364,36 +383,32 @@ typedef struct _MsgDoc MsgDoc;
|
|||
static void
|
||||
add_terms_values (MuMsgFieldId mfid, MsgDoc* msgdoc)
|
||||
{
|
||||
MuMsgFieldType type;
|
||||
|
||||
/* note: contact-stuff (To/Cc/From) will handled in
|
||||
* add_contact_info, not here */
|
||||
if (!mu_msg_field_xapian_index(mfid) &&
|
||||
!mu_msg_field_xapian_term(mfid) &&
|
||||
!mu_msg_field_xapian_value(mfid))
|
||||
return;
|
||||
|
||||
type = mu_msg_field_type (mfid);
|
||||
|
||||
if (type == MU_MSG_FIELD_TYPE_STRING) {
|
||||
if (mfid == MU_MSG_FIELD_ID_BODY_TEXT)
|
||||
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg,
|
||||
mfid);
|
||||
switch (mfid) {
|
||||
case MU_MSG_FIELD_ID_DATE:
|
||||
add_terms_values_date (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||
break;
|
||||
case MU_MSG_FIELD_ID_BODY_TEXT:
|
||||
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||
break;
|
||||
default:
|
||||
if (mu_msg_field_is_numeric (mfid))
|
||||
add_terms_values_number (*msgdoc->_doc, msgdoc->_msg,
|
||||
mfid);
|
||||
else if (mu_msg_field_type (mfid) ==
|
||||
MU_MSG_FIELD_TYPE_STRING)
|
||||
add_terms_values_string (*msgdoc->_doc,
|
||||
msgdoc->_msg,
|
||||
mfid);
|
||||
else
|
||||
add_terms_values_string (*msgdoc->_doc, msgdoc->_msg,
|
||||
mfid);
|
||||
return;
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
if (type == MU_MSG_FIELD_TYPE_BYTESIZE ||
|
||||
type == MU_MSG_FIELD_TYPE_TIME_T ||
|
||||
type == MU_MSG_FIELD_TYPE_INT) {
|
||||
add_terms_values_number (*msgdoc->_doc, msgdoc->_msg,
|
||||
mfid);
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue