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

@ -415,9 +415,7 @@ SCM_DEFINE(get_header,
static Mu::Option<Mu::QueryResults> static Mu::Option<Mu::QueryResults>
get_query_results(Mu::Store& store, const char* expr, int maxnum) get_query_results(Mu::Store& store, const char* expr, int maxnum)
{ {
Mu::Query query(store); return store.run_query(expr, MU_MSG_FIELD_ID_NONE, Mu::QueryFlags::None, maxnum);
return query.run(expr, MU_MSG_FIELD_ID_NONE, Mu::QueryFlags::None, maxnum);
} }
SCM_DEFINE(for_each_message, SCM_DEFINE(for_each_message,

View File

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

View File

@ -59,18 +59,17 @@ test_query()
item.message_id().value_or("<none>").c_str()); item.message_id().value_or("<none>").c_str());
}; };
Query q{store};
g_assert_cmpuint(store.size(), ==, 19); 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_true(!!res);
g_assert_cmpuint(res->size(), ==, 19); g_assert_cmpuint(res->size(), ==, 19);
dump_matches(*res); 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_true(!!res);
g_assert_cmpuint(res->size(), ==, 11); g_assert_cmpuint(res->size(), ==, 11);
dump_matches(*res); 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**)>; using OutputFunc = std::function<bool(MuMsg*, const OutputInfo&, const MuConfig*, GError**)>;
static gboolean static gboolean
print_internal(const Query& query, print_internal(const Store& store,
const std::string& expr, const std::string& expr,
gboolean xapian, gboolean xapian,
gboolean warn, gboolean warn,
GError** err) GError** err)
{ {
std::cout << query.parse(expr, xapian) << "\n"; std::cout << store.parse_query(expr, xapian) << "\n";
return TRUE; return TRUE;
} }
@ -88,7 +89,7 @@ sort_field_from_string(const char* fieldstr, GError** err)
} }
static Option<QueryResults> 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; MuMsgFieldId sortid;
@ -109,7 +110,7 @@ run_query(const Query& q, const std::string& expr, const MuConfig* opts, GError*
if (opts->threads) if (opts->threads)
qflags |= QueryFlags::Threading; qflags |= QueryFlags::Threading;
return q.run(expr, sortid, qflags, opts->maxnum); return store.run_query(expr, sortid, qflags, opts->maxnum);
} }
static gboolean static gboolean
@ -196,20 +197,6 @@ get_query(const MuConfig* opts, GError** err)
return q; 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 static gboolean
prepare_links(const MuConfig* opts, GError** err) prepare_links(const MuConfig* opts, GError** err)
{ {
@ -391,7 +378,9 @@ thread_indent(const QueryMatch& info, const MuConfig* opts)
::fputs("/", stdout); ::fputs("/", stdout);
else else
::fputs(" ", stdout); ::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 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) if (!qres)
return FALSE; return FALSE;
@ -633,17 +622,16 @@ process_query(const Query& q, const std::string& expr, const MuConfig* opts, GEr
static gboolean static gboolean
execute_find(const Store& store, const MuConfig* opts, GError** err) execute_find(const Store& store, const MuConfig* opts, GError** err)
{ {
auto q{get_query_obj(store, err)};
auto expr{get_query(opts, err)}; auto expr{get_query(opts, err)};
if (!expr) if (!expr)
return FALSE; return FALSE;
if (opts->format == MU_CONFIG_FORMAT_XQUERY) 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) 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 else
return process_query(q, *expr, opts, err); return process_query(store, *expr, opts, err);
} }
static gboolean static gboolean

View File

@ -91,16 +91,15 @@ run_and_count_matches(const std::string& xpath,
Mu::QueryFlags flags = Mu::QueryFlags::None) Mu::QueryFlags flags = Mu::QueryFlags::None)
{ {
Mu::Store store{xpath}; Mu::Store store{xpath};
Mu::Query query{store};
if (g_test_verbose()) { if (g_test_verbose()) {
std::cout << "==> mquery: " << query.parse(expr, false) << "\n"; std::cout << "==> mquery: " << store.parse_query(expr, false) << "\n";
std::cout << "==> xquery: " << query.parse(expr, true) << "\n"; std::cout << "==> xquery: " << store.parse_query(expr, true) << "\n";
} }
Mu::allow_warnings(); 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); g_assert_true(!!qres);
assert_no_dups(*qres); assert_no_dups(*qres);
@ -236,9 +235,8 @@ static void
test_mu_query_accented_chars_01(void) test_mu_query_accented_chars_01(void)
{ {
Store store{DB_PATH1}; 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_true(!!qres);
g_assert_false(qres->empty()); g_assert_false(qres->empty());
@ -580,7 +578,6 @@ test_mu_query_cjk(void)
==, 0); ==, 0);
} }
{ {
g_setenv("XAPIAN_CJK_NGRAM", "1", TRUE); g_setenv("XAPIAN_CJK_NGRAM", "1", TRUE);
const auto xpath = make_database(MU_TESTMAILDIR_CJK); const auto xpath = make_database(MU_TESTMAILDIR_CJK);
@ -595,7 +592,6 @@ test_mu_query_cjk(void)
} }
} }
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {