Skip to content

Commit

Permalink
Node - Add rename command (valkey-io#1124)
Browse files Browse the repository at this point in the history
* Add Rename command to node
  • Loading branch information
avifenesh authored and cyip10 committed Jun 24, 2024
1 parent bba242e commit fe3bece
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Python, Node: Added LINDEX command ([#1058](https://github.com/aws/glide-for-redis/pull/1058), [#999](https://github.com/aws/glide-for-redis/pull/999))
* Python: Added ZRANK command ([#1065](https://github.com/aws/glide-for-redis/pull/1065))
* Core: Enabled Cluster Mode periodic checks by default ([#1089](https://github.com/aws/glide-for-redis/pull/1089))
* Node: Added Rename command. ([#1124](https://github.com/aws/glide-for-redis/pull/1124))

#### Features

Expand Down
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ enum RequestType {
ZRemRangeByScore = 90;
Time = 91;
Zrank = 92;
Rename = 93;
}

message Command {
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/socket_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ fn get_command(request: &Command) -> Option<Cmd> {
RequestType::ZRemRangeByScore => Some(cmd("ZREMRANGEBYSCORE")),
RequestType::Time => Some(cmd("TIME")),
RequestType::Zrank => Some(cmd("ZRANK")),
RequestType::Rename => Some(cmd("RENAME")),
}
}

Expand Down
16 changes: 16 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
createPttl,
createRPop,
createRPush,
createRename,
createSAdd,
createSCard,
createSMembers,
Expand Down Expand Up @@ -1326,6 +1327,21 @@ export class BaseClient {
return this.createWritePromise(createPersist(key));
}

/**
* Renames `key` to `newkey`.
* If `newkey` already exists it is overwritten.
* In Cluster mode, both `key` and `newkey` must be in the same hash slot,
* meaning that in practice only keys that have the same hash tag can be reliably renamed in cluster.
* See https://redis.io/commands/rename/ for more details.
*
* @param key - The key to rename.
* @param newKey - The new name of the key.
* @returns - If the `key` was successfully renamed, return "OK". If `key` does not exist, an error is thrown.
*/
public rename(key: string, newKey: string): Promise<"OK"> {
return this.createWritePromise(createRename(key, newKey));
}

/**
* @internal
*/
Expand Down
10 changes: 10 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,3 +1105,13 @@ export function createXread(

return createCommand(RequestType.XRead, args);
}

/**
* @internal
*/
export function createRename(
key: string,
newKey: string,
): redis_request.Command {
return createCommand(RequestType.Rename, [key, newKey]);
}
16 changes: 16 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
createPttl,
createRPop,
createRPush,
createRename,
createSAdd,
createSCard,
createSMembers,
Expand Down Expand Up @@ -1110,6 +1111,21 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
): T {
return this.addAndReturn(createXread(keys_and_ids, options));
}

/**
* Renames `key` to `newkey`.
* If `newkey` already exists it is overwritten.
* In Cluster mode, both `key` and `newkey` must be in the same hash slot,
* meaning that in practice only keys that have the same hash tag can be reliably renamed in cluster.
* See https://redis.io/commands/rename/ for more details.
*
* @param key - The key to rename.
* @param newKey - The new name of the key.
* Command Response - If the `key` was successfully renamed, return "OK". If `key` does not exist, an error is thrown.
*/
public rename(key: string, newKey: string): T {
return this.addAndReturn(createRename(key, newKey));
}
}

/**
Expand Down
19 changes: 19 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,25 @@ export function runBaseTests<Context>(config: {
},
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"rename test_%p",
async (protocol) => {
await runTest(async (client: BaseClient) => {
// Making sure both keys will be oart of the same slot
const key = uuidv4() + "{123}";
const newKey = uuidv4() + "{123}";
await client.set(key, "value");
await client.rename(key, newKey);
const result = await client.get(newKey);
expect(result).toEqual("value");
// If key doesn't exist it should throw, it also test that key has succfully been renamed
await expect(client.rename(key, newKey)).rejects.toThrow();
client.close();
}, protocol);
},
config.timeout,
);
}

export function runCommonTests<Context>(config: {
Expand Down
5 changes: 5 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function transactionTest(
const key7 = "{key}" + uuidv4();
const key8 = "{key}" + uuidv4();
const key9 = "{key}" + uuidv4();
const key10 = "{key}" + uuidv4();
const field = uuidv4();
const value = uuidv4();
const args: ReturnType[] = [];
Expand Down Expand Up @@ -191,6 +192,10 @@ export function transactionTest(
exact: true,
});
args.push(1);
baseTransaction.rename(key9, key10);
args.push("OK");
baseTransaction.exists([key10]);
args.push(1);
return args;
}

Expand Down

0 comments on commit fe3bece

Please sign in to comment.