Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node: add SETBIT command #1978

Merged
merged 2 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#### Changes
* Node: Added GETDEL command ([#1968](https://github.com/valkey-io/valkey-glide/pull/1968))
* Node: Added SETBIT command ([#1978](https://github.com/valkey-io/valkey-glide/pull/1978))
* Node: Added LPUSHX and RPUSHX command([#1959](https://github.com/valkey-io/valkey-glide/pull/1959))
* Node: Added LSET command ([#1952](https://github.com/valkey-io/valkey-glide/pull/1952))
* Node: Added SDIFFSTORE command ([#1931](https://github.com/valkey-io/valkey-glide/pull/1931))
Expand Down
24 changes: 24 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import {
createSCard,
createSDiff,
createSDiffStore,
createSetBit,
createSInter,
createSInterCard,
createSInterStore,
Expand Down Expand Up @@ -962,6 +963,29 @@ export class BaseClient {
return this.createWritePromise(createDecrBy(key, amount));
}

/**
* Sets or clears the bit at `offset` in the string value stored at `key`. The `offset` is a zero-based index, with
* `0` being the first element of the list, `1` being the next element, and so on. The `offset` must be less than
* `2^32` and greater than or equal to `0`. If a key is non-existent then the bit at `offset` is set to `value` and
* the preceding bits are set to `0`.
*
* See https://valkey.io/commands/setbit/ for more details.
*
* @param key - The key of the string.
* @param offset - The index of the bit to be set.
* @param value - The bit value to set at `offset`. The value must be `0` or `1`.
* @returns The bit value that was previously stored at `offset`.
*
* @example
* ```typescript
* const result = await client.setbit("key", 1, 1);
* console.log(result); // Output: 0 - The second bit value was 0 before setting to 1.
* ```
*/
public setbit(key: string, offset: number, value: number): Promise<number> {
return this.createWritePromise(createSetBit(key, offset, value));
}

/** Retrieve the value associated with `field` in the hash stored at `key`.
* See https://valkey.io/commands/hget/ for details.
*
Expand Down
15 changes: 15 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,21 @@ export function createDecrBy(
return createCommand(RequestType.DecrBy, [key, amount.toString()]);
}

/**
* @internal
*/
export function createSetBit(
key: string,
offset: number,
value: number,
): command_request.Command {
return createCommand(RequestType.SetBit, [
key,
offset.toString(),
value.toString(),
]);
}

/**
* @internal
*/
Expand Down
19 changes: 19 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
createSCard,
createSDiff,
createSDiffStore,
createSetBit,
createSInter,
createSInterCard,
createSInterStore,
Expand Down Expand Up @@ -374,6 +375,24 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createDecrBy(key, amount));
}

/**
* Sets or clears the bit at `offset` in the string value stored at `key`. The `offset` is a zero-based index, with
* `0` being the first element of the list, `1` being the next element, and so on. The `offset` must be less than
* `2^32` and greater than or equal to `0`. If a key is non-existent then the bit at `offset` is set to `value` and
* the preceding bits are set to `0`.
*
* See https://valkey.io/commands/setbit/ for more details.
*
* @param key - The key of the string.
* @param offset - The index of the bit to be set.
* @param value - The bit value to set at `offset`. The value must be `0` or `1`.
*
* Command Response - The bit value that was previously stored at `offset`.
*/
public setbit(key: string, offset: number, value: number): T {
return this.addAndReturn(createSetBit(key, offset, value));
}

/** Reads the configuration parameters of a running Redis server.
* See https://valkey.io/commands/config-get/ for details.
*
Expand Down
30 changes: 30 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,36 @@ export function runBaseTests<Context>(config: {
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`setbit test_%p`,
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key = `{key}-${uuidv4()}`;
const stringKey = `{key}-${uuidv4()}`;

expect(await client.setbit(key, 1, 1)).toEqual(0);
expect(await client.setbit(key, 1, 0)).toEqual(1);

// invalid argument - offset can't be negative
await expect(client.setbit(key, -1, 1)).rejects.toThrow(
RequestError,
);

// invalid argument - "value" arg must be 0 or 1
await expect(client.setbit(key, 0, 2)).rejects.toThrow(
RequestError,
);

// key exists, but it is not a string
expect(await client.sadd(stringKey, ["foo"])).toEqual(1);
await expect(client.setbit(stringKey, 0, 0)).rejects.toThrow(
RequestError,
);
}, protocol);
},
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`config get and config set with timeout parameter_%p`,
async (protocol) => {
Expand Down
5 changes: 5 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ export async function transactionTest(
const key14 = "{key}" + uuidv4(); // sorted set
const key15 = "{key}" + uuidv4(); // list
const key16 = "{key}" + uuidv4(); // list
const key17 = "{key}" + uuidv4(); // bitmap
const field = uuidv4();
const value = uuidv4();
const args: ReturnType[] = [];
Expand Down Expand Up @@ -566,6 +567,10 @@ export async function transactionTest(
args.push([key6, field + "3"]);
baseTransaction.blpop([key6], 0.1);
args.push([key6, field + "1"]);

baseTransaction.setbit(key17, 1, 1);
args.push(0);

baseTransaction.pfadd(key11, ["a", "b", "c"]);
args.push(1);
baseTransaction.pfcount([key11]);
Expand Down
Loading