Skip to content

Commit

Permalink
Node: add OBJECT REFCOUNT command (#1568)
Browse files Browse the repository at this point in the history
* Node: add OBJECT REFCOUNT command

* PR suggestions
  • Loading branch information
aaron-congo authored Jun 13, 2024
1 parent 850fc10 commit aa02c37
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* Node: Added ZINTERCARD command ([#1553](https://github.com/aws/glide-for-redis/pull/1553))
* Python: Added LMPOP and BLMPOP commands ([#1547](https://github.com/aws/glide-for-redis/pull/1547))
* Node: Added OBJECT IDLETIME command ([#1567](https://github.com/aws/glide-for-redis/pull/1567))
* Node: Added OBJECT REFCOUNT command ([#1568](https://github.com/aws/glide-for-redis/pull/1568))

### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/aws/glide-for-redis/pull/1494))
Expand Down
20 changes: 20 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import {
createXLen,
createZInterCard,
createObjectIdletime,
createObjectRefcount,
} from "./Commands";
import {
ClosingError,
Expand Down Expand Up @@ -2593,6 +2594,25 @@ export class BaseClient {
return this.createWritePromise(createObjectIdletime(key));
}

/**
* Returns the reference count of the object stored at `key`.
*
* See https://valkey.io/commands/object-refcount/ for more details.
*
* @param key - The `key` of the object to get the reference count of.
* @returns If `key` exists, returns the reference count of the object stored at `key` as a `number`.
* Otherwise, returns `null`.
*
* @example
* ```typescript
* const result = await client.objectRefcount("my_hash");
* console.log(result); // Output: 2 - "my_hash" has a reference count of 2.
* ```
*/
public objectRefcount(key: string): Promise<number | null> {
return this.createWritePromise(createObjectRefcount(key));
}

/**
* @internal
*/
Expand Down
7 changes: 7 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1500,3 +1500,10 @@ export function createObjectFreq(key: string): redis_request.Command {
export function createObjectIdletime(key: string): redis_request.Command {
return createCommand(RequestType.ObjectIdleTime, [key]);
}

/**
* @internal
*/
export function createObjectRefcount(key: string): redis_request.Command {
return createCommand(RequestType.ObjectRefCount, [key]);
}
15 changes: 15 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ import {
createXLen,
createZInterCard,
createObjectIdletime,
createObjectRefcount,
} from "./Commands";
import { redis_request } from "./ProtobufMessage";

Expand Down Expand Up @@ -1507,6 +1508,20 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
public objectIdletime(key: string): T {
return this.addAndReturn(createObjectIdletime(key));
}

/**
* Returns the reference count of the object stored at `key`.
*
* See https://valkey.io/commands/object-refcount/ for more details.
*
* @param key - The `key` of the object to get the reference count of.
*
* Command Response - If `key` exists, returns the reference count of the object stored at `key` as a `number`.
* Otherwise, returns `null`.
*/
public objectRefcount(key: string): T {
return this.addAndReturn(createObjectRefcount(key));
}
}

/**
Expand Down
25 changes: 25 additions & 0 deletions node/tests/RedisClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,31 @@ describe("RedisClient", () => {
},
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"object refcount transaction test_%p",
async (protocol) => {
const client = await RedisClient.createClient(
getClientConfigurationOption(cluster.getAddresses(), protocol),
);

const key = uuidv4();
const transaction = new Transaction();
transaction.set(key, "foo");
transaction.objectRefcount(key);

const response = await client.exec(transaction);
expect(response).not.toBeNull();

if (response != null) {
expect(response.length).toEqual(2);
expect(response[0]).toEqual("OK"); // transaction.set(key, "foo");
expect(response[1]).toBeGreaterThanOrEqual(1); // transaction.objectRefcount(key);
}

client.close();
},
);

runBaseTests<Context>({
init: async (protocol, clientName?) => {
const options = getClientConfigurationOption(
Expand Down
25 changes: 25 additions & 0 deletions node/tests/RedisClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,4 +417,29 @@ describe("RedisClusterClient", () => {
client.close();
},
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"object refcount transaction test_%p",
async (protocol) => {
const client = await RedisClusterClient.createClient(
getClientConfigurationOption(cluster.getAddresses(), protocol),
);

const key = uuidv4();
const transaction = new ClusterTransaction();
transaction.set(key, "foo");
transaction.objectRefcount(key);

const response = await client.exec(transaction);
expect(response).not.toBeNull();

if (response != null) {
expect(response.length).toEqual(2);
expect(response[0]).toEqual("OK"); // transaction.set(key, "foo");
expect(response[1]).toBeGreaterThanOrEqual(1); // transaction.objectRefcount(key);
}

client.close();
},
);
});
17 changes: 17 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3297,6 +3297,23 @@ export function runBaseTests<Context>(config: {
setTimeout(resolve, numMilliseconds);
});
}

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

expect(await client.objectRefcount(nonExistingKey)).toBeNull();
expect(await client.set(key, "foo")).toEqual("OK");
expect(await client.objectRefcount(key)).toBeGreaterThanOrEqual(
1,
);
}, protocol);
},
config.timeout,
);
}

export function runCommonTests<Context>(config: {
Expand Down

0 comments on commit aa02c37

Please sign in to comment.