* mu-msg-xapian: let _next skip messages that are not found on disk

This commit is contained in:
Dirk-Jan C. Binnema 2010-01-03 23:52:19 +02:00
parent 5fad1f2dd7
commit 3942a06cba
1 changed files with 52 additions and 10 deletions

View File

@ -20,12 +20,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <iostream> #include <iostream>
#include <string.h> #include <string.h>
#include <errno.h>
#include "xapian.h" #include "xapian.h"
#include "mu-msg-xapian.h" #include "mu-msg-xapian.h"
struct _MuMsgXapian { struct _MuMsgXapian {
Xapian::Enquire *_enq; Xapian::Enquire *_enq;
Xapian::MSet _matches; Xapian::MSet _matches;
Xapian::MSet::const_iterator _cursor; Xapian::MSet::const_iterator _cursor;
@ -34,6 +34,9 @@ struct _MuMsgXapian {
char* _str[MU_MSG_FIELD_ID_NUM]; char* _str[MU_MSG_FIELD_ID_NUM];
}; };
/* FIXME: maybe use get_doccount() on the database object instead
* of specifying the batch size? */
MuMsgXapian * MuMsgXapian *
mu_msg_xapian_new (const Xapian::Enquire& enq, size_t batchsize) mu_msg_xapian_new (const Xapian::Enquire& enq, size_t batchsize)
{ {
@ -76,19 +79,58 @@ mu_msg_xapian_destroy (MuMsgXapian *msg)
} }
} }
static gboolean
_message_is_readable (MuMsgXapian *msg)
{
Xapian::Document doc (msg->_cursor.get_document());
const std::string path(doc.get_value(MU_MSG_FIELD_ID_PATH));
if (access (path.c_str(), R_OK) != 0) {
g_message ("cannot read %s: %s", path.c_str(),
strerror(errno));
return FALSE;
}
return TRUE;
}
gboolean gboolean
mu_msg_xapian_next (MuMsgXapian *msg) mu_msg_xapian_next (MuMsgXapian *msg)
{ {
g_return_val_if_fail (msg, FALSE); g_return_val_if_fail (msg, FALSE);
g_return_val_if_fail (!mu_msg_xapian_is_done(msg), FALSE); g_return_val_if_fail (!mu_msg_xapian_is_done(msg), FALSE);
if (++msg->_cursor == msg->_matches.end()) try {
return FALSE; /* no more matches */ if (++msg->_cursor == msg->_matches.end())
return FALSE; /* no more matches */
for (int i = 0; i != MU_MSG_FIELD_ID_NUM; ++i) {
g_free (msg->_str[i]); /* the message may not be readable / existant, eg., because
msg->_str[i] = NULL; * of the database not being fully up to date. in that case,
} * we ignore the message. it might be nice to auto-delete
* these messages from the db, but that would might screw
* up the search; also, we only have read-only access to the
* db here */
if (!_message_is_readable (msg))
return mu_msg_xapian_next (msg);
for (int i = 0; i != MU_MSG_FIELD_ID_NUM; ++i) {
g_free (msg->_str[i]);
msg->_str[i] = NULL;
}
} catch (const Xapian::Error &err) {
g_warning ("%s: caught xapian exception '%s' (%s)",
__FUNCTION__, err.get_msg().c_str(),
err.get_error_string());
return FALSE;
} catch (...) {
g_warning ("%s: caught exception", __FUNCTION__);
return FALSE;
}
return TRUE; return TRUE;
} }
@ -114,7 +156,7 @@ mu_msg_xapian_get_field (MuMsgXapian *row, const MuMsgField *field)
try { try {
MuMsgFieldId id; MuMsgFieldId id;
id = mu_msg_field_id (field); id = mu_msg_field_id (field);
if (!row->_str[id]) { /* cache the value */ if (!row->_str[id]) { /* cache the value */
Xapian::Document doc (row->_cursor.get_document()); Xapian::Document doc (row->_cursor.get_document());