mirror of
https://github.com/djcb/mu.git
synced 2024-06-29 07:51:04 +02:00
* 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
|
msgid,i Message-ID
|
||||||
prio,p Message priority ('low', 'normal' or 'high')
|
prio,p Message priority ('low', 'normal' or 'high')
|
||||||
flag,g Message Flags
|
flag,g Message Flags
|
||||||
|
date,d Date-Range
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
For clarity, this man-page uses the longer versions.
|
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)
|
(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
|
.SH OPTIONS
|
||||||
|
|
||||||
Note, some of the important options are described in the \fBmu(1)\fR man-page
|
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_ID_DATE,
|
||||||
MU_MSG_FIELD_TYPE_TIME_T,
|
MU_MSG_FIELD_TYPE_TIME_T,
|
||||||
"date", 'd', 'D',
|
"date", 'd', 'D',
|
||||||
FLAG_GMIME | FLAG_XAPIAN_VALUE
|
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,9 +44,12 @@ enum _MuMsgFieldId {
|
||||||
|
|
||||||
MU_MSG_FIELD_ID_NUM
|
MU_MSG_FIELD_ID_NUM
|
||||||
};
|
};
|
||||||
|
typedef enum _MuMsgFieldId MuMsgFieldId;
|
||||||
|
|
||||||
static const guint MU_MSG_FIELD_ID_NONE = (guint)-1;
|
/* some specials... */
|
||||||
typedef guint MuMsgFieldId;
|
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) \
|
#define mu_msg_field_id_is_valid(MFID) \
|
||||||
((MFID) < MU_MSG_FIELD_ID_NUM)
|
((MFID) < MU_MSG_FIELD_ID_NUM)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
make/*
|
||||||
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify
|
** This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -32,12 +32,36 @@
|
||||||
#include "mu-util-db.h"
|
#include "mu-util-db.h"
|
||||||
#include "mu-msg-str.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);
|
static void add_prefix (MuMsgFieldId field, Xapian::QueryParser* qparser);
|
||||||
|
|
||||||
struct _MuQuery {
|
struct _MuQuery {
|
||||||
Xapian::Database* _db;
|
Xapian::Database* _db;
|
||||||
Xapian::QueryParser* _qparser;
|
Xapian::QueryParser* _qparser;
|
||||||
Xapian::Sorter* _sorters[MU_MSG_FIELD_TYPE_NUM];
|
Xapian::Sorter* _sorters[MU_MSG_FIELD_TYPE_NUM];
|
||||||
|
Xapian::ValueRangeProcessor* _range_processor;
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -52,7 +76,10 @@ init_mu_query (MuQuery *mqx, const char* dbpath)
|
||||||
|
|
||||||
mqx->_qparser->set_database (*mqx->_db);
|
mqx->_qparser->set_database (*mqx->_db);
|
||||||
mqx->_qparser->set_default_op (Xapian::Query::OP_AND);
|
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));
|
memset (mqx->_sorters, 0, sizeof(mqx->_sorters));
|
||||||
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_prefix,
|
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_prefix,
|
||||||
|
@ -88,6 +115,7 @@ uninit_mu_query (MuQuery *mqx)
|
||||||
try {
|
try {
|
||||||
delete mqx->_db;
|
delete mqx->_db;
|
||||||
delete mqx->_qparser;
|
delete mqx->_qparser;
|
||||||
|
delete mqx->_range_processor;
|
||||||
|
|
||||||
for (int i = 0; i != MU_MSG_FIELD_TYPE_NUM; ++i)
|
for (int i = 0; i != MU_MSG_FIELD_TYPE_NUM; ++i)
|
||||||
delete mqx->_sorters[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
|
static void
|
||||||
add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
|
add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
|
||||||
MuMsgFieldId mfid)
|
MuMsgFieldId mfid)
|
||||||
|
@ -288,6 +306,7 @@ add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
|
||||||
} else if (mfid == MU_MSG_FIELD_ID_PRIO) {
|
} else if (mfid == MU_MSG_FIELD_ID_PRIO) {
|
||||||
doc.add_term (pfx + std::string(1,
|
doc.add_term (pfx + std::string(1,
|
||||||
mu_msg_prio_char((MuMsgPrio)num)));
|
mu_msg_prio_char((MuMsgPrio)num)));
|
||||||
|
|
||||||
} else
|
} else
|
||||||
doc.add_term (pfx + numstr);
|
doc.add_term (pfx + numstr);
|
||||||
}
|
}
|
||||||
|
@ -364,8 +383,6 @@ typedef struct _MsgDoc MsgDoc;
|
||||||
static void
|
static void
|
||||||
add_terms_values (MuMsgFieldId mfid, MsgDoc* msgdoc)
|
add_terms_values (MuMsgFieldId mfid, MsgDoc* msgdoc)
|
||||||
{
|
{
|
||||||
MuMsgFieldType type;
|
|
||||||
|
|
||||||
/* note: contact-stuff (To/Cc/From) will handled in
|
/* note: contact-stuff (To/Cc/From) will handled in
|
||||||
* add_contact_info, not here */
|
* add_contact_info, not here */
|
||||||
if (!mu_msg_field_xapian_index(mfid) &&
|
if (!mu_msg_field_xapian_index(mfid) &&
|
||||||
|
@ -373,27 +390,25 @@ add_terms_values (MuMsgFieldId mfid, MsgDoc* msgdoc)
|
||||||
!mu_msg_field_xapian_value(mfid))
|
!mu_msg_field_xapian_value(mfid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type = mu_msg_field_type (mfid);
|
switch (mfid) {
|
||||||
|
case MU_MSG_FIELD_ID_DATE:
|
||||||
if (type == MU_MSG_FIELD_TYPE_STRING) {
|
add_terms_values_date (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||||
if (mfid == MU_MSG_FIELD_ID_BODY_TEXT)
|
break;
|
||||||
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg,
|
case MU_MSG_FIELD_ID_BODY_TEXT:
|
||||||
mfid);
|
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||||
else
|
break;
|
||||||
add_terms_values_string (*msgdoc->_doc, msgdoc->_msg,
|
default:
|
||||||
mfid);
|
if (mu_msg_field_is_numeric (mfid))
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
add_terms_values_number (*msgdoc->_doc, msgdoc->_msg,
|
||||||
mfid);
|
mfid);
|
||||||
return;
|
else if (mu_msg_field_type (mfid) ==
|
||||||
}
|
MU_MSG_FIELD_TYPE_STRING)
|
||||||
|
add_terms_values_string (*msgdoc->_doc,
|
||||||
|
msgdoc->_msg,
|
||||||
|
mfid);
|
||||||
|
else
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user