From 9e7f2f326ab5e8f88128873346befd1d4fc727f5 Mon Sep 17 00:00:00 2001 From: Adan Wattad Date: Fri, 16 Feb 2024 15:13:12 +0200 Subject: [PATCH] Node: added type command. (#980) * Node: added type command. * update the CHANGELOG.MD file --- CHANGELOG.md | 2 +- node/src/BaseClient.ts | 11 ++++++++++ node/src/Commands.ts | 7 +++++++ node/src/Transaction.ts | 12 +++++++++++ node/tests/SharedTests.ts | 41 +++++++++++++++++++++++++++++++++++++ node/tests/TestUtilities.ts | 2 ++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b075352f2..c854978839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ * Python, Node: Added RPOPCOUNT and LPOPCOUNT to transaction ([#874](https://github.com/aws/glide-for-redis/pull/874)) * Standalone client: Improve connection errors. ([#854](https://github.com/aws/glide-for-redis/pull/854)) * Python, Node: When recieving LPOP/RPOP with count, convert result to Array. ([#811](https://github.com/aws/glide-for-redis/pull/811)) -* Python: Added TYPE command ([#945](https://github.com/aws/glide-for-redis/pull/945)) +* Python, Node: Added TYPE command ([#945](https://github.com/aws/glide-for-redis/pull/945), [#980](https://github.com/aws/glide-for-redis/pull/980)) * Python: Added HLEN command ([#944](https://github.com/aws/glide-for-redis/pull/944)) * Node: Added ZCOUNT command ([#909](https://github.com/aws/glide-for-redis/pull/909)) diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index 230643ebdb..742e646363 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -51,6 +51,7 @@ import { createSRem, createSet, createTTL, + createType, createUnlink, createZadd, createZcard, @@ -1065,6 +1066,16 @@ export class BaseClient { return this.createWritePromise(createZcount(key, minScore, maxScore)); } + /** Returns the string representation of the type of the value stored at `key`. + * See https://redis.io/commands/type/ for more details. + * + * @param key - The key to check its data type. + * @returns If the key exists, the type of the stored value is returned. Otherwise, a "none" string is returned. + */ + public type(key: string): Promise { + return this.createWritePromise(createType(key)); + } + private readonly MAP_READ_FROM_STRATEGY: Record< ReadFrom, connection_request.ReadFrom diff --git a/node/src/Commands.ts b/node/src/Commands.ts index d8ab96f9c4..9f6996312d 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -816,3 +816,10 @@ export function createZcount( return createCommand(RequestType.Zcount, args); } + +/** + * @internal + */ +export function createType(key: string): redis_request.Command { + return createCommand(RequestType.Type, [key]); +} diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index c2c9104cbb..691dc7b8e6 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -54,6 +54,7 @@ import { createSelect, createSet, createTTL, + createType, createUnlink, createZadd, createZcard, @@ -828,6 +829,17 @@ export class BaseTransaction> { return this.addAndReturn(createZcount(key, minScore, maxScore)); } + /** Returns the string representation of the type of the value stored at `key`. + * See https://redis.io/commands/type/ for more details. + * + * @param key - The key to check its data type. + * + * Command Response - If the key exists, the type of the stored value is returned. Otherwise, a "none" string is returned. + */ + public type(key: string): T { + return this.addAndReturn(createType(key)); + } + /** Executes a single command, without checking inputs. Every part of the command, including subcommands, * should be added as a separate value in args. * diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 3aa60e9101..6e6b047afc 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -1469,6 +1469,47 @@ export function runBaseTests(config: { }, config.timeout ); + + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( + `type test_%p`, + async (protocol) => { + await runTest(async (client: BaseClient) => { + const key = uuidv4(); + expect(await client.set(key, "value")).toEqual("OK"); + expect(await client.type(key)).toEqual("string"); + expect(await client.del([key])).toEqual(1); + + expect(await client.lpush(key, ["value"])).toEqual(1); + expect(await client.type(key)).toEqual("list"); + expect(await client.del([key])).toEqual(1); + + expect(await client.sadd(key, ["value"])).toEqual(1); + expect(await client.type(key)).toEqual("set"); + expect(await client.del([key])).toEqual(1); + + expect(await client.zadd(key, { member: 1.0 })).toEqual(1); + expect(await client.type(key)).toEqual("zset"); + expect(await client.del([key])).toEqual(1); + + expect(await client.hset(key, { field: "value" })).toEqual(1); + expect(await client.type(key)).toEqual("hash"); + expect(await client.del([key])).toEqual(1); + + await client.customCommand([ + "XADD", + key, + "*", + "field", + "value", + ]); + expect(await client.type(key)).toEqual("stream"); + expect(await client.del([key])).toEqual(1); + + expect(await client.type(key)).toEqual("none"); + }, protocol); + }, + config.timeout + ); } export function runCommonTests(config: { diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index 82fa33976f..a4ff1df332 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -66,6 +66,8 @@ export function transactionTest( const args: ReturnType[] = []; baseTransaction.set(key1, "bar"); args.push("OK"); + baseTransaction.type(key1); + args.push("string"); baseTransaction.set(key2, "baz", { returnOldValue: true, });