diff --git a/CHANGELOG.md b/CHANGELOG.md index 83751c2ea5..7d8b35ef31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ * Node: Added FUNCTION FLUSH command ([#1984](https://github.com/valkey-io/valkey-glide/pull/1984)) * Node: Added FCALL and FCALL_RO commands ([#2011](https://github.com/valkey-io/valkey-glide/pull/2011)) * Node: Added COPY command ([#2024](https://github.com/valkey-io/valkey-glide/pull/2024)) +* Node: Added MOVE command ([#2104](https://github.com/valkey-io/valkey-glide/pull/2104)) * Node: Added ZMPOP command ([#1994](https://github.com/valkey-io/valkey-glide/pull/1994)) * Node: Added ZINCRBY command ([#2009](https://github.com/valkey-io/valkey-glide/pull/2009)) * Node: Added BZMPOP command ([#2018](https://github.com/valkey-io/valkey-glide/pull/2018)) diff --git a/node/src/Commands.ts b/node/src/Commands.ts index d13c047461..489eb198a1 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -2697,6 +2697,16 @@ export function createCopy( return createCommand(RequestType.Copy, args); } +/** + * @internal + */ +export function createMove( + key: string, + dbIndex: number, +): command_request.Command { + return createCommand(RequestType.Move, [key, dbIndex.toString()]); +} + /** * Optional arguments to LPOS command. * diff --git a/node/src/GlideClient.ts b/node/src/GlideClient.ts index daedf2935d..cda9ec6cfa 100644 --- a/node/src/GlideClient.ts +++ b/node/src/GlideClient.ts @@ -38,6 +38,7 @@ import { createInfo, createLastSave, createLolwut, + createMove, createPing, createPublish, createRandomKey, @@ -426,6 +427,26 @@ export class GlideClient extends BaseClient { ); } + /** + * Move `key` from the currently selected database to the database specified by `dbIndex`. + * + * See https://valkey.io/commands/move/ for more details. + * + * @param key - The key to move. + * @param dbIndex - The index of the database to move `key` to. + * @returns `true` if `key` was moved, or `false` if the `key` already exists in the destination + * database or does not exist in the source database. + * + * @example + * ```typescript + * const result = await client.move("key", 1); + * console.log(result); // Output: true + * ``` + */ + public async move(key: string, dbIndex: number): Promise { + return this.createWritePromise(createMove(key, dbIndex)); + } + /** * Displays a piece of generative computer art and the server version. * diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 0004c600a8..4b74520910 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -141,6 +141,7 @@ import { createMGet, createMSet, createMSetNX, + createMove, createObjectEncoding, createObjectFreq, createObjectIdletime, @@ -3418,6 +3419,21 @@ export class Transaction extends BaseTransaction { return this.addAndReturn(createCopy(source, destination, options)); } + /** + * Move `key` from the currently selected database to the database specified by `dbIndex`. + * + * See https://valkey.io/commands/move/ for more details. + * + * @param key - The key to move. + * @param dbIndex - The index of the database to move `key` to. + * + * Command Response - `true` if `key` was moved, or `false` if the `key` already exists in the destination + * database or does not exist in the source database. + */ + public move(key: string, dbIndex: number): Transaction { + return this.addAndReturn(createMove(key, dbIndex)); + } + /** Publish a message on pubsub channel. * * See https://valkey.io/commands/publish for more details. diff --git a/node/tests/GlideClient.test.ts b/node/tests/GlideClient.test.ts index d74776ced0..77125333ae 100644 --- a/node/tests/GlideClient.test.ts +++ b/node/tests/GlideClient.test.ts @@ -504,6 +504,46 @@ describe("GlideClient", () => { TIMEOUT, ); + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( + "move test_%p", + async (protocol) => { + const client = await GlideClient.createClient( + getClientConfigurationOption(cluster.getAddresses(), protocol), + ); + + const key1 = "{key}-1" + uuidv4(); + const key2 = "{key}-2" + uuidv4(); + const value = uuidv4(); + + expect(await client.select(0)).toEqual("OK"); + expect(await client.move(key1, 1)).toEqual(false); + + expect(await client.set(key1, value)).toEqual("OK"); + expect(await client.get(key1)).toEqual(value); + expect(await client.move(key1, 1)).toEqual(true); + expect(await client.get(key1)).toEqual(null); + expect(await client.select(1)).toEqual("OK"); + expect(await client.get(key1)).toEqual(value); + + await expect(client.move(key1, -1)).rejects.toThrow(RequestError); + + //transaction tests + const transaction = new Transaction(); + transaction.select(1); + transaction.move(key2, 0); + transaction.set(key2, value); + transaction.move(key2, 0); + transaction.select(0); + transaction.get(key2); + const results = await client.exec(transaction); + + expect(results).toEqual(["OK", false, "OK", true, "OK", value]); + + client.close(); + }, + TIMEOUT, + ); + it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( "function load function list function stats test_%p", async (protocol) => {