From f24b56de164c154bc55442a62044708ee69125f7 Mon Sep 17 00:00:00 2001 From: Adan Date: Thu, 22 Feb 2024 09:50:29 +0000 Subject: [PATCH] Node: added hvals command. --- glide-core/src/protobuf/redis_request.proto | 1 + glide-core/src/socket_listener.rs | 1 + node/src/BaseClient.ts | 11 +++++++++++ node/src/Commands.ts | 7 +++++++ node/src/Transaction.ts | 12 +++++++++++ node/tests/SharedTests.ts | 22 +++++++++++++++++++++ node/tests/TestUtilities.ts | 2 ++ 7 files changed, 56 insertions(+) diff --git a/glide-core/src/protobuf/redis_request.proto b/glide-core/src/protobuf/redis_request.proto index 0389ce82d3..59cf745c67 100644 --- a/glide-core/src/protobuf/redis_request.proto +++ b/glide-core/src/protobuf/redis_request.proto @@ -123,6 +123,7 @@ enum RequestType { XTrim = 79; XGroupCreate = 80; XGroupDestroy = 81; + Hvals = 82; } message Command { diff --git a/glide-core/src/socket_listener.rs b/glide-core/src/socket_listener.rs index d925c80172..ffaf39f7ce 100644 --- a/glide-core/src/socket_listener.rs +++ b/glide-core/src/socket_listener.rs @@ -360,6 +360,7 @@ fn get_command(request: &Command) -> Option { RequestType::XGroupCreate => Some(get_two_word_command("XGROUP", "CREATE")), RequestType::XGroupDestroy => Some(get_two_word_command("XGROUP", "DESTROY")), RequestType::XTrim => Some(cmd("XTRIM")), + RequestType::Hvals => Some(cmd("HVALS")), } } diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index a73c40f47e..1c8067b068 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -31,6 +31,7 @@ import { createHLen, createHMGet, createHSet, + createHvals, createIncr, createIncrBy, createIncrByFloat, @@ -631,6 +632,16 @@ export class BaseClient { return this.createWritePromise(createHLen(key)); } + /** Returns all values in the hash stored at key. + * See https://redis.io/commands/hvals/ for more details. + * + * @param key - The key of the hash. + * @returns a list of values in the hash, or an empty list when the key does not exist + */ + public hvals(key: string): Promise { + return this.createWritePromise(createHvals(key)); + } + /** Inserts all the specified values at the head of the list stored at `key`. * `elements` are inserted one after the other to the head of the list, from the leftmost element to the rightmost element. * If `key` does not exist, it is created as empty list before performing the push operations. diff --git a/node/src/Commands.ts b/node/src/Commands.ts index ffd24f4731..2ae48326ee 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -592,6 +592,13 @@ export function createHLen(key: string): redis_request.Command { return createCommand(RequestType.HLen, [key]); } +/** + * @internal + */ +export function createHvals(key: string): redis_request.Command { + return createCommand(RequestType.Hvals, [key]); +} + /** * @internal */ diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index cf6f3826b9..dd630323db 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -31,6 +31,7 @@ import { createHLen, createHMGet, createHSet, + createHvals, createIncr, createIncrBy, createIncrByFloat, @@ -425,6 +426,17 @@ export class BaseTransaction> { return this.addAndReturn(createHLen(key)); } + /** Returns all values in the hash stored at key. + * See https://redis.io/commands/hvals/ for more details. + * + * @param key - The key of the hash. + * + * Command Response - a list of values in the hash, or an empty list when the key does not exist + */ + public hvals(key: string): T { + return this.addAndReturn(createHvals(key)); + } + /** Inserts all the specified values at the head of the list stored at `key`. * `elements` are inserted one after the other to the head of the list, from the leftmost element to the rightmost element. * If `key` does not exist, it is created as empty list before performing the push operations. diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 2ed87bedbb..a19d5c8b7e 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -772,6 +772,28 @@ export function runBaseTests(config: { config.timeout ); + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( + `hvals test_%p`, + async (protocol) => { + await runTest(async (client: BaseClient) => { + const key1 = uuidv4(); + const field1 = uuidv4(); + const field2 = uuidv4(); + const fieldValueMap = { + [field1]: "value1", + [field2]: "value2", + }; + + expect(await client.hset(key1, fieldValueMap)).toEqual(2); + expect(await client.hvals(key1)).toEqual(["value1", "value2"]); + expect(await client.hdel(key1, [field1])).toEqual(1); + expect(await client.hvals(key1)).toEqual(["value2"]); + expect(await client.hvals("nonExistingHash")).toEqual([]); + }, protocol); + }, + config.timeout + ); + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( `lpush, lpop and lrange with existing and non existing key_%p`, async (protocol) => { diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index fadf6e5fde..bc4a0730f4 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -86,6 +86,8 @@ export function transactionTest( args.push(1); baseTransaction.hlen(key4); args.push(1); + baseTransaction.hvals(key4); + args.push([value]); baseTransaction.hget(key4, field); args.push(value); baseTransaction.hgetall(key4);