* mu-store/mu-msg-fields: special handling for To:/Cc:/From: so we can better
search for them.
This commit is contained in:
@ -20,11 +20,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "mu-msg-fields.h"
|
#include "mu-msg-fields.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* note: the differences for our purposes between a xapian field and a term:
|
||||||
|
* - there is only a single value for some item in per document (msg), ie.
|
||||||
|
* one value containing the list of To: addresses
|
||||||
|
* - there can be multiple terms, each containing e.g. one of the To: addresses
|
||||||
|
* - searching uses terms, but to display some field, it must be in the
|
||||||
|
* value (at least when using MuMsgIter)
|
||||||
|
*/
|
||||||
enum _FieldFlags {
|
enum _FieldFlags {
|
||||||
FLAG_GMIME = 1 << 1, /* field retrieved through gmime */
|
FLAG_GMIME = 1 << 1, /* field retrieved through gmime */
|
||||||
FLAG_XAPIAN_INDEX = 1 << 2, /* field is indexed in xapian */
|
FLAG_XAPIAN_INDEX = 1 << 2, /* field is indexed in xapian */
|
||||||
FLAG_XAPIAN_TERM = 1 << 3, /* field stored as term in xapian */
|
FLAG_XAPIAN_TERM = 1 << 3, /* field stored as term in xapian */
|
||||||
FLAG_XAPIAN_VALUE = 1 << 4 /* field stored as value in xapian */
|
FLAG_XAPIAN_VALUE = 1 << 4, /* field stored as value in xapian */
|
||||||
|
FLAG_XAPIAN_CONTACT = 1 << 5 /* field contains e-mail address */
|
||||||
};
|
};
|
||||||
typedef enum _FieldFlags FieldFlags;
|
typedef enum _FieldFlags FieldFlags;
|
||||||
|
|
||||||
@ -40,7 +49,9 @@ struct _MuMsgField {
|
|||||||
FieldFlags _flags; /* the flags that tells us what to do */
|
FieldFlags _flags; /* the flags that tells us what to do */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* the name and shortcut fields must be lower case, or they might be
|
||||||
|
* misinterpreted by the query-preprocesser which turns queries into
|
||||||
|
* lowercase */
|
||||||
static const MuMsgField FIELD_DATA[] = {
|
static const MuMsgField FIELD_DATA[] = {
|
||||||
{
|
{
|
||||||
MU_MSG_FIELD_ID_BODY_TEXT,
|
MU_MSG_FIELD_ID_BODY_TEXT,
|
||||||
@ -60,7 +71,7 @@ static const MuMsgField FIELD_DATA[] = {
|
|||||||
MU_MSG_FIELD_ID_CC,
|
MU_MSG_FIELD_ID_CC,
|
||||||
MU_MSG_FIELD_TYPE_STRING,
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
"cc", "c", "C",
|
"cc", "c", "C",
|
||||||
FLAG_GMIME | FLAG_XAPIAN_INDEX | FLAG_XAPIAN_VALUE
|
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -81,7 +92,7 @@ static const MuMsgField FIELD_DATA[] = {
|
|||||||
MU_MSG_FIELD_ID_FROM,
|
MU_MSG_FIELD_ID_FROM,
|
||||||
MU_MSG_FIELD_TYPE_STRING,
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
"from", "f", "F",
|
"from", "f", "F",
|
||||||
FLAG_GMIME | FLAG_XAPIAN_INDEX | FLAG_XAPIAN_VALUE
|
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -123,7 +134,7 @@ static const MuMsgField FIELD_DATA[] = {
|
|||||||
MU_MSG_FIELD_ID_TO,
|
MU_MSG_FIELD_ID_TO,
|
||||||
MU_MSG_FIELD_TYPE_STRING,
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
"to", "t", "T",
|
"to", "t", "T",
|
||||||
FLAG_GMIME | FLAG_XAPIAN_INDEX | FLAG_XAPIAN_VALUE
|
FLAG_GMIME | FLAG_XAPIAN_CONTACT | FLAG_XAPIAN_VALUE
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -232,7 +243,12 @@ mu_msg_field_xapian_term (const MuMsgField *field)
|
|||||||
return field->_flags & FLAG_XAPIAN_TERM;
|
return field->_flags & FLAG_XAPIAN_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mu_msg_field_xapian_contact (const MuMsgField *field)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (field, FALSE);
|
||||||
|
return field->_flags & FLAG_XAPIAN_CONTACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|||||||
@ -169,6 +169,16 @@ gboolean mu_msg_field_xapian_term (const MuMsgField *field) G_GNUC_PURE;
|
|||||||
*/
|
*/
|
||||||
gboolean mu_msg_field_xapian_value (const MuMsgField *field) G_GNUC_PURE;
|
gboolean mu_msg_field_xapian_value (const MuMsgField *field) G_GNUC_PURE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* should this field be stored as contact information? This means that
|
||||||
|
* e-mail address will be stored as terms, and names will be indexed
|
||||||
|
*
|
||||||
|
* @param field a MuMsgField
|
||||||
|
*
|
||||||
|
* @return TRUE if the field should be stored as contact information,
|
||||||
|
* FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean mu_msg_field_xapian_contact (const MuMsgField *field) G_GNUC_PURE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is the field gmime-enabled? That is, can be field be retrieved
|
* is the field gmime-enabled? That is, can be field be retrieved
|
||||||
|
|||||||
@ -23,8 +23,10 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <xapian.h>
|
#include <xapian.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "mu-msg.h"
|
#include "mu-msg.h"
|
||||||
|
#include "mu-msg-contact.h"
|
||||||
#include "mu-store.h"
|
#include "mu-store.h"
|
||||||
#include "mu-util.h"
|
#include "mu-util.h"
|
||||||
|
|
||||||
@ -164,7 +166,6 @@ mu_store_flush (MuStore *store)
|
|||||||
store->_db->flush ();
|
store->_db->flush ();
|
||||||
|
|
||||||
} MU_XAPIAN_CATCH_BLOCK;
|
} MU_XAPIAN_CATCH_BLOCK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -200,9 +201,8 @@ add_terms_values_string (Xapian::Document& doc, MuMsg *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mu_msg_field_xapian_term(field))
|
if (mu_msg_field_xapian_term(field))
|
||||||
/* terms can be up to MU_STORE_MAX_TERM_LENGTH
|
/* terms can be up to MU_STORE_MAX_TERM_LENGTH (240)
|
||||||
* (240) long; this is a Xapian limit
|
* long; this is a Xapian limit */
|
||||||
* */
|
|
||||||
doc.add_term (std::string (prefix + value, 0,
|
doc.add_term (std::string (prefix + value, 0,
|
||||||
MU_STORE_MAX_TERM_LENGTH));
|
MU_STORE_MAX_TERM_LENGTH));
|
||||||
|
|
||||||
@ -243,6 +243,8 @@ add_terms_values (const MuMsgField* field, MsgDoc* msgdoc)
|
|||||||
{
|
{
|
||||||
MuMsgFieldType type;
|
MuMsgFieldType type;
|
||||||
|
|
||||||
|
/* note: contact-stuff (To/Cc/From) will handled in
|
||||||
|
* add_contact_info, not here */
|
||||||
if (!mu_msg_field_xapian_index(field) &&
|
if (!mu_msg_field_xapian_index(field) &&
|
||||||
!mu_msg_field_xapian_term(field) &&
|
!mu_msg_field_xapian_term(field) &&
|
||||||
!mu_msg_field_xapian_value(field))
|
!mu_msg_field_xapian_value(field))
|
||||||
@ -270,6 +272,45 @@ add_terms_values (const MuMsgField* field, MsgDoc* msgdoc)
|
|||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
each_contact_info (MuMsgContact *contact, MsgDoc *data)
|
||||||
|
{
|
||||||
|
std::string pfx;
|
||||||
|
|
||||||
|
static const MuMsgField *to_field =
|
||||||
|
mu_msg_field_from_id (MU_MSG_FIELD_ID_TO);
|
||||||
|
static const MuMsgField *from_field =
|
||||||
|
mu_msg_field_from_id (MU_MSG_FIELD_ID_FROM);
|
||||||
|
static const MuMsgField *cc_field =
|
||||||
|
mu_msg_field_from_id (MU_MSG_FIELD_ID_CC);
|
||||||
|
|
||||||
|
static const std::string to_pfx (mu_msg_field_xapian_prefix(to_field));
|
||||||
|
static const std::string from_pfx (mu_msg_field_xapian_prefix(from_field));
|
||||||
|
static const std::string cc_pfx (mu_msg_field_xapian_prefix(cc_field));
|
||||||
|
|
||||||
|
switch (contact->type) {
|
||||||
|
case MU_MSG_CONTACT_TYPE_TO: pfx = to_pfx; break;
|
||||||
|
case MU_MSG_CONTACT_TYPE_FROM: pfx = from_pfx; break;
|
||||||
|
case MU_MSG_CONTACT_TYPE_CC: pfx = cc_pfx; break;
|
||||||
|
default: return; /* other types (like bcc) are ignored */
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_print ("[%s %s]\n", pfx.c_str(), contact->address);
|
||||||
|
|
||||||
|
if (contact->name && strlen(contact->name) > 0) {
|
||||||
|
Xapian::TermGenerator termgen;
|
||||||
|
termgen.set_document (*data->_doc);
|
||||||
|
termgen.index_text_without_positions (contact->name, 1, pfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contact->address && strlen (contact->address))
|
||||||
|
data->_doc->add_term (std::string (pfx + contact->address, 0,
|
||||||
|
MU_STORE_MAX_TERM_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* get a unique id for this message */
|
/* get a unique id for this message */
|
||||||
static std::string
|
static std::string
|
||||||
get_message_uid (const char* path)
|
get_message_uid (const char* path)
|
||||||
@ -282,7 +323,7 @@ get_message_uid (const char* path)
|
|||||||
return pathprefix + path;
|
return pathprefix + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string
|
static const std::string
|
||||||
get_message_uid (MuMsg *msg)
|
get_message_uid (MuMsg *msg)
|
||||||
{
|
{
|
||||||
return get_message_uid (mu_msg_get_path(msg));
|
return get_message_uid (mu_msg_get_path(msg));
|
||||||
@ -308,6 +349,10 @@ mu_store_store (MuStore *store, MuMsg *msg)
|
|||||||
newdoc.add_term (uid);
|
newdoc.add_term (uid);
|
||||||
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_terms_values,
|
mu_msg_field_foreach ((MuMsgFieldForEachFunc)add_terms_values,
|
||||||
&msgdoc);
|
&msgdoc);
|
||||||
|
/* also store the contact-info as separate terms */
|
||||||
|
mu_msg_contact_foreach (msg,
|
||||||
|
(MuMsgContactForeachFunc)each_contact_info,
|
||||||
|
&msgdoc);
|
||||||
|
|
||||||
/* we replace all existing documents for this file */
|
/* we replace all existing documents for this file */
|
||||||
id = store->_db->replace_document (uid, newdoc);
|
id = store->_db->replace_document (uid, newdoc);
|
||||||
|
|||||||
Reference in New Issue
Block a user