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 PFADD command. #1317

Merged
merged 6 commits into from
Apr 25, 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
Expand Up @@ -15,6 +15,7 @@
* Python: Added ZREMRANGEBYLEX command ([#1306](https://github.com/aws/glide-for-redis/pull/1306))
* Python: Added LINSERT command ([#1304](https://github.com/aws/glide-for-redis/pull/1304))
* Python: Added GEOPOS command ([#1301](https://github.com/aws/glide-for-redis/pull/1301))
* Node: Added PFADD command ([#1317](https://github.com/aws/glide-for-redis/pull/1317))
* Python: Added PFADD command ([#1315](https://github.com/aws/glide-for-redis/pull/1315))

#### Fixes
Expand Down
23 changes: 23 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
createPExpire,
createPExpireAt,
createPersist,
createPfAdd,
createPttl,
createRPop,
createRPush,
Expand Down Expand Up @@ -2203,6 +2204,28 @@ export class BaseClient {
return this.createWritePromise(createBrpop(keys, timeout));
}

/** Adds all elements to the HyperLogLog data structure stored at the specified `key`.
* Creates a new structure if the `key` does not exist.
* When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed.
*
* See https://redis.io/commands/pfadd/ for more details.
*
* @param key - The key of the HyperLogLog data structure to add elements into.
* @param elements - An array of members to add to the HyperLogLog stored at `key`.
* @returns - If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is
* altered, then returns `1`. Otherwise, returns `0`.
* @example
* ```typescript
* const result = await client.pfadd("hll_1", ["a", "b", "c"]);
* console.log(result); // Output: 1 - Indicates that a data structure was created or modified
* const result = await client.pfadd("hll_2", []);
* console.log(result); // Output: 1 - Indicates that a new empty data structure was created
* ```
*/
public pfadd(key: string, elements: string[]): Promise<number> {
return this.createWritePromise(createPfAdd(key, elements));
}

/**
* @internal
*/
Expand Down
11 changes: 11 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1287,3 +1287,14 @@ export function createRename(
): redis_request.Command {
return createCommand(RequestType.Rename, [key, newKey]);
}

/**
* @internal
*/
export function createPfAdd(
key: string,
elements: string[],
): redis_request.Command {
const args = [key, ...elements];
return createCommand(RequestType.PfAdd, args);
}
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 {
createPExpire,
createPExpireAt,
createPersist,
createPfAdd,
createPing,
createPttl,
createRPop,
Expand Down Expand Up @@ -1258,6 +1259,21 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
public brpop(keys: string[], timeout: number): T {
return this.addAndReturn(createBrpop(keys, timeout));
}

/** Adds all elements to the HyperLogLog data structure stored at the specified `key`.
* Creates a new structure if the `key` does not exist.
* When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed.
*
* See https://redis.io/commands/pfadd/ for more details.
*
* @param key - The key of the HyperLogLog data structure to add elements into.
* @param elements - An array of members to add to the HyperLogLog stored at `key`.
* Command Response - If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is
* altered, then returns `1`. Otherwise, returns `0`.
*/
public pfadd(key: string, elements: string[]): T {
return this.addAndReturn(createPfAdd(key, elements));
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion node/tests/RedisClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Context = {
client: RedisClient;
};

const TIMEOUT = 10000;
const TIMEOUT = 50000;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a total IT timeout, 10 sec is too low. Sometimes it runs longer and causes test failures.


describe("RedisClient", () => {
let testsFailed = 0;
Expand Down
20 changes: 19 additions & 1 deletion node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2278,13 +2278,31 @@ export function runBaseTests<Context>(config: {
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
// If key doesn't exist it should throw, it also test that key has successfully been renamed
await expect(client.rename(key, newKey)).rejects.toThrow();
client.close();
}, protocol);
},
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"pfadd test_%p",
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key = uuidv4();
expect(await client.pfadd(key, [])).toEqual(1);
expect(await client.pfadd(key, ["one", "two"])).toEqual(1);
expect(await client.pfadd(key, ["two"])).toEqual(0);
expect(await client.pfadd(key, [])).toEqual(0);

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

export function runCommonTests<Context>(config: {
Expand Down
3 changes: 3 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export async function transactionTest(
const key8 = "{key}" + uuidv4();
const key9 = "{key}" + uuidv4();
const key10 = "{key}" + uuidv4();
const key11 = "{key}" + uuidv4(); // hyper log log
const field = uuidv4();
const value = uuidv4();
const args: ReturnType[] = [];
Expand Down Expand Up @@ -217,6 +218,8 @@ export async function transactionTest(
args.push(3);
baseTransaction.brpop([key6], 0.1);
args.push([key6, field + "3"]);
baseTransaction.pfadd(key11, ["a", "b", "c"]);
args.push(1);
return args;
}

Expand Down
Loading