]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dict-client: Forward dict_iterate_set_limit() to dict server
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 10 Nov 2016 21:00:59 +0000 (23:00 +0200)
committerGitLab <gitlab@git.dovecot.net>
Fri, 11 Nov 2016 12:03:41 +0000 (14:03 +0200)
src/dict/dict-commands.c
src/lib-dict/dict-client.c

index 9c0cf30d9f5f7d081aa7a0b6a55eb2e25578e9a4..75c1d769f7995d2ac8564e2b6310f27942e2dfba 100644 (file)
@@ -194,18 +194,22 @@ static int cmd_iterate(struct dict_connection_cmd *cmd, const char *line)
 {
        const char *const *args;
        unsigned int flags;
+       uint64_t max_rows;
 
        args = t_strsplit_tabescaped(line);
-       if (str_array_length(args) < 2 ||
-           str_to_uint(args[0], &flags) < 0) {
+       if (str_array_length(args) < 3 ||
+           str_to_uint(args[0], &flags) < 0 ||
+           str_to_uint64(args[1], &max_rows) < 0) {
                i_error("dict client: ITERATE: broken input");
                return -1;
        }
 
-       /* <flags> <path> */
+       /* <flags> <max_rows> <path> */
        flags |= DICT_ITERATE_FLAG_ASYNC;
-       cmd->iter = dict_iterate_init_multiple(cmd->conn->dict, args+1, flags);
+       cmd->iter = dict_iterate_init_multiple(cmd->conn->dict, args+2, flags);
        cmd->iter_flags = flags;
+       if (max_rows > 0)
+               dict_iterate_set_limit(cmd->iter, max_rows);
        dict_iterate_set_async_callback(cmd->iter, cmd_iterate_callback, cmd);
        dict_connection_cmd_output_more(cmd);
        return 1;
index 3c75047fb5c72a9902741a0dbe812a0fb35dac94..ab2655372513aca94103490f74a47e0ca2df330b 100644 (file)
@@ -89,12 +89,14 @@ struct client_dict_iter_result {
 struct client_dict_iterate_context {
        struct dict_iterate_context ctx;
        char *error;
+       const char **paths;
        enum dict_iterate_flags flags;
 
        pool_t results_pool;
        ARRAY(struct client_dict_iter_result) results;
        unsigned int result_idx;
 
+       bool cmd_sent;
        bool seen_results;
        bool finished;
        bool deinit;
@@ -956,22 +958,32 @@ static struct dict_iterate_context *
 client_dict_iterate_init(struct dict *_dict, const char *const *paths,
                         enum dict_iterate_flags flags)
 {
-       struct client_dict *dict = (struct client_dict *)_dict;
         struct client_dict_iterate_context *ctx;
-       struct client_dict_cmd *cmd;
-       string_t *query = t_str_new(256);
-       unsigned int i;
 
        ctx = i_new(struct client_dict_iterate_context, 1);
        ctx->ctx.dict = _dict;
        ctx->results_pool = pool_alloconly_create("client dict iteration", 512);
        ctx->flags = flags;
+       ctx->paths = p_strarray_dup(system_pool, paths);
        i_array_init(&ctx->results, 64);
+       return &ctx->ctx;
+}
+
+static void
+client_dict_iterate_cmd_send(struct client_dict_iterate_context *ctx)
+{
+       struct client_dict *dict = (struct client_dict *)ctx->ctx.dict;
+       struct client_dict_cmd *cmd;
+       unsigned int i;
+       string_t *query = t_str_new(256);
 
-       str_printfa(query, "%c%d", DICT_PROTOCOL_CMD_ITERATE, flags);
-       for (i = 0; paths[i] != NULL; i++) {
+       /* we can't do this query in _iterate_init(), because
+          _set_limit() hasn't been called yet at that point. */
+       str_printfa(query, "%c%d\t%llu", DICT_PROTOCOL_CMD_ITERATE, ctx->flags,
+                   (unsigned long long)ctx->ctx.max_rows);
+       for (i = 0; ctx->paths[i] != NULL; i++) {
                str_append_c(query, '\t');
-                       str_append(query, str_tabescape(paths[i]));
+               str_append(query, str_tabescape(ctx->paths[i]));
        }
 
        cmd = client_dict_cmd_init(dict, str_c(query));
@@ -980,7 +992,6 @@ client_dict_iterate_init(struct dict *_dict, const char *const *paths,
        cmd->retry_errors = TRUE;
 
        client_dict_cmd_send(dict, &cmd, NULL);
-       return &ctx->ctx;
 }
 
 static bool client_dict_iterate(struct dict_iterate_context *_ctx,
@@ -1005,6 +1016,11 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx,
                ctx->seen_results = TRUE;
                return TRUE;
        }
+       if (!ctx->cmd_sent) {
+               ctx->cmd_sent = TRUE;
+               client_dict_iterate_cmd_send(ctx);
+               return client_dict_iterate(_ctx, key_r, value_r);
+       }
        ctx->ctx.has_more = !ctx->finished;
        ctx->result_idx = 0;
        array_clear(&ctx->results);
@@ -1030,6 +1046,7 @@ static int client_dict_iterate_deinit(struct dict_iterate_context *_ctx,
        *error_r = t_strdup(ctx->error);
        array_free(&ctx->results);
        pool_unref(&ctx->results_pool);
+       i_free(ctx->paths);
        client_dict_iterate_free(ctx);
 
        client_dict_add_timeout(dict);