From 2f9dd78bb003b0e589c015ff05ea4024b995dc76 Mon Sep 17 00:00:00 2001 From: djcb Date: Sun, 16 Dec 2012 15:08:34 +0200 Subject: [PATCH] * add query flags (which match msgiterflags) to mu_query_run, update callers --- guile/mu-guile-message.c | 4 +-- lib/mu-container.c | 12 +++---- lib/mu-query.cc | 70 ++++++++++++++++++++---------------- lib/mu-query.h | 20 +++++++---- lib/mu-threader.c | 4 +-- mu/mu-cmd-find.c | 10 ++++-- mu/mu-cmd-server.c | 21 +++++++---- mu/tests/test-mu-query.c | 8 ++--- mu/tests/test-mu-threads.c | 4 +-- toys/mug/mug-msg-list-view.c | 10 ++++-- 10 files changed, 100 insertions(+), 63 deletions(-) diff --git a/guile/mu-guile-message.c b/guile/mu-guile-message.c index e1d57b95..37e53c4d 100644 --- a/guile/mu-guile-message.c +++ b/guile/mu-guile-message.c @@ -432,8 +432,8 @@ get_query_iter (MuQuery *query, const char* expr, int maxnum) GError *err; err = NULL; - iter = mu_query_run (query, expr, - FALSE, MU_MSG_FIELD_ID_NONE, TRUE, maxnum, &err); + iter = mu_query_run (query, expr, MU_MSG_FIELD_ID_NONE, maxnum, + MU_QUERY_FLAG_NONE, &err); if (!iter) { mu_guile_g_error ("", err); g_clear_error (&err); diff --git a/lib/mu-container.c b/lib/mu-container.c index c2a676a3..fc88db5f 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -312,7 +312,7 @@ mu_container_from_list (GSList *lst) struct _SortFuncData { MuMsgFieldId mfid; - gboolean revert; + gboolean descending; gpointer user_data; }; typedef struct _SortFuncData SortFuncData; @@ -335,7 +335,7 @@ sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) else if (!b1->msg) return -1; - if (data->revert) + if (data->descending) return mu_msg_cmp (b1->msg, a1->msg, data->mfid); else return mu_msg_cmp (a1->msg, b1->msg, data->mfid); @@ -367,14 +367,14 @@ container_sort_real (MuContainer *c, SortFuncData *sfdata) MuContainer* -mu_container_sort (MuContainer *c, MuMsgFieldId mfid, gboolean revert, +mu_container_sort (MuContainer *c, MuMsgFieldId mfid, gboolean descending, gpointer user_data) { SortFuncData sfdata; - sfdata.mfid = mfid; - sfdata.revert = revert; - sfdata.user_data = user_data; + sfdata.mfid = mfid; + sfdata.descending = descending; + sfdata.user_data = user_data; g_return_val_if_fail (c, NULL); g_return_val_if_fail (mu_msg_field_id_is_valid(mfid), NULL); diff --git a/lib/mu-query.cc b/lib/mu-query.cc index 85c1ffe5..c0a00db8 100644 --- a/lib/mu-query.cc +++ b/lib/mu-query.cc @@ -342,38 +342,38 @@ mu_query_preprocess (const char *query, GError **err) * exception is raised. We try to reopen the database, and run the * query again. */ static MuMsgIter * -try_requery (MuQuery *self, const char* searchexpr, gboolean threads, - MuMsgFieldId sortfieldid, gboolean revert, int maxnum, - GError **err) +try_requery (MuQuery *self, const char* searchexpr, MuMsgFieldId sortfieldid, + int maxnum, MuQueryFlags flags, GError **err) { try { /* let's assume that infinite regression is * impossible */ self->db().reopen(); MU_WRITE_LOG ("reopening db after modification"); - return mu_query_run (self, searchexpr, threads, sortfieldid, - revert, maxnum, err); + return mu_query_run (self, searchexpr, sortfieldid, + maxnum, flags, err); } MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN (err, MU_ERROR_XAPIAN, 0); } static Xapian::Enquire -get_enquire (MuQuery *self, const char *searchexpr, gboolean threads, - MuMsgFieldId sortfieldid, gboolean revert, GError **err) +get_enquire (MuQuery *self, const char *searchexpr, MuMsgFieldId sortfieldid, + MuQueryFlags flags, GError **err) { Xapian::Enquire enq (self->db()); if (sortfieldid != MU_MSG_FIELD_ID_NONE) - enq.set_sort_by_value ((Xapian::valueno)sortfieldid, - revert ? true : false); + enq.set_sort_by_value + ((Xapian::valueno)sortfieldid, + (flags & MU_QUERY_FLAG_DESCENDING) ? true : false); /* empty or "" means "matchall" */ if (!mu_str_is_empty(searchexpr) && g_strcmp0 (searchexpr, "\"\"") != 0) /* NULL or "" or """" */ - enq.set_query(get_query (self, searchexpr, err)); - else - enq.set_query(Xapian::Query::MatchAll); + enq.set_query(get_query (self, searchexpr, err)); + else + enq.set_query(Xapian::Query::MatchAll); enq.set_cutoff(0,0); @@ -381,10 +381,29 @@ get_enquire (MuQuery *self, const char *searchexpr, gboolean threads, } +static MuMsgIterFlags +msg_iter_flags (MuQueryFlags flags) +{ + MuMsgIterFlags iflags; + + iflags = MU_MSG_ITER_FLAG_NONE; + + if (flags & MU_QUERY_FLAG_THREADS) + iflags |= MU_MSG_ITER_FLAG_THREADS; + if (flags & MU_QUERY_FLAG_DESCENDING) + iflags |= MU_MSG_ITER_FLAG_DESCENDING; + if (flags & MU_QUERY_FLAG_SKIP_UNREADABLE) + iflags |= MU_MSG_ITER_FLAG_SKIP_UNREADABLE; + if (flags & MU_QUERY_FLAG_SKIP_MSGID_DUPS) + iflags |= MU_MSG_ITER_FLAG_SKIP_MSGID_DUPS; + + return iflags; +} + + MuMsgIter* -mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads, - MuMsgFieldId sortfieldid, gboolean revert, int maxnum, - GError **err) +mu_query_run (MuQuery *self, const char* searchexpr, MuMsgFieldId sortfieldid, + int maxnum, MuQueryFlags flags, GError **err) { g_return_val_if_fail (self, NULL); g_return_val_if_fail (searchexpr, NULL); @@ -393,16 +412,8 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads, NULL); try { MuMsgIter *iter; - Xapian::Enquire enq (get_enquire(self, searchexpr, threads, - sortfieldid, revert, err)); - MuMsgIterFlags flags; - - flags = MU_MSG_ITER_FLAG_NONE; - if (threads) - flags |= MU_MSG_ITER_FLAG_THREADS; - if (revert) - flags |= MU_MSG_ITER_FLAG_REVERT; - + Xapian::Enquire enq (get_enquire(self, searchexpr, sortfieldid, flags, + err)); /* get the 'real' maxnum if it was specified as < 0 */ maxnum <= 0 ? self->db().get_doccount() : maxnum; @@ -412,15 +423,14 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads, maxnum, /* in we were *not* using threads, no further sorting * is needed since Xapian already sorted */ - threads ? sortfieldid : MU_MSG_FIELD_ID_NONE, - flags, + (flags & MU_QUERY_FLAG_THREADS) ? sortfieldid : MU_MSG_FIELD_ID_NONE, + msg_iter_flags (flags), err); if (err && *err && (*err)->code == MU_ERROR_XAPIAN_MODIFIED) { g_clear_error (err); - return try_requery (self, searchexpr, threads, - sortfieldid, - revert, maxnum, err); + return try_requery (self, searchexpr, sortfieldid, + maxnum, flags, err); } else return iter; diff --git a/lib/mu-query.h b/lib/mu-query.h index ee5054f8..be7f11bb 100644 --- a/lib/mu-query.h +++ b/lib/mu-query.h @@ -64,19 +64,28 @@ void mu_query_destroy (MuQuery *self); char* mu_query_version (MuQuery *store) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + +enum _MuQueryFlags { + MU_QUERY_FLAG_NONE = 0, + + MU_QUERY_FLAG_THREADS = 1 << 0, /* <** add threading info */ + MU_QUERY_FLAG_DESCENDING = 1 << 1, /* <** sort z->a */ + MU_QUERY_FLAG_SKIP_UNREADABLE = 1 << 2, /* <** skip unreadable msgs */ + MU_QUERY_FLAG_SKIP_MSGID_DUPS = 1 << 3 /* <** skip msgid dups */ +}; +typedef enum _MuQueryFlags MuQueryFlags; + /** * run a Xapian query; for the syntax, please refer to the mu-find * manpage, or http://xapian.org/docs/queryparser.html * * @param self a valid MuQuery instance * @param expr the search expression; use "" to match all messages - * @param threads calculate message-threads * @param sortfield the field id to sort by or MU_MSG_FIELD_ID_NONE if * sorting is not desired - * @param reverse if TRUE, sort in descending (Z-A) order, otherwise, - * sort in descending (A-Z) order * @param maxnum maximum number of search results to return, or <= 0 for * unlimited + * @param flags bitwise OR'd flags to influence the query (see MuQueryFlags) * @param err receives error information (if there is any); if * function returns non-NULL, err will _not_be set. err can be NULL * possible error (err->code) is MU_ERROR_QUERY, @@ -84,9 +93,8 @@ char* mu_query_version (MuQuery *store) * @return a MuMsgIter instance you can iterate over, or NULL in * case of error */ -MuMsgIter* mu_query_run (MuQuery *self, const char* expr, gboolean threads, - MuMsgFieldId sortfieldid, gboolean ascending, int maxnum, - GError **err) +MuMsgIter* mu_query_run (MuQuery *self, const char* expr, MuMsgFieldId sortfieldid, int maxnum, + MuQueryFlags flags, GError **err) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; diff --git a/lib/mu-threader.c b/lib/mu-threader.c index 46660831..4e1fddea 100644 --- a/lib/mu-threader.c +++ b/lib/mu-threader.c @@ -59,7 +59,7 @@ GHashTable* create_doc_id_thread_path_hash (MuContainer *root, * http://www.jwz.org/doc/threading.html */ GHashTable* mu_threader_calculate (MuMsgIter *iter, size_t matchnum, - MuMsgFieldId sortfield, gboolean revert) + MuMsgFieldId sortfield, gboolean descending) { GHashTable *id_table, *thread_ids; MuContainer *root_set; @@ -82,7 +82,7 @@ mu_threader_calculate (MuMsgIter *iter, size_t matchnum, /* sort root set */ if (sortfield != MU_MSG_FIELD_ID_NONE) - root_set = mu_container_sort (root_set, sortfield, revert, + root_set = mu_container_sort (root_set, sortfield, descending, NULL); /* step 5: group root set by subject */ diff --git a/mu/mu-cmd-find.c b/mu/mu-cmd-find.c index d350f925..6f1b5267 100644 --- a/mu/mu-cmd-find.c +++ b/mu/mu-cmd-find.c @@ -113,6 +113,7 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err) { MuMsgIter *iter; MuMsgFieldId sortid; + MuQueryFlags qflags; sortid = MU_MSG_FIELD_ID_NONE; if (opts->sortfield) { @@ -121,8 +122,13 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err) return FALSE; } - iter = mu_query_run (xapian, query, opts->threads, sortid, - opts->reverse, -1, err); + qflags = MU_QUERY_FLAG_NONE; + if (opts->threads) + qflags |= MU_QUERY_FLAG_THREADS; + if (opts->reverse) + qflags |= MU_QUERY_FLAG_DESCENDING; + + iter = mu_query_run (xapian, query, sortid, -1, qflags, err); return iter; } diff --git a/mu/mu-cmd-server.c b/mu/mu-cmd-server.c index 815f3c54..7c3911f9 100644 --- a/mu/mu-cmd-server.c +++ b/mu/mu-cmd-server.c @@ -266,8 +266,9 @@ get_docid_from_msgid (MuQuery *query, const char *str, GError **err) MuMsgIter *iter; querystr = g_strdup_printf ("msgid:%s", str); - iter = mu_query_run (query, querystr, FALSE, - MU_MSG_FIELD_ID_NONE, FALSE, 1, err); + iter = mu_query_run (query, querystr, + MU_MSG_FIELD_ID_NONE, + 1, MU_QUERY_FLAG_NONE, err); g_free (querystr); docid = MU_STORE_INVALID_DOCID; @@ -300,8 +301,8 @@ get_docids_from_msgids (MuQuery *query, const char *str, GError **err) GSList *lst; querystr = g_strdup_printf ("msgid:%s", str); - iter = mu_query_run (query, querystr, FALSE, - MU_MSG_FIELD_ID_NONE, FALSE,-1 /*unlimited*/, + iter = mu_query_run (query, querystr, MU_MSG_FIELD_ID_NONE, + -1 /*unlimited*/, MU_QUERY_FLAG_NONE, err); g_free (querystr); @@ -889,6 +890,7 @@ cmd_find (ServerContext *ctx, GSList *args, GError **err) gboolean threads, reverse; MuMsgFieldId sortfield; const char *querystr; + MuQueryFlags qflags; GET_STRING_OR_ERROR_RETURN (args, "query", &querystr, err); if (get_find_params (args, &threads, &sortfield, @@ -900,9 +902,14 @@ cmd_find (ServerContext *ctx, GSList *args, GError **err) /* note: when we're threading, we get *all* matching messages, * and then only return maxnum; this is so that we maximimize * the change of all messages in a thread showing up */ - iter = mu_query_run (ctx->query, querystr, threads, - sortfield, reverse, - threads ? -1 : maxnum, err); + qflags = MU_QUERY_FLAG_NONE; + if (threads) + qflags |= MU_QUERY_FLAG_THREADS; + if (reverse) + qflags |= MU_QUERY_FLAG_DESCENDING; + + iter = mu_query_run (ctx->query, querystr, sortfield, + threads ? -1 : maxnum, qflags, err); if (!iter) { print_and_clear_g_error (err); return MU_OK; diff --git a/mu/tests/test-mu-query.c b/mu/tests/test-mu-query.c index 8bca3ac7..9e7d6e8b 100644 --- a/mu/tests/test-mu-query.c +++ b/mu/tests/test-mu-query.c @@ -130,8 +130,8 @@ run_and_count_matches (const char *xpath, const char *query) } - iter = mu_query_run (mquery, query, FALSE, MU_MSG_FIELD_ID_NONE, - FALSE, -1, NULL); + iter = mu_query_run (mquery, query, MU_MSG_FIELD_ID_NONE, -1, + MU_QUERY_FLAG_NONE, NULL); mu_query_destroy (mquery); g_assert (iter); @@ -295,8 +295,8 @@ test_mu_query_accented_chars_01 (void) query = mu_query_new (store, NULL); mu_store_unref (store); - iter = mu_query_run (query, "fünkÿ", FALSE, MU_MSG_FIELD_ID_NONE, - FALSE, -1, NULL); + iter = mu_query_run (query, "fünkÿ", MU_MSG_FIELD_ID_NONE, + -1, MU_QUERY_FLAG_NONE, NULL); err = NULL; msg = mu_msg_iter_get_msg_floating (iter); /* don't unref */ if (!msg) { diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index 4310de97..b39723a6 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -70,8 +70,8 @@ run_and_get_iter (const char *xpath, const char *query) mu_store_unref (store); g_assert (query); - iter = mu_query_run (mquery, query, TRUE, MU_MSG_FIELD_ID_DATE, - FALSE, -1, NULL); + iter = mu_query_run (mquery, query, MU_MSG_FIELD_ID_DATE, + -1, MU_QUERY_FLAG_THREADS, NULL); mu_query_destroy (mquery); g_assert (iter); diff --git a/toys/mug/mug-msg-list-view.c b/toys/mug/mug-msg-list-view.c index a4afa34e..931b6521 100644 --- a/toys/mug/mug-msg-list-view.c +++ b/toys/mug/mug-msg-list-view.c @@ -327,6 +327,7 @@ run_query (const char *xpath, const char *query, MugMsgListView * self) MuQuery *xapian; MuMsgIter *iter; MuStore *store; + MuQueryFlags qflags; err = NULL; if (! (store = mu_store_new_read_only (xpath, &err)) || @@ -342,8 +343,13 @@ run_query (const char *xpath, const char *query, MugMsgListView * self) } mu_store_unref (store); - iter = mu_query_run (xapian, query, TRUE, MU_MSG_FIELD_ID_DATE, - TRUE, -1, &err); + qflags = MU_QUERY_FLAG_THREADS | + MU_QUERY_FLAG_DESCENDING | + MU_QUERY_FLAG_SKIP_UNREADABLE | + MU_QUERY_FLAG_SKIP_MSGID_DUPS; + + iter = mu_query_run (xapian, query, MU_MSG_FIELD_ID_DATE, + -1, qflags, &err); mu_query_destroy (xapian); if (!iter) { g_warning ("Error: %s", err->message);