Skip to content

Commit

Permalink
Node: add SUNION command
Browse files Browse the repository at this point in the history
Signed-off-by: aaron-congo <[email protected]>
  • Loading branch information
aaron-congo committed Jul 10, 2024
1 parent 97b13e3 commit 57ef844
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 1 deletion.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#### Changes
* Node: Added SUNION command ([#1919](https://github.com/valkey-io/valkey-glide/pull/1919))

## 1.0.0 (2024-07-09)

#### Changes
* Node: Added ZINTERSTORE command ([#1513](https://github.com/valkey-io/valkey-glide/pull/1513))
* Python: Added OBJECT ENCODING command ([#1471](https://github.com/valkey-io/valkey-glide/pull/1471))
Expand Down Expand Up @@ -94,7 +99,7 @@
#### Fixes
* Python: fixing a bug with transaction exec ([#1796](https://github.com/valkey-io/valkey-glide/pull/1796))

## 0.4.1 (2024-02-06)
## 0.4.1 (2024-06-02)

#### Fixes
* Node: Fix set command bug with expiry option ([#1508](https://github.com/valkey-io/valkey-glide/pull/1508))
Expand Down
26 changes: 26 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ import {
createZRemRangeByRank,
createZRemRangeByScore,
createZScore,
createSUnion,
} from "./Commands";
import {
ClosingError,
Expand Down Expand Up @@ -1316,6 +1317,31 @@ export class BaseClient {
);
}

/**
* Gets the union of all the given sets.
*
* See https://valkey.io/commands/sunion/ for more details.
*
* @remarks When in cluster mode, all `keys` must map to the same hash slot.
* @param keys - The keys of the sets.
* @returns A set of members which are present in at least one of the given sets.
* If none of the sets exist, an empty set will be returned.
*
* @example
* ```typescript
* await client.sadd("my_set1", ["member1", "member2"]);
* await client.sadd("my_set2", ["member2", "member3"]);
* const result1 = await client.sunion(["my_set1", "my_set2"]);
* console.log(result1); // Output: Set {'member1', 'member2', 'member3'} - Sets "my_set1" and "my_set2" have three unique members.
*
* const result2 = await client.sunion(["my_set1", "non_existing_set"]);
* console.log(result2); // Output: Set {'member1', 'member2'}
* ```
*/
public sunion(keys: string[]): Promise<Set<string>> {
return this.createWritePromise(createSUnion(keys));
}

/**
* Stores the members of the union of all given sets specified by `keys` into a new set
* at `destination`.
Expand Down
7 changes: 7 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,13 @@ export function createSInter(keys: string[]): command_request.Command {
return createCommand(RequestType.SInter, keys);
}

/**
* @internal
*/
export function createSUnion(keys: string[]): command_request.Command {
return createCommand(RequestType.SUnion, keys);
}

/**
* @internal
*/
Expand Down
15 changes: 15 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ import {
createZRemRangeByRank,
createZRemRangeByScore,
createZScore,
createSUnion,
} from "./Commands";
import { command_request } from "./ProtobufMessage";

Expand Down Expand Up @@ -732,6 +733,20 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createSInter(keys), true);
}

/**
* Gets the union of all the given sets.
*
* See https://valkey.io/commands/sunion/ for more details.
*
* @param keys - The keys of the sets.
*
* Command Response - A set of members which are present in at least one of the given sets.
* If none of the sets exist, an empty set will be returned.
*/
public sunion(keys: string[]): T {
return this.addAndReturn(createSUnion(keys));
}

/**
* Stores the members of the union of all given sets specified by `keys` into a new set
* at `destination`.
Expand Down
1 change: 1 addition & 0 deletions node/tests/RedisClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ describe("GlideClusterClient", () => {
client.sinter(["abc", "zxy", "lkn"]),
client.zinterstore("abc", ["zxy", "lkn"]),
client.sunionstore("abc", ["zxy", "lkn"]),
client.sunion(["zxy", "lkn"]),
client.pfcount(["abc", "zxy", "lkn"]),
// TODO all rest multi-key commands except ones tested below
];
Expand Down
33 changes: 33 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,39 @@ export function runBaseTests<Context>(config: {
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`sunion test_%p`,
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key1 = `{key}:${uuidv4()}`;
const key2 = `{key}:${uuidv4()}`;
const stringKey = `{key}:${uuidv4()}`;
const nonExistingKey = `{key}:${uuidv4()}`;
const memberList1 = ["a", "b", "c"];
const memberList2 = ["b", "c", "d", "e"];

expect(await client.sadd(key1, memberList1)).toEqual(3);
expect(await client.sadd(key2, memberList2)).toEqual(4);
checkSimple(await client.sunion([key1, key2])).toEqual(
new Set(["a", "b", "c", "d", "e"]),
);

// invalid argument - key list must not be empty
await expect(client.sunion([])).rejects.toThrow();

// non-existing key returns the set of existing keys
checkSimple(
await client.sunion([key1, nonExistingKey]),
).toEqual(new Set(memberList1));

// key exists, but it is not a set
expect(await client.set(stringKey, "value")).toEqual("OK");
await expect(client.sunion([stringKey])).rejects.toThrow();
}, protocol);
},
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`sunionstore test_%p`,
async (protocol) => {
Expand Down
2 changes: 2 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ export async function transactionTest(
args.push(2);
baseTransaction.sunionstore(key7, [key7, key7]);
args.push(2);
baseTransaction.sunion([key7, key7]);
args.push(new Set(["bar", "foo"]));
baseTransaction.sinter([key7, key7]);
args.push(new Set(["bar", "foo"]));
baseTransaction.srem(key7, ["foo"]);
Expand Down

0 comments on commit 57ef844

Please sign in to comment.