store/query: update for new store/query api

Update to the new API.
This commit is contained in:
Dirk-Jan C. Binnema 2022-01-30 14:33:25 +02:00
parent 5fc8a8f83e
commit ebc9b88f80
5 changed files with 62 additions and 82 deletions

View File

@ -78,15 +78,15 @@ struct _FlagData {
};
typedef struct _FlagData FlagData;
#define MU_GUILE_INITIALIZED_OR_ERROR \
do { \
if (!(mu_guile_initialized())) { \
mu_guile_error(FUNC_NAME, \
0, \
"mu not initialized; call mu:initialize", \
SCM_UNDEFINED); \
return SCM_UNSPECIFIED; \
} \
#define MU_GUILE_INITIALIZED_OR_ERROR \
do { \
if (!(mu_guile_initialized())) { \
mu_guile_error(FUNC_NAME, \
0, \
"mu not initialized; call mu:initialize", \
SCM_UNDEFINED); \
return SCM_UNSPECIFIED; \
} \
} while (0)
static void
@ -415,9 +415,7 @@ SCM_DEFINE(get_header,
static Mu::Option<Mu::QueryResults>
get_query_results(Mu::Store& store, const char* expr, int maxnum)
{
Mu::Query query(store);
return query.run(expr, MU_MSG_FIELD_ID_NONE, Mu::QueryFlags::None, maxnum);
return store.run_query(expr, MU_MSG_FIELD_ID_NONE, Mu::QueryFlags::None, maxnum);
}
SCM_DEFINE(for_each_message,

View File

@ -54,7 +54,7 @@ using namespace Command;
/// @brief object to manage the server-context for all commands.
struct Server::Private {
Private(Store& store, Output output)
: store_{store}, output_{output}, command_map_{make_command_map()}, query_{store_},
: store_{store}, output_{output}, command_map_{make_command_map()},
keep_going_{true}
{
}
@ -69,7 +69,6 @@ struct Server::Private {
const Store& store() const { return store_; }
Indexer& indexer() { return store().indexer(); }
const CommandMap& command_map() const { return command_map_; }
const Query& query() const { return query_; }
//
// invoke
@ -112,7 +111,7 @@ private:
MuMsgOptions opts) const;
Sexp::List
move_docid(Store::Id docid, const std::string& flagstr, bool new_name, bool no_view);
move_docid(Store::Id docid, const std::string& flagstr, bool new_name, bool no_view);
Sexp::List perform_move(Store::Id docid,
MuMsg* msg,
const std::string& maildirarg,
@ -121,13 +120,11 @@ private:
bool no_view);
bool maybe_mark_as_read(MuMsg* msg, Store::Id docid);
bool maybe_mark_msgid_as_read(const Mu::Query& query, const char* msgid);
Store& store_;
Server::Output output_;
const CommandMap command_map_;
const Query query_;
bool maybe_mark_msgid_as_read(const char* msgid);
Store& store_;
Server::Output output_;
const CommandMap command_map_;
std::atomic<bool> keep_going_{};
};
@ -336,7 +333,9 @@ Server::Private::make_command_map()
return cmap;
}
G_GNUC_PRINTF(2, 3) static Sexp make_error(Error::Code errcode, const char* frm, ...)
G_GNUC_PRINTF(2, 3)
static Sexp
make_error(Error::Code errcode, const char* frm, ...)
{
char* msg{};
va_list ap;
@ -540,7 +539,7 @@ Server::Private::contacts_handler(const Parameters& params)
/* get a *list* of all messages with the given message id */
static std::vector<Store::Id>
docids_for_msgid(const Query& q, const std::string& msgid, size_t max = 100)
docids_for_msgid(const Store& store, const std::string& msgid, size_t max = 100)
{
if (msgid.size() > Store::MaxTermLength) {
throw Error(Error::Code::InvalidArgument, "invalid message-id '%s'", msgid.c_str());
@ -553,7 +552,7 @@ docids_for_msgid(const Query& q, const std::string& msgid, size_t max = 100)
g_free(tmp);
GError* gerr{};
const auto res{q.run(expr, MU_MSG_FIELD_ID_NONE, QueryFlags::None, max)};
const auto res{store.run_query(expr, MU_MSG_FIELD_ID_NONE, QueryFlags::None, max)};
g_free(expr);
if (!res)
throw Error(Error::Code::Store, &gerr, "failed to run msgid-query");
@ -593,7 +592,7 @@ path_from_docid(const Store& store, unsigned docid)
}
static std::vector<Store::Id>
determine_docids(const Query& q, const Parameters& params)
determine_docids(const Store& store, const Parameters& params)
{
auto docid{get_int_or(params, ":docid", 0)};
const auto msgid{get_string_or(params, ":msgid")};
@ -605,7 +604,7 @@ determine_docids(const Query& q, const Parameters& params)
if (docid != 0)
return {(unsigned)docid};
else
return docids_for_msgid(q, msgid.c_str());
return docids_for_msgid(store, msgid.c_str());
}
size_t
@ -679,7 +678,7 @@ Server::Private::find_handler(const Parameters& params)
if (threads)
qflags |= QueryFlags::Threading;
auto qres{query().run(q, sort_field, qflags, maxnum)};
auto qres{store_.run_query(q, sort_field, qflags, maxnum)};
if (!qres)
throw Error(Error::Code::Query, "failed to run query");
@ -899,7 +898,7 @@ Server::Private::move_handler(const Parameters& params)
const auto flagstr{get_string_or(params, ":flags")};
const auto rename{get_bool_or(params, ":rename")};
const auto no_view{get_bool_or(params, ":noupdate")};
const auto docids{determine_docids(query(), params)};
const auto docids{determine_docids(store_, params)};
if (docids.size() > 1) {
if (!maildir.empty()) // ie. duplicate message-ids.
@ -955,9 +954,9 @@ Server::Private::ping_handler(const Parameters& params)
const auto queries = get_string_vec(params, ":queries");
Sexp::List qresults;
for (auto&& q : queries) {
const auto count{query().count(q)};
const auto count{store_.count_query(q)};
const auto unreadq{format("flag:unread AND (%s)", q.c_str())};
const auto unread{query().count(unreadq)};
const auto unread{store_.count_query(unreadq)};
Sexp::List lst;
lst.add_prop(":query", Sexp::make_string(q));
@ -1067,12 +1066,12 @@ Server::Private::maybe_mark_as_read(MuMsg* msg, Store::Id docid)
}
bool
Server::Private::maybe_mark_msgid_as_read(const Mu::Query& query, const char* msgid)
Server::Private::maybe_mark_msgid_as_read(const char* msgid)
{
if (!msgid)
return false; // nothing to do.
const auto docids{docids_for_msgid(query, std::string{msgid})};
const auto docids{docids_for_msgid(store_, std::string{msgid})};
for (auto&& docid : docids) {
MuMsg* msg = store().find_message(docid);
if (!msg)
@ -1102,7 +1101,7 @@ Server::Private::view_handler(const Parameters& params)
docid = Store::InvalidId;
msg = mu_msg_new_from_file(path.c_str(), NULL, &gerr);
} else {
docid = determine_docids(query(), params).at(0);
docid = determine_docids(store(), params).at(0);
msg = store().find_message(docid);
}
@ -1113,7 +1112,7 @@ Server::Private::view_handler(const Parameters& params)
// maybe mark the main message as read.
maybe_mark_as_read(msg, docid);
/* maybe mark _all_ messsage with same message-id as read */
maybe_mark_msgid_as_read(query(), mu_msg_get_msgid(msg));
maybe_mark_msgid_as_read(mu_msg_get_msgid(msg));
}
Sexp::List seq;

View File

@ -59,18 +59,17 @@ test_query()
item.message_id().value_or("<none>").c_str());
};
Query q{store};
g_assert_cmpuint(store.size(), ==, 19);
{
const auto res = q.run("", MU_MSG_FIELD_ID_NONE, QueryFlags::None);
const auto res = store.run_query("", MU_MSG_FIELD_ID_NONE, QueryFlags::None);
g_assert_true(!!res);
g_assert_cmpuint(res->size(), ==, 19);
dump_matches(*res);
}
{
const auto res = q.run("", MU_MSG_FIELD_ID_PATH, QueryFlags::None, 11);
const auto res = store.run_query("", MU_MSG_FIELD_ID_PATH, QueryFlags::None, 11);
g_assert_true(!!res);
g_assert_cmpuint(res->size(), ==, 11);
dump_matches(*res);

View File

@ -57,13 +57,14 @@ constexpr auto LastOutput{OutputInfo{0, false, true}};
using OutputFunc = std::function<bool(MuMsg*, const OutputInfo&, const MuConfig*, GError**)>;
static gboolean
print_internal(const Query& query,
print_internal(const Store& store,
const std::string& expr,
gboolean xapian,
gboolean warn,
GError** err)
{
std::cout << query.parse(expr, xapian) << "\n";
std::cout << store.parse_query(expr, xapian) << "\n";
return TRUE;
}
@ -88,7 +89,7 @@ sort_field_from_string(const char* fieldstr, GError** err)
}
static Option<QueryResults>
run_query(const Query& q, const std::string& expr, const MuConfig* opts, GError** err)
run_query(const Store& store, const std::string& expr, const MuConfig* opts, GError** err)
{
MuMsgFieldId sortid;
@ -109,7 +110,7 @@ run_query(const Query& q, const std::string& expr, const MuConfig* opts, GError*
if (opts->threads)
qflags |= QueryFlags::Threading;
return q.run(expr, sortid, qflags, opts->maxnum);
return store.run_query(expr, sortid, qflags, opts->maxnum);
}
static gboolean
@ -196,20 +197,6 @@ get_query(const MuConfig* opts, GError** err)
return q;
}
static Mu::Query
get_query_obj(const Store& store, GError** err)
{
const auto count{store.size()};
if (count == (unsigned)-1)
throw Mu::Error(Error::Code::Store, "invalid store");
if (count == 0)
throw Mu::Error(Error::Code::Store, "store is empty");
return Mu::Query{store};
}
static gboolean
prepare_links(const MuConfig* opts, GError** err)
{
@ -391,7 +378,9 @@ thread_indent(const QueryMatch& info, const MuConfig* opts)
::fputs("/", stdout);
else
::fputs(" ", stdout);
::fputs(empty_parent ? "*> " : is_dup ? "=> " : "-> ", stdout);
::fputs(empty_parent ? "*> " : is_dup ? "=> "
: "-> ",
stdout);
}
}
@ -616,9 +605,9 @@ output_query_results(const QueryResults& qres, const MuConfig* opts, GError** er
}
static gboolean
process_query(const Query& q, const std::string& expr, const MuConfig* opts, GError** err)
process_query(const Store& store, const std::string& expr, const MuConfig* opts, GError** err)
{
auto qres{run_query(q, expr, opts, err)};
auto qres{run_query(store, expr, opts, err)};
if (!qres)
return FALSE;
@ -633,17 +622,16 @@ process_query(const Query& q, const std::string& expr, const MuConfig* opts, GEr
static gboolean
execute_find(const Store& store, const MuConfig* opts, GError** err)
{
auto q{get_query_obj(store, err)};
auto expr{get_query(opts, err)};
if (!expr)
return FALSE;
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
return print_internal(q, *expr, TRUE, FALSE, err);
return print_internal(store, *expr, TRUE, FALSE, err);
else if (opts->format == MU_CONFIG_FORMAT_MQUERY)
return print_internal(q, *expr, FALSE, opts->verbose, err);
return print_internal(store, *expr, FALSE, opts->verbose, err);
else
return process_query(q, *expr, opts, err);
return process_query(store, *expr, opts, err);
}
static gboolean

View File

@ -91,16 +91,15 @@ run_and_count_matches(const std::string& xpath,
Mu::QueryFlags flags = Mu::QueryFlags::None)
{
Mu::Store store{xpath};
Mu::Query query{store};
if (g_test_verbose()) {
std::cout << "==> mquery: " << query.parse(expr, false) << "\n";
std::cout << "==> xquery: " << query.parse(expr, true) << "\n";
std::cout << "==> mquery: " << store.parse_query(expr, false) << "\n";
std::cout << "==> xquery: " << store.parse_query(expr, true) << "\n";
}
Mu::allow_warnings();
auto qres{query.run(expr, MU_MSG_FIELD_ID_NONE, flags)};
auto qres{store.run_query(expr, MU_MSG_FIELD_ID_NONE, flags)};
g_assert_true(!!qres);
assert_no_dups(*qres);
@ -236,9 +235,8 @@ static void
test_mu_query_accented_chars_01(void)
{
Store store{DB_PATH1};
Query q{store};
auto qres{q.run("fünkÿ")};
auto qres{store.run_query("fünkÿ")};
g_assert_true(!!qres);
g_assert_false(qres->empty());
@ -571,31 +569,29 @@ test_mu_query_cjk(void)
g_unsetenv("XAPIAN_CJK_NGRAM");
const auto xpath = make_database(MU_TESTMAILDIR_CJK);
g_assert_cmpuint(run_and_count_matches(xpath,
"サーバがダウンしました",
QueryFlags::None),
==, 1);
"サーバがダウンしました",
QueryFlags::None),
==, 1);
g_assert_cmpuint(run_and_count_matches(xpath,
"サーバ",
QueryFlags::None),
==, 0);
"サーバ",
QueryFlags::None),
==, 0);
}
{
g_setenv("XAPIAN_CJK_NGRAM", "1", TRUE);
const auto xpath = make_database(MU_TESTMAILDIR_CJK);
g_assert_cmpuint(run_and_count_matches(xpath,
"サーバがダウンしました",
QueryFlags::None),
==, 0);
"サーバがダウンしました",
QueryFlags::None),
==, 0);
g_assert_cmpuint(run_and_count_matches(xpath,
"サーバ",
QueryFlags::None),
==, 0);
"サーバ",
QueryFlags::None),
==, 0);
}
}
int
main(int argc, char* argv[])
{