]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dict, dict-client: Support dict_iterate_values()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 17 Nov 2020 12:24:57 +0000 (14:24 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 23 Nov 2020 12:04:46 +0000 (12:04 +0000)
This doesn't change the dict client protocol in an incompatible way, so it's
possible to mix old/new client/server.

src/dict/dict-commands.c
src/lib-dict/dict-client.c

index e7eaa1c339b860f7725514d0b0343de7910f98b6..327cb6550d39a859b98cf2febe2a8fcdf811f0f3 100644 (file)
@@ -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));
 
index f247921e4784680ad2a12170670d63e94a25be7b..546bcf4f9b597a25880a7af86b99df9ca6c00202 100644 (file)
@@ -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;