* mu-store: many cleanups, fixes

This commit is contained in:
Dirk-Jan C. Binnema
2011-08-30 22:02:28 +03:00
parent 5e9ea1fa23
commit 6a13866235
5 changed files with 255 additions and 180 deletions

View File

@ -33,6 +33,19 @@
#include "mu-store.h"
#include "mu-contacts.h"
class MuStoreError {
public:
MuStoreError (MuError err, const std::string& what) :
_err (err), _what(what) {}
MuError mu_error () const { return _err; }
const std::string& what() const { return _what; }
private:
MuError _err;
const std::string _what;
};
struct _MuStore {
/* by default, use transactions of 30000 messages */
@ -40,34 +53,44 @@ struct _MuStore {
/* http://article.gmane.org/gmane.comp.search.xapian.general/3656 */
#define MU_STORE_MAX_TERM_LENGTH 240
_MuStore (const char *xpath, const char *contacts_cache, bool read_only):
_MuStore (const char *path, const char *contacts_path, bool read_only):
_in_transaction (false), _processed (0),
_batch_size(MU_STORE_DEFAULT_BATCH_SIZE),
_contacts(0), _version(0), _db(0), _read_only(read_only) {
_contacts(0), _path (0), _version(0),
_db(0), _read_only(read_only), _ref_count (1) {
if (!check_path ())
throw MuStoreError (MU_ERROR_FILE, "invalid_path");
_path = g_strdup (path);
if (read_only)
_db = new Xapian::Database (xpath);
_db = new Xapian::Database (path);
else
_db = new Xapian::WritableDatabase (xpath,
Xapian::DB_CREATE_OR_OPEN);
_db = new Xapian::WritableDatabase
(path, Xapian::DB_CREATE_OR_OPEN);
if (!check_version ())
throw std::runtime_error
("xapian db version check failed");
throw MuStoreError (MU_ERROR_XAPIAN_NOT_UP_TO_DATE,
("xapian db version check failed"));
if (contacts_cache) {
_contacts = mu_contacts_new (contacts_cache);
if (contacts_path) {
_contacts = mu_contacts_new (contacts_path);
if (!_contacts) /* don't bail-out for this */
throw std::runtime_error
("failed to init contacts cache");
throw MuStoreError (MU_ERROR_FILE,
("failed to init contacts cache"));
}
MU_WRITE_LOG ("%s: opened %s (batch size: %u)",
__FUNCTION__, xpath, batch_size());
__FUNCTION__, this->path(), batch_size());
}
~_MuStore () {
try {
if (_ref_count != 0)
g_warning ("ref count != 0");
g_free (_version);
g_free (_path);
mu_contacts_destroy (_contacts);
@ -81,24 +104,13 @@ struct _MuStore {
} MU_XAPIAN_CATCH_BLOCK;
}
/* get a unique id for this message; note, this function returns a
* static buffer -- not reentrant */
const char* get_message_uid (const char* path) {
char pfx = 0;
static char buf[PATH_MAX + 10];
if (G_UNLIKELY(!pfx)) {
pfx = mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_PATH);
buf[0]=pfx;
}
std::strcpy (buf + 1, path);
return buf;
}
/* close the old database, and write an empty one on top of it */
void clear();
/* get a unique id for this message; note, this function returns a
* static buffer -- not reentrant */
const char* get_message_uid (MuMsg *msg) {
return get_message_uid (mu_msg_get_path(msg));
}
* static buffer -- not reentrant */
const char* get_message_uid (const char* path);
const char* get_message_uid (MuMsg *msg);
MuContacts* contacts() { return _contacts; }
@ -108,38 +120,20 @@ struct _MuStore {
mu_store_get_metadata (this, MU_STORE_VERSION_KEY);
}
void begin_transaction () {
try {
db_writable()->begin_transaction();
set_in_transaction (true);
} MU_XAPIAN_CATCH_BLOCK;
}
void commit_transaction () {
try {
set_in_transaction (false);
db_writable()->commit_transaction();
} MU_XAPIAN_CATCH_BLOCK;
}
void rollback_transaction () {
try {
set_in_transaction (false);
db_writable()->cancel_transaction();
} MU_XAPIAN_CATCH_BLOCK;
}
void begin_transaction ();
void commit_transaction ();
void rollback_transaction ();
Xapian::WritableDatabase* db_writable() {
if (G_UNLIKELY(_read_only))
throw std::runtime_error
("database is read-only");
if (G_UNLIKELY(is_read_only()))
throw std::runtime_error ("database is read-only");
return (Xapian::WritableDatabase*)_db;
}
Xapian::Database* db_read_only() const {
return _db;
}
Xapian::Database* db_read_only() const { return _db; }
const char* path () const { return _path; }
bool is_read_only () const { return _read_only; }
size_t batch_size () const { return _batch_size;}
size_t set_batch_size (size_t n) {
@ -153,31 +147,15 @@ struct _MuStore {
int set_processed (int n) { return _processed = n;}
int inc_processed () { return ++_processed; }
/* MuStore is ref-counted */
guint ref () { return ++_ref_count; }
guint unref () { return --_ref_count; }
private:
bool check_version () {
const gchar *version;
version = mu_store_version (this);
/* no version yet? it must be a new db then; we'll set the version */
if (!version) {
if (!mu_store_set_metadata (this, MU_STORE_VERSION_KEY,
MU_XAPIAN_DB_VERSION)) {
g_warning ("failed to set database version");
return FALSE;
}
return TRUE; /* ok, done. */
}
/* we have a version, but is it the right one? */
if (std::strcmp (version, MU_XAPIAN_DB_VERSION) != 0) {
g_warning ("expected db version %s, but got %s",
MU_XAPIAN_DB_VERSION,
version ? version : "<none>" );
return FALSE;
}
return TRUE;
bool check_version ();
bool check_path () {
return true; // FIXME
}
/* transaction handling */
@ -187,10 +165,14 @@ private:
/* contacts object to cache all the contact information */
MuContacts *_contacts;
char *_path;
mutable char *_version;
Xapian::Database *_db;
bool _read_only;
guint _ref_count;
};