Skip to content

Commit

Permalink
Node: added OBJECT ENCODING command (valkey-io#1518)
Browse files Browse the repository at this point in the history
* Node: added OBJECT ENCODING command (#338)

* Updated CHANGELOG.md
  • Loading branch information
yipin-chen committed Jun 7, 2024
1 parent 14ef037 commit a06c348
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Python: Added ZINTER, ZUNION commands ([#1478](https://github.com/aws/glide-for-redis/pull/1478))
* Python: Added SINTERCARD command ([#1511](https://github.com/aws/glide-for-redis/pull/1511))
* Python: Added SORT command ([#1439](https://github.com/aws/glide-for-redis/pull/1439))
* Node: Added OBJECT ENCODING command ([#1518](https://github.com/aws/glide-for-redis/pull/1518))

### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/aws/glide-for-redis/pull/1494))
Expand Down
18 changes: 18 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
createLTrim,
createMGet,
createMSet,
createObjectEncoding,
createPExpire,
createPExpireAt,
createPTTL,
Expand Down Expand Up @@ -2400,6 +2401,23 @@ export class BaseClient {
return this.createWritePromise(createPfCount(keys));
}

/** Returns the internal encoding for the Redis object stored at `key`.
*
* See https://valkey.io/commands/object-encoding for more details.
*
* @param key - The `key` of the object to get the internal encoding of.
* @returns - If `key` exists, returns the internal encoding of the object stored at `key` as a string.
* Otherwise, returns None.
* @example
* ```typescript
* const result = await client.object_encoding("my_hash");
* console.log(result); // Output: "listpack"
* ```
*/
public object_encoding(key: string): Promise<string | null> {
return this.createWritePromise(createObjectEncoding(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 @@ -1375,3 +1375,10 @@ export function createPfAdd(
export function createPfCount(keys: string[]): redis_request.Command {
return createCommand(RequestType.PfCount, keys);
}

/**
* @internal
*/
export function createObjectEncoding(key: string): redis_request.Command {
return createCommand(RequestType.ObjectEncoding, [key]);
}
13 changes: 13 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
createLTrim,
createMGet,
createMSet,
createObjectEncoding,
createPExpire,
createPExpireAt,
createPTTL,
Expand Down Expand Up @@ -1365,6 +1366,18 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
public pfcount(keys: string[]): T {
return this.addAndReturn(createPfCount(keys));
}

/** Returns the internal encoding for the Redis object stored at `key`.
*
* See https://valkey.io/commands/object-encoding for more details.
*
* @param key - The `key` of the object to get the internal encoding of.
* Command Response - If `key` exists, returns the internal encoding of the object stored at `key` as a string.
* Otherwise, returns None.
*/
public object_encoding(key: string): T {
return this.addAndReturn(createObjectEncoding(key));
}
}

/**
Expand Down
143 changes: 143 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2732,6 +2732,149 @@ export function runBaseTests<Context>(config: {
},
config.timeout,
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"object encoding test_%p",
async (protocol) => {
await runTest(async (client: BaseClient) => {
const string_key = uuidv4();
const list_key = uuidv4();
const hashtable_key = uuidv4();
const intset_key = uuidv4();
const set_listpack_key = uuidv4();
const hash_hashtable_key = uuidv4();
const hash_listpack_key = uuidv4();
const skiplist_key = uuidv4();
const zset_listpack_key = uuidv4();
const stream_key = uuidv4();
const non_existing_key = uuidv4();
const versionLessThan7 =
await checkIfServerVersionLessThan("7.0.0");
const versionLessThan72 =
await checkIfServerVersionLessThan("7.2.0");

expect(await client.object_encoding(non_existing_key)).toEqual(
null,
);

expect(
await client.set(
string_key,
"a really loooooooooooooooooooooooooooooooooooooooong value",
),
).toEqual("OK");
expect(await client.object_encoding(string_key)).toEqual("raw");

expect(await client.set(string_key, "2")).toEqual("OK");
expect(await client.object_encoding(string_key)).toEqual("int");

expect(await client.set(string_key, "value")).toEqual("OK");
expect(await client.object_encoding(string_key)).toEqual(
"embstr",
);

expect(await client.lpush(list_key, ["1"])).toEqual(1);

if (versionLessThan7) {
expect(await client.object_encoding(list_key)).toEqual(
"quicklist",
);
} else {
expect(await client.object_encoding(list_key)).toEqual(
"listpack",
);
}

// The default value of set-max-intset-entries is 512
for (let i = 0; i < 513; i++) {
expect(
await client.sadd(hashtable_key, [String(i)]),
).toEqual(1);
}

expect(await client.object_encoding(hashtable_key)).toEqual(
"hashtable",
);

expect(await client.sadd(intset_key, ["1"])).toEqual(1);
expect(await client.object_encoding(intset_key)).toEqual(
"intset",
);

expect(await client.sadd(set_listpack_key, ["foo"])).toEqual(1);

if (versionLessThan72) {
expect(
await client.object_encoding(set_listpack_key),
).toEqual("hashtable");
} else {
expect(
await client.object_encoding(set_listpack_key),
).toEqual("listpack");
}

// The default value of hash-max-listpack-entries is 512
for (let i = 0; i < 513; i++) {
expect(
await client.hset(hash_hashtable_key, {
[String(i)]: "2",
}),
).toEqual(1);
}

expect(
await client.object_encoding(hash_hashtable_key),
).toEqual("hashtable");

expect(
await client.hset(hash_listpack_key, { "1": "2" }),
).toEqual(1);

if (versionLessThan7) {
expect(
await client.object_encoding(hash_listpack_key),
).toEqual("ziplist");
} else {
expect(
await client.object_encoding(hash_listpack_key),
).toEqual("listpack");
}

// The default value of zset-max-listpack-entries is 128
for (let i = 0; i < 129; i++) {
expect(
await client.zadd(skiplist_key, { [String(i)]: 2.0 }),
).toEqual(1);
}

expect(await client.object_encoding(skiplist_key)).toEqual(
"skiplist",
);

expect(
await client.zadd(zset_listpack_key, { "1": 2.0 }),
).toEqual(1);

if (versionLessThan7) {
expect(
await client.object_encoding(zset_listpack_key),
).toEqual("ziplist");
} else {
expect(
await client.object_encoding(zset_listpack_key),
).toEqual("listpack");
}

expect(
await client.xadd(stream_key, [["field", "value"]]),
).not.toBeNull();
expect(await client.object_encoding(stream_key)).toEqual(
"stream",
);
}, protocol);
},
config.timeout,
);
}

export function runCommonTests<Context>(config: {
Expand Down
2 changes: 2 additions & 0 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ export async function transactionTest(
const args: ReturnType[] = [];
baseTransaction.set(key1, "bar");
args.push("OK");
baseTransaction.object_encoding(key1);
args.push("embstr");
baseTransaction.type(key1);
args.push("string");
baseTransaction.echo(value);
Expand Down

0 comments on commit a06c348

Please sign in to comment.