mirror of https://github.com/djcb/mu.git
mu: no need to pass 'maildir' when we can deduce it
Only needed when setting up the database.
This commit is contained in:
parent
ee4730382d
commit
38779cfade
|
@ -343,7 +343,7 @@ mu_index_run (MuIndex *index, gboolean reindex, gboolean lazycheck,
|
|||
g_return_val_if_fail (index && index->_store, MU_ERROR);
|
||||
g_return_val_if_fail (msg_cb, MU_ERROR);
|
||||
|
||||
path = mu_store_maildir (index->_store);
|
||||
path = mu_store_root_maildir (index->_store);
|
||||
if (!check_path (path))
|
||||
return MU_ERROR;
|
||||
|
||||
|
@ -401,7 +401,7 @@ mu_index_stats (MuIndex *index,
|
|||
g_return_val_if_fail (index, MU_ERROR);
|
||||
g_return_val_if_fail (cb_msg, MU_ERROR);
|
||||
|
||||
path = mu_store_maildir (index->_store);
|
||||
path = mu_store_root_maildir (index->_store);
|
||||
if (!check_path (path))
|
||||
return MU_ERROR;
|
||||
|
||||
|
|
164
lib/mu-store.cc
164
lib/mu-store.cc
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** Copyright (C) 2019 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the GNU General Public License as published by the
|
||||
|
@ -43,8 +43,6 @@ constexpr auto CreatedKey = "created";
|
|||
|
||||
constexpr auto ExpectedSchemaVersion = MU_STORE_SCHEMA_VERSION;
|
||||
|
||||
using Addresses = Store::Addresses;
|
||||
|
||||
extern "C" {
|
||||
static unsigned add_or_update_msg (MuStore *store, unsigned docid, MuMsg *msg, GError **err);
|
||||
}
|
||||
|
@ -99,8 +97,8 @@ struct Store::Private {
|
|||
Private (const std::string& path, bool readonly):
|
||||
db_path_{path},
|
||||
db_{readonly?
|
||||
std::make_shared<Xapian::Database>(db_path_) :
|
||||
std::make_shared<Xapian::WritableDatabase>(db_path_, Xapian::DB_OPEN)},
|
||||
std::make_shared<Xapian::Database>(db_path_) :
|
||||
std::make_shared<Xapian::WritableDatabase>(db_path_, Xapian::DB_OPEN)},
|
||||
root_maildir_{db()->get_metadata(RootMaildirKey)},
|
||||
created_{atoll(db()->get_metadata(CreatedKey).c_str())},
|
||||
schema_version_{db()->get_metadata(SchemaVersionKey)},
|
||||
|
@ -108,17 +106,29 @@ struct Store::Private {
|
|||
contacts_{db()->get_metadata(ContactsKey)} {
|
||||
}
|
||||
|
||||
Private (const std::string& path, const std::string& root_maildir):
|
||||
Private (const std::string& path, const std::string& root_maildir,
|
||||
const StringVec& personal_addresses):
|
||||
db_path_{path},
|
||||
db_{std::make_shared<Xapian::WritableDatabase>(
|
||||
db_path_, Xapian::DB_CREATE_OR_OVERWRITE)},
|
||||
root_maildir_{root_maildir},
|
||||
created_{time({})},
|
||||
schema_version_{MU_STORE_SCHEMA_VERSION} {
|
||||
schema_version_{MU_STORE_SCHEMA_VERSION},
|
||||
personal_addresses_{personal_addresses} {
|
||||
|
||||
writable_db()->set_metadata(SchemaVersionKey, schema_version_);
|
||||
writable_db()->set_metadata(RootMaildirKey, root_maildir_);
|
||||
writable_db()->set_metadata(CreatedKey, Mu::format("%" PRId64, (int64_t)created_));
|
||||
|
||||
std::string addrs;
|
||||
for (const auto& addr : personal_addresses_) { // _very_ minimal check.
|
||||
if (addr.find(",") != std::string::npos)
|
||||
throw Mu::Error(Error::Code::InvalidArgument,
|
||||
"e-mail address '%s' contains comma", addr.c_str());
|
||||
addrs += (addrs.empty() ? "": ",") + addr;
|
||||
}
|
||||
writable_db()->set_metadata (PersonalAddressesKey, addrs);
|
||||
|
||||
}
|
||||
|
||||
~Private() {
|
||||
|
@ -144,25 +154,6 @@ struct Store::Private {
|
|||
return w_db;
|
||||
}
|
||||
|
||||
void set_personal_addresses (const Addresses& addresses) {
|
||||
|
||||
std::string all_addresses;
|
||||
personal_addresses_.clear();
|
||||
|
||||
for (const auto& addr : addresses) {
|
||||
// very basic check; just ensure there's no ',' in the address.
|
||||
// we don't insist on full RFC5322
|
||||
if (addr.find(",") != std::string::npos)
|
||||
throw Mu::Error(Error::Code::InvalidArgument,
|
||||
"e-mail address '%s' contains comma", addr.c_str());
|
||||
if (!all_addresses.empty())
|
||||
all_addresses += ',';
|
||||
all_addresses += addr;
|
||||
personal_addresses_.emplace_back(addr);
|
||||
}
|
||||
writable_db()->set_metadata (PersonalAddressesKey, all_addresses);
|
||||
}
|
||||
|
||||
void add_synonyms () {
|
||||
mu_flags_foreach ((MuFlagsForeachFunc)add_synonym_for_flag,
|
||||
writable_db().get());
|
||||
|
@ -181,10 +172,10 @@ struct Store::Private {
|
|||
const std::string root_maildir_;
|
||||
const time_t created_{};
|
||||
const std::string schema_version_;
|
||||
Addresses personal_addresses_;
|
||||
const StringVec personal_addresses_;
|
||||
Contacts contacts_;
|
||||
|
||||
bool in_transaction_{};
|
||||
std::atomic<bool> in_transaction_{};
|
||||
std::mutex lock_;
|
||||
|
||||
mutable std::atomic<std::size_t> ref_count_{1};
|
||||
|
@ -218,20 +209,24 @@ Store::Store (const std::string& path, bool readonly):
|
|||
if (ExpectedSchemaVersion == schema_version())
|
||||
return; // All is good; nothing further to do
|
||||
|
||||
if (readonly || root_maildir().empty())
|
||||
throw Mu::Error(Error::Code::SchemaMismatch, "database needs reindexing");
|
||||
g_warning ("expected schema-version %s, but got %s",
|
||||
ExpectedSchemaVersion, schema_version().c_str());
|
||||
|
||||
if (readonly) // this requires user-action.
|
||||
throw Mu::Error(Error::Code::SchemaMismatch,
|
||||
"database needs reindexing");
|
||||
|
||||
g_debug ("upgrading database");
|
||||
const auto addresses{personal_addresses()};
|
||||
const auto root_mdir{root_maildir()};
|
||||
|
||||
priv_.reset();
|
||||
priv_ = std::make_unique<Private> (path, root_mdir);
|
||||
set_personal_addresses (addresses);
|
||||
priv_ = std::make_unique<Private> (path, root_mdir, addresses);
|
||||
}
|
||||
|
||||
Store::Store (const std::string& path, const std::string& maildir):
|
||||
priv_{std::make_unique<Private>(path, maildir)}
|
||||
Store::Store (const std::string& path, const std::string& maildir,
|
||||
const StringVec& personal_addresses):
|
||||
priv_{std::make_unique<Private>(path, maildir, personal_addresses)}
|
||||
{}
|
||||
|
||||
Store::~Store() = default;
|
||||
|
@ -239,35 +234,24 @@ Store::~Store() = default;
|
|||
bool
|
||||
Store::read_only() const
|
||||
{
|
||||
LOCKED;
|
||||
return !priv_->wdb();
|
||||
}
|
||||
|
||||
const std::string&
|
||||
Store::root_maildir () const
|
||||
{
|
||||
LOCKED;
|
||||
return priv_->root_maildir_;
|
||||
}
|
||||
|
||||
void
|
||||
Store::set_personal_addresses(const Store::Addresses& addresses)
|
||||
{
|
||||
LOCKED;
|
||||
priv_->set_personal_addresses (addresses);
|
||||
}
|
||||
|
||||
const Store::Addresses&
|
||||
const StringVec&
|
||||
Store::personal_addresses(void) const
|
||||
{
|
||||
LOCKED;
|
||||
return priv_->personal_addresses_;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
Store::database_path() const
|
||||
{
|
||||
LOCKED;
|
||||
return priv_->db_path_;
|
||||
}
|
||||
|
||||
|
@ -281,8 +265,6 @@ Store::contacts() const
|
|||
std::size_t
|
||||
Store::size() const
|
||||
{
|
||||
LOCKED;
|
||||
|
||||
return priv_->db()->get_doccount();
|
||||
}
|
||||
|
||||
|
@ -296,16 +278,12 @@ Store::empty() const
|
|||
const std::string&
|
||||
Store::schema_version() const
|
||||
{
|
||||
LOCKED;
|
||||
|
||||
return priv_->schema_version_;
|
||||
}
|
||||
|
||||
time_t
|
||||
Store::created() const
|
||||
{
|
||||
LOCKED;
|
||||
|
||||
return priv_->created_;
|
||||
}
|
||||
|
||||
|
@ -344,7 +322,7 @@ Store::add_message (const std::string& path)
|
|||
LOCKED;
|
||||
|
||||
GError *gerr{};
|
||||
const auto maildir{ maildir_from_path(root_maildir(), path)};
|
||||
const auto maildir{maildir_from_path(root_maildir(), path)};
|
||||
auto msg{mu_msg_new_from_file (path.c_str(), maildir.c_str(), &gerr)};
|
||||
if (G_UNLIKELY(!msg))
|
||||
throw Error{Error::Code::Message, "failed to create message: %s",
|
||||
|
@ -503,7 +481,7 @@ mu_store_new_readable (const char* xpath, GError **err)
|
|||
} catch (const Mu::Error& me) {
|
||||
if (me.code() == Mu::Error::Code::SchemaMismatch)
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN_NEEDS_REINDEX,
|
||||
"database @ %s needs (re)indexing", xpath);
|
||||
"read-only database @ %s needs (re)indexing", xpath);
|
||||
else
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN,
|
||||
"error opening database @ %s: %s", xpath, me.what());
|
||||
|
@ -533,13 +511,10 @@ mu_store_new_writable (const char* xpath, GError **err)
|
|||
} catch (const Mu::Error& me) {
|
||||
if (me.code() == Mu::Error::Code::SchemaMismatch)
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN_NEEDS_REINDEX,
|
||||
"database @ %s needs (re)indexing", xpath);
|
||||
"read/write database @ %s needs (re)indexing", xpath);
|
||||
else
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN,
|
||||
"error opening database @ %s: %s", xpath, me.what());
|
||||
// } catch (const Xapian::DatabaseNotFoundError& dbe) { // Xapian 1.4.10
|
||||
// g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN_NEEDS_REINDEX,
|
||||
// "database @ %s not found", xpath);
|
||||
} catch (const Xapian::DatabaseOpeningError& dbe) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN_NEEDS_REINDEX,
|
||||
"failed to open database @ %s", xpath);
|
||||
|
@ -555,16 +530,21 @@ mu_store_new_writable (const char* xpath, GError **err)
|
|||
}
|
||||
|
||||
MuStore*
|
||||
mu_store_new_create (const char* xpath, const char *maildir, GError **err)
|
||||
mu_store_new_create (const char* xpath, const char *root_maildir,
|
||||
const char **personal_addresses, GError **err)
|
||||
{
|
||||
g_return_val_if_fail (xpath, NULL);
|
||||
g_return_val_if_fail (maildir, NULL);
|
||||
g_return_val_if_fail (root_maildir, NULL);
|
||||
|
||||
g_debug ("create database at %s (maildir=%s)", xpath, maildir);
|
||||
g_debug ("create database at %s (root-maildir=%s)", xpath, root_maildir);
|
||||
|
||||
try {
|
||||
StringVec addrs;
|
||||
for (auto i = 0; personal_addresses && personal_addresses[i]; ++i)
|
||||
addrs.emplace_back(personal_addresses[i]);
|
||||
|
||||
return reinterpret_cast<MuStore*>(
|
||||
new Store (xpath, std::string{maildir}));
|
||||
new Store (xpath, std::string{root_maildir}, addrs));
|
||||
|
||||
} catch (const Xapian::DatabaseLockError& dle) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK,
|
||||
|
@ -648,7 +628,6 @@ mu_store_count (const MuStore *store, GError **err)
|
|||
(unsigned)-1);
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
mu_store_schema_version (const MuStore *store)
|
||||
{
|
||||
|
@ -760,7 +739,7 @@ mu_store_database_path (const MuStore *store)
|
|||
|
||||
|
||||
const char*
|
||||
mu_store_maildir (const MuStore *store)
|
||||
mu_store_root_maildir (const MuStore *store)
|
||||
{
|
||||
g_return_val_if_fail (store, NULL);
|
||||
|
||||
|
@ -776,24 +755,6 @@ mu_store_created (const MuStore *store)
|
|||
return self(store)->created();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
mu_store_set_personal_addresses (MuStore *store, const char **my_addresses)
|
||||
{
|
||||
g_return_if_fail (store);
|
||||
|
||||
if (!my_addresses)
|
||||
return;
|
||||
|
||||
Store::Addresses addrs;
|
||||
for (auto i = 0; my_addresses[i]; ++i)
|
||||
addrs.emplace_back(my_addresses[i]);
|
||||
|
||||
mutable_self(store)->set_personal_addresses (addrs);
|
||||
}
|
||||
|
||||
|
||||
char**
|
||||
mu_store_personal_addresses (const MuStore *store)
|
||||
{
|
||||
|
@ -807,7 +768,6 @@ mu_store_personal_addresses (const MuStore *store)
|
|||
return addrs;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mu_store_flush (MuStore *store) try {
|
||||
|
||||
|
@ -1088,7 +1048,7 @@ struct MsgDoc {
|
|||
Store *_store;
|
||||
/* callback data, to determine whether this message is 'personal' */
|
||||
gboolean _personal;
|
||||
const Addresses *_my_addresses;
|
||||
const StringVec *_my_addresses;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1360,26 +1320,34 @@ mu_store_update_msg (MuStore *store, unsigned docid, MuMsg *msg, GError **err)
|
|||
}
|
||||
|
||||
unsigned
|
||||
mu_store_add_path (MuStore *store, const char *path, const char *maildir,
|
||||
GError **err)
|
||||
{
|
||||
MuMsg *msg;
|
||||
unsigned docid;
|
||||
mu_store_add_path (MuStore *store, const char *path, GError **err) try {
|
||||
|
||||
g_return_val_if_fail (store, FALSE);
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
MuMsg *msg;
|
||||
unsigned docid;
|
||||
|
||||
msg = mu_msg_new_from_file (path, maildir, err);
|
||||
if (!msg)
|
||||
return MU_STORE_INVALID_DOCID;
|
||||
g_return_val_if_fail (store, FALSE);
|
||||
g_return_val_if_fail (path, FALSE);
|
||||
|
||||
docid = add_or_update_msg (store, 0, msg, err);
|
||||
mu_msg_unref (msg);
|
||||
const auto maildir{maildir_from_path(self(store)->root_maildir(), path)};
|
||||
msg = mu_msg_new_from_file (path, maildir.c_str(), err);
|
||||
if (!msg)
|
||||
return MU_STORE_INVALID_DOCID;
|
||||
|
||||
return docid;
|
||||
docid = add_or_update_msg (store, 0, msg, err);
|
||||
mu_msg_unref (msg);
|
||||
|
||||
return docid;
|
||||
|
||||
} catch (const Mu::Error& me) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_XAPIAN,
|
||||
"%s", me.what());
|
||||
return MU_STORE_INVALID_DOCID;
|
||||
} catch (...) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_INTERNAL,
|
||||
"caught exception");
|
||||
return MU_STORE_INVALID_DOCID;
|
||||
}
|
||||
|
||||
|
||||
XapianWritableDatabase*
|
||||
mu_store_get_writable_database (MuStore *store)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** Copyright (C) 2019 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the GNU General Public License as published by the
|
||||
|
@ -30,6 +30,8 @@
|
|||
#include <vector>
|
||||
#include <ctime>
|
||||
|
||||
#include <utils/mu-utils.hh>
|
||||
|
||||
namespace Mu {
|
||||
|
||||
class Store {
|
||||
|
@ -47,8 +49,11 @@ public:
|
|||
*
|
||||
* @param path path to the database
|
||||
* @param maildir maildir to use for this store
|
||||
* @param personal_addressesaddresses that should be recognized as
|
||||
* 'personal' for identifying personal messages.
|
||||
*/
|
||||
Store (const std::string& path, const std::string& maildir);
|
||||
Store (const std::string& path, const std::string& maildir,
|
||||
const StringVec& personal_addresses);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
|
@ -92,23 +97,12 @@ public:
|
|||
*/
|
||||
std::time_t created() const;
|
||||
|
||||
using Addresses = std::vector<std::string>;
|
||||
/**< A vec of email addresses (of the type foo@example.com, RFC-5322)*/
|
||||
|
||||
/**
|
||||
* Set addresses that should be recognized as 'personal'
|
||||
*
|
||||
* @param addresses
|
||||
*/
|
||||
void set_personal_addresses (const Addresses& addresses);
|
||||
|
||||
|
||||
/**
|
||||
* Get a vec with the personal addresses
|
||||
*
|
||||
* @return personal addresses
|
||||
*/
|
||||
const Addresses& personal_addresses() const;
|
||||
const StringVec& personal_addresses() const;
|
||||
|
||||
/**
|
||||
* Get the Contacts object for this store
|
||||
|
@ -263,13 +257,15 @@ MuStore* mu_store_new_writable (const char *xpath, GError **err)
|
|||
*
|
||||
* @param path the path to the database
|
||||
* @param path to the maildir
|
||||
* @param personal_addressesaddresses that should be recognized as
|
||||
* 'personal' for identifying personal messages.
|
||||
* @param err to receive error info or NULL. err->code is MuError value
|
||||
*
|
||||
* @return a new MuStore object with ref count == 1, or NULL in case
|
||||
* of error; free with mu_store_unref
|
||||
*/
|
||||
MuStore* mu_store_new_create (const char *xpath, const char *maildir,
|
||||
GError **err)
|
||||
const char **personal_addresses, GError **err)
|
||||
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
|
@ -346,13 +342,13 @@ const char *mu_store_database_path (const MuStore *store);
|
|||
|
||||
|
||||
/**
|
||||
* Get the maildir for this message store.
|
||||
* Get the root-maildir for this message store.
|
||||
*
|
||||
* @param store the store
|
||||
*
|
||||
* @return the maildir.
|
||||
*/
|
||||
const char *mu_store_maildir(const MuStore *store);
|
||||
const char *mu_store_root_maildir(const MuStore *store);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -364,20 +360,6 @@ const char *mu_store_maildir(const MuStore *store);
|
|||
*/
|
||||
time_t mu_store_created(const MuStore *store);
|
||||
|
||||
|
||||
/**
|
||||
* register a char** of email addresses as 'my' addresses, ie. mark
|
||||
* message that have these addresses in one of the address fields as
|
||||
* 'personal' (e.g., in mu-contacts). calling this function overrides
|
||||
* any 'my addresses' that were set before, using this function or
|
||||
* through mu_store_new_writable
|
||||
*
|
||||
* @param store a valid store object
|
||||
* @param my_addresses a char** of email addresses
|
||||
*/
|
||||
void mu_store_set_personal_addresses (MuStore *store,
|
||||
const char **my_addresses);
|
||||
|
||||
/**
|
||||
* Get the list of personal addresses from the store
|
||||
*
|
||||
|
@ -455,15 +437,12 @@ unsigned mu_store_update_msg (MuStore *store, unsigned docid, MuMsg *msg,
|
|||
*
|
||||
* @param store a valid store
|
||||
* @param path full filesystem path to a valid message
|
||||
* @param maildir set the maildir (e.g. "/drafts") for this message, or NULL
|
||||
* note that you cannot mu_msg_move_msg_to_maildir unless maildir is set.
|
||||
* @param err receives error information, if any, or NULL
|
||||
*
|
||||
* @return the docid of the stored message, or 0
|
||||
* (MU_STORE_INVALID_DOCID) in case of error
|
||||
*/
|
||||
unsigned mu_store_add_path (MuStore *store, const char *path,
|
||||
const char* maildir, GError **err);
|
||||
unsigned mu_store_add_path (MuStore *store, const char *path, GError **err);
|
||||
|
||||
/**
|
||||
* remove a message from the database based on its path
|
||||
|
|
|
@ -44,7 +44,7 @@ test_mu_store_new_destroy (void)
|
|||
g_assert (tmpdir);
|
||||
|
||||
err = NULL;
|
||||
store = mu_store_new_create (tmpdir, "/tmp", &err);
|
||||
store = mu_store_new_create (tmpdir, "/tmp", NULL, &err);
|
||||
g_assert_no_error (err);
|
||||
g_assert (store);
|
||||
|
||||
|
@ -68,7 +68,7 @@ test_mu_store_version (void)
|
|||
g_assert (tmpdir);
|
||||
|
||||
err = NULL;
|
||||
store = mu_store_new_create (tmpdir, "/tmp", &err);
|
||||
store = mu_store_new_create (tmpdir, "/tmp", NULL, &err);
|
||||
g_assert (store);
|
||||
mu_store_unref (store);
|
||||
store = mu_store_new_readable (tmpdir, &err);
|
||||
|
@ -95,7 +95,7 @@ test_mu_store_store_msg_and_count (void)
|
|||
tmpdir = test_mu_common_get_random_tmpdir();
|
||||
g_assert (tmpdir);
|
||||
|
||||
store = mu_store_new_create (tmpdir, MU_TESTMAILDIR, NULL);
|
||||
store = mu_store_new_create (tmpdir, MU_TESTMAILDIR, NULL, NULL);
|
||||
g_assert (store);
|
||||
g_free (tmpdir);
|
||||
|
||||
|
@ -152,7 +152,7 @@ test_mu_store_store_msg_remove_and_count (void)
|
|||
tmpdir = test_mu_common_get_random_tmpdir();
|
||||
g_assert (tmpdir);
|
||||
|
||||
store = mu_store_new_create (tmpdir, MU_TESTMAILDIR, NULL);
|
||||
store = mu_store_new_create (tmpdir, MU_TESTMAILDIR, NULL, NULL);
|
||||
g_assert (store);
|
||||
|
||||
g_assert_cmpuint (0,==,mu_store_count (store, NULL));
|
||||
|
|
|
@ -174,15 +174,6 @@ static inline std::string to_string (const T& val)
|
|||
*
|
||||
*/
|
||||
|
||||
#define MU_STORE_CATCH_BLOCK_RETURN(GE,R) \
|
||||
catch (const MuStoreError& merr) { \
|
||||
mu_util_g_set_error ((GE), \
|
||||
merr.mu_error(), "%s", \
|
||||
merr.what().c_str()); \
|
||||
return (R); \
|
||||
} \
|
||||
|
||||
|
||||
#define MU_XAPIAN_CATCH_BLOCK \
|
||||
catch (const Xapian::Error &xerr) { \
|
||||
g_critical ("%s: xapian error '%s'", \
|
||||
|
|
|
@ -279,7 +279,7 @@ index_title (MuStore *store, MuConfig *opts)
|
|||
#pragma GCC diagnostic pop
|
||||
g_print ("created : %s%s%s\n", green, tbuf, def);
|
||||
g_print ("maildir : %s%s%s\n",
|
||||
green, mu_store_maildir (store), def);
|
||||
green, mu_store_root_maildir (store), def);
|
||||
|
||||
g_print ("personal-addresses : ");
|
||||
|
||||
|
|
|
@ -222,8 +222,6 @@ message_options (const Parameters& params)
|
|||
return (MuMsgOptions)opts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 'add' adds a message to the database, and takes two parameters: 'path', which
|
||||
* is the full path to the message, and 'maildir', which is the maildir this
|
||||
* message lives in (e.g. "/inbox"). response with an (:info ...) message with
|
||||
|
@ -233,10 +231,9 @@ static void
|
|||
add_handler (Context& context, const Parameters& params)
|
||||
{
|
||||
const auto path{get_string_or(params, "path")};
|
||||
const auto maildir{get_string_or(params, "maildir")};
|
||||
|
||||
GError *gerr{};
|
||||
const auto docid{mu_store_add_path (context.store, path.c_str(), maildir.c_str(), &gerr)};
|
||||
const auto docid{mu_store_add_path (context.store, path.c_str(), &gerr)};
|
||||
if (docid == MU_STORE_INVALID_DOCID)
|
||||
throw Error(Error::Code::Store, &gerr, "failed to add message at %s",
|
||||
path.c_str());
|
||||
|
@ -1048,9 +1045,7 @@ sent_handler (Context& context, const Parameters& params)
|
|||
{
|
||||
GError *gerr{};
|
||||
const auto path{get_string_or(params, "path")};
|
||||
const auto docid{mu_store_add_path(context.store, path.c_str(),
|
||||
get_string_or(params, "maildir").c_str(),
|
||||
&gerr)};
|
||||
const auto docid{mu_store_add_path(context.store, path.c_str(), &gerr)};
|
||||
if (docid == MU_STORE_INVALID_DOCID)
|
||||
throw Error{Error::Code::Store, &gerr, "failed to add path"};
|
||||
|
||||
|
@ -1092,8 +1087,7 @@ make_command_map (Context& context)
|
|||
|
||||
cmap.emplace("add",
|
||||
CommandInfo{
|
||||
ArgMap{ {"path", ArgInfo{Type::String, true, "file system path to the message" }},
|
||||
{"maildir", ArgInfo{Type::String, true, "the maildir the where the message lives" }}},
|
||||
ArgMap{ {"path", ArgInfo{Type::String, true, "file system path to the message" }}},
|
||||
"add a message to the store",
|
||||
[&](const auto& params){add_handler(context, params);}});
|
||||
|
||||
|
|
72
mu/mu-cmd.c
72
mu/mu-cmd.c
|
@ -374,7 +374,7 @@ foreach_msg_file (MuStore *store, MuConfig *opts,
|
|||
static gboolean
|
||||
add_path_func (MuStore *store, const char *path, GError **err)
|
||||
{
|
||||
return mu_store_add_path (store, path, NULL, err);
|
||||
return mu_store_add_path (store, path, err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -569,17 +569,37 @@ show_usage (void)
|
|||
typedef MuError (*store_func) (MuStore *, MuConfig *, GError **err);
|
||||
|
||||
|
||||
static gboolean
|
||||
needs_rebuild (MuStore *store, MuConfig *opts, GError **err)
|
||||
static MuStore*
|
||||
get_store (MuConfig *opts, gboolean read_only, GError **err)
|
||||
{
|
||||
if (store)
|
||||
return mu_store_count(store, NULL) == 0;
|
||||
else
|
||||
return err &&
|
||||
(*err)->code == MU_ERROR_XAPIAN_NEEDS_REINDEX &&
|
||||
opts->maildir;
|
||||
if (opts->rebuild && read_only) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR,
|
||||
"cannot rebuild a read-only database");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (read_only)
|
||||
return mu_store_new_readable (
|
||||
mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), err);
|
||||
|
||||
if (!opts->rebuild)
|
||||
return mu_store_new_writable
|
||||
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), err);
|
||||
|
||||
if (!opts->maildir) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN,
|
||||
MU_ERROR_IN_PARAMETERS,
|
||||
"missing --maildir parameter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mu_store_new_create (mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||
opts->maildir,
|
||||
(const char**)opts->my_addresses,
|
||||
err);
|
||||
}
|
||||
|
||||
|
||||
static MuError
|
||||
with_store (store_func func, MuConfig *opts, gboolean read_only,
|
||||
GError **err)
|
||||
|
@ -587,42 +607,10 @@ with_store (store_func func, MuConfig *opts, gboolean read_only,
|
|||
MuStore *store;
|
||||
MuError merr;
|
||||
|
||||
if (opts->rebuild && read_only) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR,
|
||||
"cannot rebuild a read-only database");
|
||||
return MU_G_ERROR_CODE(err);
|
||||
}
|
||||
|
||||
if (read_only) {
|
||||
store = mu_store_new_readable (
|
||||
mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), err);
|
||||
} else if (!opts->rebuild) {
|
||||
store = mu_store_new_writable
|
||||
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), err);
|
||||
if (needs_rebuild (store, opts, err)) {
|
||||
if (store)
|
||||
mu_store_unref(store);
|
||||
opts->rebuild = TRUE;
|
||||
g_clear_error (err);
|
||||
return with_store(func, opts, read_only, err);
|
||||
}
|
||||
} else { /* rebuilding */
|
||||
if (!opts->maildir) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN,
|
||||
MU_ERROR_IN_PARAMETERS,
|
||||
"missing --maildir parameter");
|
||||
}
|
||||
store = mu_store_new_create
|
||||
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||
opts->maildir, err);
|
||||
}
|
||||
|
||||
store = get_store (opts, read_only, err);
|
||||
if (!store)
|
||||
return MU_G_ERROR_CODE(err);
|
||||
|
||||
if (!read_only && opts->my_addresses)
|
||||
mu_store_set_personal_addresses (
|
||||
store, (const char**)opts->my_addresses);
|
||||
|
||||
merr = func (store, opts, err);
|
||||
mu_store_unref (store);
|
||||
|
|
Loading…
Reference in New Issue