store/server: centralize docids-for-msgid

No need for two near-identical impls

Remove some dead declarations.
This commit is contained in:
Dirk-Jan C. Binnema 2023-07-09 23:20:32 +03:00
parent 0b4f7c4cbe
commit 18490a818d
4 changed files with 45 additions and 57 deletions

View File

@ -535,39 +535,6 @@ Server::Private::contacts_handler(const Command& cmd)
output_sexp(seq, Server::OutputFlags::SplitList);
}
/* get a *list* of all messages with the given message id */
static std::vector<Store::Id>
docids_for_msgid(const Store& store, const std::string& msgid, size_t max = 100)
{
if (msgid.size() > MaxTermLength) {
throw Error(Error::Code::InvalidArgument, "invalid message-id '{}'", msgid);
} else if (msgid.empty())
return {};
const auto xprefix{field_from_id(Field::Id::MessageId).shortcut};
/*XXX this is a bit dodgy */
auto tmp{g_ascii_strdown(msgid.c_str(), -1)};
auto expr{g_strdup_printf("%c:%s", xprefix, tmp)};
g_free(tmp);
GError* gerr{};
std::lock_guard l{store.lock()};
const auto res{store.run_query(expr, {}, QueryFlags::None, max)};
g_free(expr);
if (!res)
throw Error(Error::Code::Store, &gerr,
"failed to run message-id-query: {}", res.error().what());
else if (res->empty())
throw Error(Error::Code::NotFound,
"could not find message(s) for msgid {}", msgid);
std::vector<Store::Id> docids{};
for (auto&& mi : *res)
docids.emplace_back(mi.doc_id());
return docids;
}
/*
* creating a message object just to get a path seems a bit excessive maybe
* mu_store_get_path could be added if this turns out to be a problem
@ -599,7 +566,7 @@ determine_docids(const Store& store, const Command& cmd)
if (docid != 0)
return {static_cast<Store::Id>(docid)};
else
return docids_for_msgid(store, msgid.c_str());
return unwrap(store.find_docids_with_message_id(msgid));
}
size_t

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2020-2023 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,8 +30,7 @@
namespace Mu {
/**
* @brief Implements the mu server, as used by mu4e.
*
* @brief Implements the mu server, as used by mu4e.
*/
class Server {
public:

View File

@ -423,8 +423,6 @@ Store::Private::move_message_unlocked(Message&& msg,
return Ok(std::move(msg));
}
/* get a vec of all messages with the given message id */
static Store::IdMessageVec
messages_with_msgid(const Store& store, const std::string& msgid, size_t max=100)
@ -460,6 +458,36 @@ messages_with_msgid(const Store& store, const std::string& msgid, size_t max=100
}
static Result<std::string>
message_id_query(const std::string& msgid)
{
if (msgid.empty())
return Err(Error::Code::InvalidArgument, "empty message-id");
else if (msgid.size() > MaxTermLength)
return Err(Error::Code::InvalidArgument, "message-id too long");
else
return Ok(mu_format("{}:{}", field_from_id(Field::Id::MessageId).shortcut, msgid));
}
Result<Store::IdVec>
Store::find_docids_with_message_id(const std::string& msgid) const
{
std::lock_guard guard{priv_->lock_};
if (auto&& query{message_id_query(msgid)}; !query)
return Err(std::move(query.error()));
else if (auto&& res{run_query(*query)}; !res)
return Err(std::move(res.error()));
else {
Store::IdVec ids;
for (auto&& mi: *res)
ids.emplace_back(mi.doc_id());
return Ok(std::move(ids));
}
}
static Flags
filter_dup_flags(Flags old_flags, Flags new_flags)
{

View File

@ -271,6 +271,18 @@ public:
*/
Option<Message> find_message(Id id) const;
using IdVec = std::vector<Id>;
/**
* Get the doc-ids for messages with the given message-id
*
* @param msg_id a message id
* @param max_results maximum number of results
*
* @return either an Error or a vector of docids
*/
Result<IdVec> find_docids_with_message_id(const std::string& msg_id) const;
/**
* does a certain message exist in the store already?
*
@ -353,24 +365,6 @@ public:
*/
size_t for_each_term(Field::Id id, ForEachTermFunc func) const;
/**
* Get the store metadata for @p key
*
* @param key the metadata key
*
* @return the metadata value or empty for none.
*/
std::string metadata(const std::string& key) const;
/**
* Write metadata to the store.
*
* @param key key
* @param val value
*/
void set_metadata(const std::string& key, const std::string& val);
/**
* Get the timestamp for some message, or 0 if not found
*