Skip to content

Commit 9832951

Browse files
committed
Node: Add command SetRange
Signed-off-by: TJ Zhang <tj.zhang@improving.com>
1 parent 54cfb74 commit 9832951

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
* Node: Added ZLEXCOUNT command ([#2022](https://github.com/valkey-io/valkey-glide/pull/2022))
4747
* Node: Added ZREMRANGEBYLEX command ([#2025]((https://github.com/valkey-io/valkey-glide/pull/2025))
4848
* Node: Added ZSCAN command ([#2061](https://github.com/valkey-io/valkey-glide/pull/2061))
49+
* Node: Added SETRANGE command ([#2066](https://github.com/valkey-io/valkey-glide/pull/2066))
4950

5051
#### Breaking Changes
5152
* Node: (Refactor) Convert classes to types ([#2005](https://github.com/valkey-io/valkey-glide/pull/2005))

node/src/BaseClient.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ import {
135135
createSUnionStore,
136136
createSet,
137137
createSetBit,
138+
createSetRange,
138139
createStrlen,
139140
createTTL,
140141
createTouch,
@@ -4464,6 +4465,34 @@ export class BaseClient {
44644465
return this.createWritePromise(createTouch(keys));
44654466
}
44664467

4468+
/**
4469+
* Overwrites part of the string stored at `key`, starting at the specified `offset`,
4470+
* for the entire length of `value`. If the `offset` is larger than the current length of the string at `key`,
4471+
* the string is padded with zero bytes to make `offset` fit. Creates the `key` if it doesn't exist.
4472+
*
4473+
* See https://valkey.io/commands/setrange/ for more details.
4474+
*
4475+
* @param key - The key of the string to update.
4476+
* @param offset - The position in the string where `value` should be written.
4477+
* @param value - The string written with `offset`.
4478+
* @returns The length of the string stored at `key` after it was modified.
4479+
*
4480+
* @example
4481+
* ```typescript
4482+
* const len = await client.setrange("key", 6, "GLIDE");
4483+
* console.log(len); // Output: 11 - New key was created with length of 11 symbols
4484+
* const value = await client.get("key");
4485+
* console.log(result); // Output: "\0\0\0\0\0\0GLIDE" - The string was padded with zero bytes
4486+
* ```
4487+
*/
4488+
public async setrange(
4489+
key: string,
4490+
offset: number,
4491+
value: string,
4492+
): Promise<number> {
4493+
return this.createWritePromise(createSetRange(key, offset, value));
4494+
}
4495+
44674496
/**
44684497
* @internal
44694498
*/

node/src/Commands.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,3 +3044,12 @@ export function createZScan(
30443044

30453045
return createCommand(RequestType.ZScan, args);
30463046
}
3047+
3048+
/** @internal */
3049+
export function createSetRange(
3050+
key: string,
3051+
offset: number,
3052+
value: string,
3053+
): command_request.Command {
3054+
return createCommand(RequestType.SetRange, [key, offset.toString(), value]);
3055+
}

node/src/Transaction.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ import {
162162
createSelect,
163163
createSet,
164164
createSetBit,
165+
createSetRange,
165166
createSort,
166167
createSortReadOnly,
167168
createStrlen,
@@ -2694,6 +2695,23 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
26942695
public randomKey(): T {
26952696
return this.addAndReturn(createRandomKey());
26962697
}
2698+
2699+
/**
2700+
* Overwrites part of the string stored at `key`, starting at the specified `offset`,
2701+
* for the entire length of `value`. If the `offset` is larger than the current length of the string at `key`,
2702+
* the string is padded with zero bytes to make `offset` fit. Creates the `key` if it doesn't exist.
2703+
*
2704+
* See https://valkey.io/commands/setrange/ for more details.
2705+
*
2706+
* @param key - The key of the string to update.
2707+
* @param offset - The position in the string where `value` should be written.
2708+
* @param value - The string written with `offset`.
2709+
*
2710+
* Command Response - The length of the string stored at `key` after it was modified.
2711+
*/
2712+
public setrange(key: string, offset: number, value: string): T {
2713+
return this.addAndReturn(createSetRange(key, offset, value));
2714+
}
26972715
}
26982716

26992717
/**

node/tests/SharedTests.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4659,6 +4659,36 @@ export function runBaseTests<Context>(config: {
46594659
config.timeout,
46604660
);
46614661

4662+
it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
4663+
"setrange test_%p",
4664+
async (protocol) => {
4665+
await runTest(async (client: BaseClient) => {
4666+
const key = uuidv4();
4667+
const nonStringKey = uuidv4();
4668+
4669+
// new key
4670+
expect(await client.setrange(key, 0, "Hello World")).toBe(11);
4671+
4672+
// existing key
4673+
expect(await client.setrange(key, 6, "GLIDE")).toBe(11);
4674+
expect(await client.get(key)).toEqual("Hello GLIDE");
4675+
4676+
// offset > len
4677+
expect(await client.setrange(key, 15, "GLIDE")).toBe(20);
4678+
expect(await client.get(key)).toEqual(
4679+
"Hello GLIDE\0\0\0\0GLIDE",
4680+
);
4681+
4682+
// non-string key
4683+
expect(await client.lpush(nonStringKey, ["_"])).toBe(1);
4684+
await expect(
4685+
client.setrange(nonStringKey, 0, "_"),
4686+
).rejects.toThrow(RequestError);
4687+
}, protocol);
4688+
},
4689+
config.timeout,
4690+
);
4691+
46624692
// Set command tests
46634693

46644694
async function setWithExpiryOptions(client: BaseClient) {

node/tests/TestUtilities.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,8 @@ export async function transactionTest(
517517
responseData.push(["mget([key1, key2])", ["bar", "baz"]]);
518518
baseTransaction.strlen(key1);
519519
responseData.push(["strlen(key1)", 3]);
520+
baseTransaction.setrange(key1, 0, "GLIDE");
521+
responseData.push(["setrange(key1, 0, 'GLIDE'", 5]);
520522
baseTransaction.del([key1]);
521523
responseData.push(["del([key1])", 1]);
522524
baseTransaction.hset(key4, { [field]: value });

0 commit comments

Comments
 (0)