diff --git a/src/mu-cmd-find.c b/src/mu-cmd-find.c index 1476b5c4..001a94a4 100644 --- a/src/mu-cmd-find.c +++ b/src/mu-cmd-find.c @@ -35,7 +35,6 @@ #include "mu-util.h" #include "mu-util-xapian.h" - #include "mu-cmd-find.h" @@ -50,7 +49,7 @@ update_warning (void) static gboolean -print_query (MuQueryXapian *xapian, const gchar *query) +print_xapian_query (MuQueryXapian *xapian, const gchar *query) { char *querystr; @@ -117,135 +116,72 @@ sort_field_from_string (const char* fieldstr) return field; } -static gboolean -print_rows (MuQueryXapian *xapian, const gchar *query, MuConfigOptions *opts) +static size_t +print_rows (MuMsgIterXapian *iter, const char *fields) { - MuMsgIterXapian *iter; - const MuMsgField *sortfield; - - MU_WRITE_LOG ("query: '%s' (iters)", query); + size_t count = 0; + const char* myfields; - sortfield = NULL; - if (opts->sortfield) { - sortfield = sort_field_from_string (opts->sortfield); - if (!sortfield) /* error occured? */ - return FALSE; - } - - iter = mu_query_xapian_run (xapian, query, sortfield, - !opts->descending, - 0); - if (!iter) { - g_printerr ("error: running query failed\n"); - return FALSE; - } else if (mu_msg_iter_xapian_is_done (iter)) { - g_printerr ("No matches found\n"); - mu_msg_iter_xapian_destroy (iter); - return FALSE; - } + do { + int len = 0; - /* iterate over the found iters */ - do { - const char* fields = opts->fields; - int printlen = 0; - - while (*fields) { - + myfields = fields; + while (*myfields) { const MuMsgField* field; - field = mu_msg_field_from_shortcut (*fields); - if (!field || - !mu_msg_field_is_xapian_enabled (field)) - printlen += printf ("%c", *fields); + field = mu_msg_field_from_shortcut (*myfields); + if (!field || !mu_msg_field_is_xapian_enabled (field)) + len += printf ("%c", *myfields); else - printlen += - printf ("%s", - display_field(iter, field)); - ++fields; + len += printf ("%s", + display_field(iter, field)); + ++myfields; } - if (printlen > 0) - printf ("\n"); - - mu_msg_iter_xapian_next (iter); - - } while (!mu_msg_iter_xapian_is_done (iter)); - - mu_msg_iter_xapian_destroy (iter); + if (len > 0) + g_print ("\n"); - return TRUE; + ++count; + + } while (mu_msg_iter_xapian_next (iter)); + + return count; } - -static gboolean -do_output_text (MuQueryXapian *xapian, MuConfigOptions* opts, - const gchar **params) -{ - gchar *query; - gboolean retval = TRUE; - - query = mu_query_xapian_combine (params, FALSE); - - /* if xquery is set, we print the xapian query instead of the - * output; this is for debugging purposes */ - if (opts->xquery) - retval = print_query (xapian, query); - else - retval = print_rows (xapian, query, opts); - - g_free (query); - - return retval; -} - - /* create a linksdir if it not exist yet; if it already existed, * remove old links if opts->clearlinks was specified */ static gboolean -create_or_clear_linksdir_maybe (MuConfigOptions* opts) +create_or_clear_linksdir_maybe (const char *linksdir, gboolean clearlinks) { - if (access (opts->linksdir, F_OK) != 0) { - if (!mu_maildir_mkmdir (opts->linksdir, 0700, TRUE)) + if (access (linksdir, F_OK) != 0) { + if (!mu_maildir_mkmdir (linksdir, 0700, TRUE)) return FALSE; - } else if (opts->clearlinks) - mu_maildir_clear_links (opts->linksdir); + } else if (clearlinks) + mu_maildir_clear_links (linksdir); return TRUE; } -static gboolean -do_output_links (MuQueryXapian *xapian, MuConfigOptions* opts, - const gchar **params) -{ - gchar *query; - gboolean retval = TRUE; - MuMsgIterXapian *iter; - const MuMsgField *pathfield; - if (!create_or_clear_linksdir_maybe (opts)) - return FALSE; +static size_t +make_links (MuMsgIterXapian *iter, const char* linksdir, gboolean clearlinks) +{ + size_t count = 0; + const MuMsgField *pathfield; - query = mu_query_xapian_combine (params, FALSE); - - MU_WRITE_LOG ("query: '%s' (links)", query); - iter = mu_query_xapian_run (xapian, query, NULL, FALSE, 0); - if (!iter) { - g_printerr ("error: running query failed\n"); - return FALSE; - } else if (mu_msg_iter_xapian_is_done (iter)) { - g_printerr ("No matches found\n"); - mu_msg_iter_xapian_destroy (iter); - return FALSE; - } + if (!create_or_clear_linksdir_maybe (linksdir, clearlinks)) + return 0; pathfield = mu_msg_field_from_id (MU_MSG_FIELD_ID_PATH); /* iterate over the found iters */ - for (; !mu_msg_iter_xapian_is_done (iter); - mu_msg_iter_xapian_next (iter)) { - + do { const char *path; + /* there's no data in the iter */ + if (mu_msg_iter_xapian_is_null (iter)) + return count; + path = mu_msg_iter_xapian_get_field (iter, pathfield); if (!path) continue; @@ -257,17 +193,77 @@ do_output_links (MuQueryXapian *xapian, MuConfigOptions* opts, continue; } - if (!mu_maildir_link (path, opts->linksdir)) + if (!mu_maildir_link (path, linksdir)) break; + ++count; + } while (mu_msg_iter_xapian_next (iter)); + + return count; +} + + + +static gboolean +run_query (MuQueryXapian *xapian, const gchar *query, MuConfigOptions *opts) +{ + MuMsgIterXapian *iter; + const MuMsgField *sortfield; + size_t matches; + + MU_WRITE_LOG ("query: '%s'", query); + + sortfield = NULL; + if (opts->sortfield) { + sortfield = sort_field_from_string (opts->sortfield); + if (!sortfield) /* error occured? */ + return FALSE; } + iter = mu_query_xapian_run (xapian, query, sortfield, + !opts->descending, 0); + if (!iter) { + g_printerr ("error: running query failed\n"); + return FALSE; + } + + if (opts->linksdir) + matches = make_links (iter, opts->linksdir, opts->clearlinks); + else + matches = print_rows (iter, opts->fields); + + if (matches == 0) + g_printerr ("No matches found\n"); mu_msg_iter_xapian_destroy (iter); + + return matches > 0; +} + + + +static gboolean +do_output (MuQueryXapian *xapian, MuConfigOptions* opts, + const gchar **params) +{ + gchar *query; + gboolean retval = TRUE; + + query = mu_query_xapian_combine (params, FALSE); + + /* if xquery is set, we print the xapian query instead of the + * output; this is for debugging purposes */ + if (opts->xquery) + retval = print_xapian_query (xapian, query); + else + retval = run_query (xapian, query, opts); + g_free (query); return retval; } + + static gboolean query_params_valid (MuConfigOptions *opts) { @@ -326,10 +322,7 @@ mu_cmd_find (MuConfigOptions *opts) return FALSE; } - if (opts->linksdir) - rv = do_output_links (xapian, opts, params); - else - rv = do_output_text (xapian, opts, params); + rv = do_output (xapian, opts, params); mu_query_xapian_destroy (xapian); mu_msg_gmime_uninit(); @@ -347,6 +340,3 @@ mu_cmd_view (MuConfigOptions *opts) return TRUE; /* FIXME */ } - - - diff --git a/src/mu-cmd-index.c b/src/mu-cmd-index.c index 2ebd11a9..7ea167f2 100644 --- a/src/mu-cmd-index.c +++ b/src/mu-cmd-index.c @@ -146,10 +146,21 @@ database_version_check_and_update (MuConfigOptions *opts) return FALSE; } + +static MuResult +run_cleanup (MuIndex *midx, MuIndexStats *stats, gboolean quiet) +{ + mu_index_stats_clear (stats); + return mu_index_cleanup (midx, stats, + quiet ? index_msg_silent_cb : index_msg_cb, + NULL); +} + + gboolean mu_cmd_cleanup (MuConfigOptions *opts) { - int rv; + MuResult rv; MuIndex *midx; MuIndexStats stats; @@ -165,31 +176,46 @@ mu_cmd_cleanup (MuConfigOptions *opts) g_warning ("Cleanup failed"); return FALSE; } + g_message ("Cleaning up removed messages from %s", opts->xpath); + rv = run_cleanup (midx, &stats, opts->quiet); - mu_index_stats_clear (&stats); - rv = mu_index_cleanup (midx, &stats, - opts->quiet ? index_msg_silent_cb : index_msg_cb, - NULL); mu_index_destroy (midx); if (!opts->quiet) g_print ("\n"); - if (rv == MU_OK || rv == MU_STOP) - return TRUE; - else - return FALSE; + return (rv == MU_OK || rv == MU_STOP) ? TRUE: FALSE; +} + +static MuResult +run_index (MuIndex *midx, const char* maildir, MuIndexStats *stats, + gboolean reindex, gboolean quiet) +{ + MuResult rv; + + mu_index_stats_clear (stats); + mu_msg_gmime_init (); + + rv = mu_index_run (midx, maildir, reindex, stats, + quiet ? index_msg_silent_cb :index_msg_cb, + NULL, NULL); + + mu_msg_gmime_init (); + + return rv; } gboolean mu_cmd_index (MuConfigOptions *opts) { - int rv; - + gboolean rv; + MuIndex *midx; + MuIndexStats stats; + g_return_val_if_fail (opts, FALSE); if (!check_index_params (opts)) @@ -200,51 +226,26 @@ mu_cmd_index (MuConfigOptions *opts) install_sig_handler (); - mu_msg_gmime_init (); - { - MuIndex *midx; - MuIndexStats stats; - - mu_index_stats_clear (&stats); - midx = mu_index_new (opts->xpath); - - if (!midx) { - g_warning ("Indexing failed"); - return FALSE; - } + midx = mu_index_new (opts->xpath); + if (!midx) { + g_warning ("Indexing failed"); + return FALSE; + } - g_message ("Indexing messages from %s", opts->maildir); - g_message ("Database: %s", opts->xpath); - - rv = mu_index_run (midx, opts->maildir, - opts->reindex, &stats, - opts->quiet ? - index_msg_silent_cb :index_msg_cb, - NULL, NULL); - if (!opts->nocleanup && !MU_CAUGHT_SIGNAL) { - stats._processed = 0; /* start over */ - if (!opts->quiet) - g_print ("\n"); - g_message ("Cleaning up missing messages"); - mu_index_cleanup (midx, &stats, - opts->quiet ? - index_msg_silent_cb : index_msg_cb, - NULL); - } - - if (!opts->quiet) { - index_msg_cb (&stats, NULL); - g_print ("\n"); - } - - MU_WRITE_LOG ("processed: %d; updated/new: %d, " - "cleaned-up: %d", - stats._processed, stats._updated, - stats._cleaned_up); - - mu_index_destroy (midx); - } - mu_msg_gmime_uninit (); + g_message ("Indexing messages from %s", opts->maildir); + g_message ("Database: %s", opts->xpath); - return rv == MU_OK ? TRUE : FALSE; + rv = run_index (midx, opts->maildir, &stats, opts->reindex, opts->quiet); + if (rv == MU_OK && !opts->nocleanup) + rv = run_cleanup (midx, &stats, opts->quiet); + + mu_index_destroy (midx); + + MU_WRITE_LOG ("processed: %d; updated/new: %d, cleaned-up: %d", + stats._processed, stats._updated,stats._cleaned_up); + + if (!opts->quiet) + g_print ("\n"); + + return (rv == MU_OK || rv == MU_STOP) ? TRUE: FALSE; } diff --git a/src/mu-msg-iter-xapian.cc b/src/mu-msg-iter-xapian.cc index e70ae66d..820a24e0 100644 --- a/src/mu-msg-iter-xapian.cc +++ b/src/mu-msg-iter-xapian.cc @@ -33,6 +33,7 @@ struct _MuMsgIterXapian { size_t _batchsize; size_t _offset; char* _str[MU_MSG_FIELD_ID_NUM]; + bool _is_null; }; @@ -48,8 +49,11 @@ mu_msg_iter_xapian_new (const Xapian::Enquire& enq, size_t batchsize) iter->_enq = new Xapian::Enquire(enq); iter->_matches = iter->_enq->get_mset (0, batchsize); - if (!iter->_matches.empty()) + if (!iter->_matches.empty()) { iter->_cursor = iter->_matches.begin(); + iter->_is_null = false; + } else + iter->_is_null = true; iter->_batchsize = batchsize; iter->_offset = 0; @@ -94,11 +98,14 @@ get_next_batch (MuMsgIterXapian *iter) { iter->_matches = iter->_enq->get_mset (iter->_offset, iter->_batchsize); - if (iter->_matches.empty()) + if (iter->_matches.empty()) { iter->_cursor = iter->_matches.end(); - else + iter->_is_null = true; + } else { iter->_cursor = iter->_matches.begin(); - + iter->_is_null = false; + } + return iter; } @@ -106,7 +113,6 @@ gboolean mu_msg_iter_xapian_next (MuMsgIterXapian *iter) { g_return_val_if_fail (iter, FALSE); - g_return_val_if_fail (!mu_msg_iter_xapian_is_done(iter), FALSE); try { ++iter->_offset; @@ -136,17 +142,11 @@ mu_msg_iter_xapian_next (MuMsgIterXapian *iter) gboolean -mu_msg_iter_xapian_is_done (MuMsgIterXapian *iter) +mu_msg_iter_xapian_is_null (MuMsgIterXapian *iter) { g_return_val_if_fail (iter, TRUE); - if (iter->_matches.empty()) - return TRUE; - - if (iter->_cursor == iter->_matches.end()) - return TRUE; - - return FALSE; + return iter->_is_null; } @@ -154,7 +154,7 @@ const gchar* mu_msg_iter_xapian_get_field (MuMsgIterXapian *iter, const MuMsgField *field) { g_return_val_if_fail (iter, NULL); - g_return_val_if_fail (!mu_msg_iter_xapian_is_done(iter), NULL); + g_return_val_if_fail (!mu_msg_iter_xapian_is_null(iter), NULL); g_return_val_if_fail (field, NULL); try { diff --git a/src/mu-msg-iter-xapian.h b/src/mu-msg-iter-xapian.h index c83e3bb9..076477a8 100644 --- a/src/mu-msg-iter-xapian.h +++ b/src/mu-msg-iter-xapian.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS struct _MuMsgIterXapian; typedef struct _MuMsgIterXapian MuMsgIterXapian; + /** * get the next next message (which you got from * e.g. mu_query_xapian_run) @@ -38,15 +39,15 @@ typedef struct _MuMsgIterXapian MuMsgIterXapian; */ gboolean mu_msg_iter_xapian_next (MuMsgIterXapian *iter); + /** - * are there any message left? together with mu_msg_iter_xapian_next, this - * function can be used to iterate over query results. + * does the iter point to a real message? * - * @param msg a valid MuMsgIterXapian message + * @param msg a valid MuMsgIterXapian iter * - * @return TRUE if there are messages left, FALSE otherwise + * @return TRUE if the iterator points to a message, FALSE other */ -gboolean mu_msg_iter_xapian_is_done (MuMsgIterXapian *iter); +gboolean mu_msg_iter_xapian_is_null (MuMsgIterXapian *iter); /** * destroy the sequence of messages diff --git a/src/tests/test-mu-query.c b/src/tests/test-mu-query.c index 6016991e..0a15f6df 100644 --- a/src/tests/test-mu-query.c +++ b/src/tests/test-mu-query.c @@ -104,12 +104,13 @@ test_mu_query_01 (void) int count; MuMsgIterXapian *iter; - iter = mu_query_xapian_run (query, queries[i].query, NULL, FALSE, 0); + iter = mu_query_xapian_run (query, queries[i].query, NULL, FALSE, 1); count = 0; - while (!mu_msg_iter_xapian_is_done (iter)) { - mu_msg_iter_xapian_next (iter); - ++count; + if (!mu_msg_iter_xapian_is_null (iter)) { + do { + ++count; + } while (mu_msg_iter_xapian_next (iter)); } g_assert_cmpuint (queries[i].count, ==, count);