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: added OBJECT ENCODING command #1518

Merged
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 @@ -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 @@ -2380,6 +2381,23 @@ export class BaseClient {
return this.createWritePromise(createPfAdd(key, elements));
}

/** 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 @@ -1368,3 +1368,10 @@ export function createPfAdd(
const args = [key, ...elements];
return createCommand(RequestType.PfAdd, args);
}

/**
* @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 @@ -1351,6 +1352,18 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
public pfadd(key: string, elements: string[]): T {
return this.addAndReturn(createPfAdd(key, elements));
}

/** 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 @@ -2701,6 +2701,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
Loading