From 217683437468663839ec9bb6c7d2892b98fae4f9 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 12 Jan 2017 20:35:12 +0200 Subject: [PATCH] dict-client: Support multiple values for lookups --- src/dict/dict-commands.c | 28 ++++++++++++++++++++++++++-- src/lib-dict/dict-client.c | 5 +++++ src/lib-dict/dict-client.h | 5 ++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/dict/dict-commands.c b/src/dict/dict-commands.c index c4f2e8216f..4fe78572ac 100644 --- a/src/dict/dict-commands.c +++ b/src/dict/dict-commands.c @@ -162,6 +162,31 @@ dict_cmd_reply_handle_timings(struct dict_connection_cmd *cmd, (unsigned int)ioloop_timeval.tv_usec); } +static void +cmd_lookup_write_reply(struct dict_connection_cmd *cmd, + const char *const *values, string_t *str) +{ + string_t *tmp; + + i_assert(values[0] != NULL); + + if (cmd->conn->minor_version < DICT_CLIENT_PROTOCOL_VERSION_MIN_MULTI_OK || + values[1] == NULL) { + str_append_c(str, DICT_PROTOCOL_REPLY_OK); + str_append_tabescaped(str, values[0]); + return; + } + /* the results get double-tabescaped so they end up becoming a single + parameter */ + tmp = t_str_new(128); + for (unsigned int i = 0; values[i] != NULL; i++) { + str_append_c(tmp, '\t'); + str_append_tabescaped(tmp, values[i]); + } + str_append_c(str, DICT_PROTOCOL_REPLY_MULTI_OK); + str_append_tabescaped(str, str_c(tmp) + 1); +} + static void cmd_lookup_callback(const struct dict_lookup_result *result, void *context) { @@ -169,8 +194,7 @@ cmd_lookup_callback(const struct dict_lookup_result *result, void *context) string_t *str = t_str_new(128); if (result->ret > 0) { - str_append_c(str, DICT_PROTOCOL_REPLY_OK); - str_append_tabescaped(str, result->value); + cmd_lookup_write_reply(cmd, result->values, str); } else if (result->ret == 0) { str_append_c(str, DICT_PROTOCOL_REPLY_NOTFOUND); } else { diff --git a/src/lib-dict/dict-client.c b/src/lib-dict/dict-client.c index a72506c53d..158fed1363 100644 --- a/src/lib-dict/dict-client.c +++ b/src/lib-dict/dict-client.c @@ -938,6 +938,11 @@ client_dict_lookup_async_callback(struct client_dict_cmd *cmd, result.values = values; result.ret = 1; break; + case DICT_PROTOCOL_REPLY_MULTI_OK: + result.values = t_strsplit_tabescaped(value); + result.value = result.values[0]; + result.ret = 1; + break; case DICT_PROTOCOL_REPLY_NOTFOUND: result.ret = 0; break; diff --git a/src/lib-dict/dict-client.h b/src/lib-dict/dict-client.h index 47028342ba..dfd391a2fb 100644 --- a/src/lib-dict/dict-client.h +++ b/src/lib-dict/dict-client.h @@ -6,7 +6,9 @@ #define DEFAULT_DICT_SERVER_SOCKET_FNAME "dict" #define DICT_CLIENT_PROTOCOL_MAJOR_VERSION 2 -#define DICT_CLIENT_PROTOCOL_MINOR_VERSION 1 +#define DICT_CLIENT_PROTOCOL_MINOR_VERSION 2 + +#define DICT_CLIENT_PROTOCOL_VERSION_MIN_MULTI_OK 2 #define DICT_CLIENT_MAX_LINE_LENGTH (64*1024) @@ -32,6 +34,7 @@ enum dict_protocol_reply { DICT_PROTOCOL_REPLY_ERROR = -1, DICT_PROTOCOL_REPLY_OK = 'O', /* */ + DICT_PROTOCOL_REPLY_MULTI_OK = 'M', /* protocol v2.2+ */ DICT_PROTOCOL_REPLY_NOTFOUND = 'N', DICT_PROTOCOL_REPLY_FAIL = 'F', DICT_PROTOCOL_REPLY_WRITE_UNCERTAIN = 'W',