diff --git a/CHANGELOG.md b/CHANGELOG.md index 5409203239..49ccff88db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Python: Added ECHO command ([#953](https://github.com/aws/glide-for-redis/pull/953)) * Python: Added ZPOPMIN command ([#975](https://github.com/aws/glide-for-redis/pull/975)) * Node: Added STRLEN command ([#993](https://github.com/aws/glide-for-redis/pull/993)) +* Node: Added LINDEX command ([#999](https://github.com/aws/glide-for-redis/pull/999)) #### Features * Python, Node: Added support in Lua Scripts ([#775](https://github.com/aws/glide-for-redis/pull/775), [#860](https://github.com/aws/glide-for-redis/pull/860)) diff --git a/glide-core/src/protobuf/redis_request.proto b/glide-core/src/protobuf/redis_request.proto index 0a659eee8a..1fd6eb939c 100644 --- a/glide-core/src/protobuf/redis_request.proto +++ b/glide-core/src/protobuf/redis_request.proto @@ -108,6 +108,7 @@ enum RequestType { Echo = 70; ZPopMin = 71; Strlen = 72; + Lindex = 73; } message Command { diff --git a/glide-core/src/socket_listener.rs b/glide-core/src/socket_listener.rs index 23329b7962..d541234f9e 100644 --- a/glide-core/src/socket_listener.rs +++ b/glide-core/src/socket_listener.rs @@ -351,6 +351,7 @@ fn get_command(request: &Command) -> Option { RequestType::Echo => Some(cmd("ECHO")), RequestType::ZPopMin => Some(cmd("ZPOPMIN")), RequestType::Strlen => Some(cmd("STRLEN")), + RequestType::Lindex => Some(cmd("LINDEX")), } } diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index ce32220015..59e6107f17 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -39,6 +39,7 @@ import { createLRange, createLRem, createLTrim, + createLindex, createMGet, createMSet, createPExpire, @@ -1096,6 +1097,21 @@ export class BaseClient { preferReplica: connection_request.ReadFrom.PreferReplica, }; + /** Returns the element at index `index` in the list stored at `key`. + * The index is zero-based, so 0 means the first element, 1 the second element and so on. + * Negative indices can be used to designate elements starting at the tail of the list. + * Here, -1 means the last element, -2 means the penultimate and so forth. + * See https://redis.io/commands/lindex/ for more details. + * + * @param key - The `key` of the list. + * @param index - The `index` of the element in the list to retrieve. + * @returns - The element at `index` in the list stored at `key`. + * If `index` is out of range or if `key` does not exist, null is returned. + */ + public lindex(key: string, index: number): Promise { + return this.createWritePromise(createLindex(key, index)); + } + /** * @internal */ diff --git a/node/src/Commands.ts b/node/src/Commands.ts index 0da92cc018..6d174eb333 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -830,3 +830,13 @@ export function createType(key: string): redis_request.Command { export function createStrlen(key: string): redis_request.Command { return createCommand(RequestType.Strlen, [key]); } + +/** + * @internal + */ +export function createLindex( + key: string, + index: number +): redis_request.Command { + return createCommand(RequestType.Lindex, [key, index.toString()]); +} diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 5e5c509b27..8800f34620 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -62,6 +62,7 @@ import { createZcount, createZrem, createZscore, + createLindex, } from "./Commands"; import { redis_request } from "./ProtobufMessage"; @@ -866,6 +867,21 @@ export class BaseTransaction> { public customCommand(args: string[]): T { return this.addAndReturn(createCustomCommand(args)); } + + /** Returns the element at index `index` in the list stored at `key`. + * The index is zero-based, so 0 means the first element, 1 the second element and so on. + * Negative indices can be used to designate elements starting at the tail of the list. + * Here, -1 means the last element, -2 means the penultimate and so forth. + * See https://redis.io/commands/lindex/ for more details. + * + * @param key - The `key` of the list. + * @param index - The `index` of the element in the list to retrieve. + * Command Response - The element at index in the list stored at `key`. + * If `index` is out of range or if `key` does not exist, null is returned. + */ + public lindex(key: string, index: number): T { + return this.addAndReturn(createLindex(key, index)); + } } /** diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 4025da31f7..ab4217092c 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -1535,6 +1535,24 @@ export function runBaseTests(config: { }, config.timeout ); + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( + `lindex test_%p`, + async (protocol) => { + await runTest(async (client: BaseClient) => { + const listName = uuidv4(); + const listKey1Value = uuidv4(); + const listKey2Value = uuidv4(); + expect( + await client.lpush(listName, [listKey1Value, listKey2Value]) + ).toEqual(2); + expect(await client.lindex(listName, 0)).toEqual(listKey2Value); + expect(await client.lindex(listName, 1)).toEqual(listKey1Value); + expect(await client.lindex("notExsitingList", 1)).toEqual(null); + expect(await client.lindex(listName, 3)).toEqual(null); + }, protocol); + }, + config.timeout + ); } export function runCommonTests(config: { diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index 3e99f6fa56..7b8683f4e6 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -115,6 +115,8 @@ export function transactionTest( args.push([field + "3", field + "2"]); baseTransaction.rpush(key6, [field + "1", field + "2", field + "3"]); args.push(3); + baseTransaction.lindex(key6, 0); + args.push(field + "1"); baseTransaction.rpop(key6); args.push(field + "3"); baseTransaction.rpopCount(key6, 2);