From: Timo Sirainen Date: Tue, 17 Nov 2020 12:24:57 +0000 (+0200) Subject: dict, dict-client: Support dict_iterate_values() X-Git-Tag: 2.3.14.rc1~328 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1c4cef0099aaf384b0a586c69ad02f66b0771f03;p=thirdparty%2Fdovecot%2Fcore.git dict, dict-client: Support dict_iterate_values() This doesn't change the dict client protocol in an incompatible way, so it's possible to mix old/new client/server. --- diff --git a/src/dict/dict-commands.c b/src/dict/dict-commands.c index e7eaa1c339..327cb6550d 100644 --- a/src/dict/dict-commands.c +++ b/src/dict/dict-commands.c @@ -270,7 +270,7 @@ cmd_iterate_flush_finish(struct dict_connection_cmd *cmd, string_t *str) static int cmd_iterate_flush(struct dict_connection_cmd *cmd) { string_t *str = t_str_new(256); - const char *key, *value; + const char *key, *const *values; if (cmd->conn->destroyed) { cmd_iterate_flush_finish(cmd, str); @@ -280,7 +280,7 @@ static int cmd_iterate_flush(struct dict_connection_cmd *cmd) if (!dict_connection_flush_if_full(cmd->conn)) return 0; - while (dict_iterate(cmd->iter, &key, &value)) { + while (dict_iterate_values(cmd->iter, &key, &values)) { cmd->rows++; str_truncate(str, 0); if (cmd->async_reply_id != 0) { @@ -290,8 +290,13 @@ static int cmd_iterate_flush(struct dict_connection_cmd *cmd) str_append_c(str, DICT_PROTOCOL_REPLY_OK); str_append_tabescaped(str, key); str_append_c(str, '\t'); - if ((cmd->iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0) - str_append_tabescaped(str, value); + if ((cmd->iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0) { + str_append_tabescaped(str, values[0]); + for (unsigned int i = 1; values[i] != NULL; i++) { + str_append_c(str, '\t'); + str_append_tabescaped(str, values[i]); + } + } str_append_c(str, '\n'); o_stream_nsend(cmd->conn->conn.output, str_data(str), str_len(str)); diff --git a/src/lib-dict/dict-client.c b/src/lib-dict/dict-client.c index f247921e47..546bcf4f9b 100644 --- a/src/lib-dict/dict-client.c +++ b/src/lib-dict/dict-client.c @@ -92,7 +92,7 @@ struct client_dict { }; struct client_dict_iter_result { - const char *key, *value; + const char *key, *const *values; }; struct client_dict_iterate_context { @@ -105,7 +105,6 @@ struct client_dict_iterate_context { pool_t results_pool; ARRAY(struct client_dict_iter_result) results; unsigned int result_idx; - const char *values[2]; bool cmd_sent; bool seen_results; @@ -1083,7 +1082,7 @@ client_dict_iter_async_callback(struct client_dict_cmd *cmd, struct client_dict_iterate_context *ctx = cmd->iter; struct client_dict *dict = cmd->dict; struct client_dict_iter_result *result; - const char *iter_key = NULL, *iter_value = NULL; + const char *iter_key = NULL, *const *iter_values = NULL; if (ctx->deinit) { cmd->background = TRUE; @@ -1103,7 +1102,7 @@ client_dict_iter_async_callback(struct client_dict_cmd *cmd, case DICT_PROTOCOL_REPLY_OK: /* key \t value */ iter_key = value; - iter_value = extra_args[0]; + iter_values = extra_args; extra_args++; break; case DICT_PROTOCOL_REPLY_FAIL: @@ -1112,7 +1111,7 @@ client_dict_iter_async_callback(struct client_dict_cmd *cmd, default: break; } - if (iter_value == NULL && error == NULL) { + if ((iter_values == NULL || iter_values[0] == NULL) && error == NULL) { /* broken protocol */ error = t_strdup_printf("dict client (%s) sent broken iterate reply: %c%s", dict->conn.conn.name, reply, value); @@ -1137,7 +1136,7 @@ client_dict_iter_async_callback(struct client_dict_cmd *cmd, result = array_append_space(&ctx->results); result->key = p_strdup(ctx->results_pool, iter_key); - result->value = p_strdup(ctx->results_pool, iter_value); + result->values = p_strarray_dup(ctx->results_pool, iter_values); client_dict_iter_api_callback(ctx, cmd, NULL); } @@ -1200,8 +1199,7 @@ static bool client_dict_iterate(struct dict_iterate_context *_ctx, results = array_get(&ctx->results, &count); if (ctx->result_idx < count) { *key_r = results[ctx->result_idx].key; - ctx->values[0] = results[ctx->result_idx].value; - *values_r = ctx->values; + *values_r = results[ctx->result_idx].values; ctx->ctx.has_more = TRUE; ctx->result_idx++; ctx->seen_results = TRUE;