diff --git a/lib/mu-server.cc b/lib/mu-server.cc index 282344ec..0997ec90 100644 --- a/lib/mu-server.cc +++ b/lib/mu-server.cc @@ -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 -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 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(docid)}; else - return docids_for_msgid(store, msgid.c_str()); + return unwrap(store.find_docids_with_message_id(msgid)); } size_t diff --git a/lib/mu-server.hh b/lib/mu-server.hh index 95837216..3153457f 100644 --- a/lib/mu-server.hh +++ b/lib/mu-server.hh @@ -1,5 +1,5 @@ /* -** Copyright (C) 2020 Dirk-Jan C. Binnema +** Copyright (C) 2020-2023 Dirk-Jan C. Binnema ** ** 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: diff --git a/lib/mu-store.cc b/lib/mu-store.cc index ddcd2eba..ed3be7e9 100644 --- a/lib/mu-store.cc +++ b/lib/mu-store.cc @@ -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 +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::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) { diff --git a/lib/mu-store.hh b/lib/mu-store.hh index bdfdf713..73dea822 100644 --- a/lib/mu-store.hh +++ b/lib/mu-store.hh @@ -271,6 +271,18 @@ public: */ Option find_message(Id id) const; + using IdVec = std::vector; + + /** + * 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 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 *