* lib: try to reopen database when it got updated from the outside (for guile)

This commit is contained in:
djcb 2012-08-19 09:57:49 +03:00
parent 90674172b9
commit 93171a5b90
4 changed files with 48 additions and 7 deletions

View File

@ -110,9 +110,12 @@ private:
MuMsg *_msg;
};
MuMsgIter*
mu_msg_iter_new (XapianEnquire *enq, size_t maxnum,
gboolean threads, MuMsgFieldId sortfield, gboolean revert)
gboolean threads, MuMsgFieldId sortfield, gboolean revert,
GError **err)
{
g_return_val_if_fail (enq, NULL);
/* sortfield should be set to .._NONE when we're not threading */
@ -125,7 +128,13 @@ mu_msg_iter_new (XapianEnquire *enq, size_t maxnum,
return new MuMsgIter ((Xapian::Enquire&)*enq, maxnum, threads,
sortfield, revert ? true : false);
} MU_XAPIAN_CATCH_BLOCK_RETURN(NULL);
} catch (const Xapian::DatabaseModifiedError &dbmex) {
mu_util_g_set_error (err, MU_ERROR_XAPIAN_MODIFIED,
"database was modified; please reopen");
return 0;
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, 0);
}

View File

@ -48,13 +48,16 @@ typedef struct _MuMsgIter MuMsgIter;
* @param sorting field when using threads; note, when 'threads' is
* FALSE, this should be MU_MSG_FIELD_ID_NONE
* @param if TRUE, revert the sorting order
* @param err receives error information. if the error is MU_ERROR_XAPIAN_MODIFIED,
* the database should be reloaded.
*
* @return a new MuMsgIter, or NULL in case of error
*/
MuMsgIter *mu_msg_iter_new (XapianEnquire *enq,
size_t batchsize, gboolean threads,
MuMsgFieldId threadsortfield,
gboolean revert) G_GNUC_WARN_UNUSED_RESULT;
gboolean revert,
GError **err) G_GNUC_WARN_UNUSED_RESULT;
/**
* get the next message (which you got from

View File

@ -309,6 +309,26 @@ mu_query_preprocess (const char *query, GError **err)
}
/* this function is for handling the case where a DatabaseModified
* exception is raised. We try to reopen the database, and run the
* query again. */
static MuMsgIter *
try_requery (MuQuery *self, const char* searchexpr, gboolean threads,
MuMsgFieldId sortfieldid, gboolean revert, int maxnum,
GError **err)
{
try {
/* let's assume that infinite regression is
* impossible */
self->db().reopen();
MU_WRITE_LOG ("reopening db after modification");
return mu_query_run (self, searchexpr, threads, sortfieldid,
revert, maxnum, err);
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, 0);
}
MuMsgIter*
mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
MuMsgFieldId sortfieldid, gboolean revert, int maxnum,
@ -320,6 +340,7 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
sortfieldid == MU_MSG_FIELD_ID_NONE,
NULL);
try {
MuMsgIter *iter;
Xapian::Enquire enq (self->db());
/* note, when our result will be *threaded*, we sort
@ -336,12 +357,18 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
enq.set_cutoff(0,0);
return mu_msg_iter_new (
iter = mu_msg_iter_new (
reinterpret_cast<XapianEnquire*>(&enq),
maxnum <= 0 ? self->db().get_doccount() : maxnum,
threads,
threads ? sortfieldid : MU_MSG_FIELD_ID_NONE,
revert);
threads, threads ? sortfieldid : MU_MSG_FIELD_ID_NONE,
revert, err);
if (err && *err && (*err)->code == MU_ERROR_XAPIAN_MODIFIED) {
g_clear_error (err);
return try_requery (self, searchexpr, threads, sortfieldid,
revert, maxnum, err);
} else
return iter;
} MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, 0);
}

View File

@ -414,6 +414,8 @@ enum _MuError {
MU_ERROR_XAPIAN_STORE_FAILED = 20,
/* could not remove */
MU_ERROR_XAPIAN_REMOVE_FAILED = 21,
/* database was modified; reload */
MU_ERROR_XAPIAN_MODIFIED = 22,
/* GMime related errors */