Skip to content

Commit

Permalink
Node: add bytes support to append getrange hget mget hvals (valkey-io…
Browse files Browse the repository at this point in the history
…#2150)

* change signatures of append, getrange, hget, hvals, mget

Signed-off-by: lior sventitzky <liorsve@amazon.com>

* node: change test getrange

Signed-off-by: lior sventitzky <liorsve@amazon.com>

* node: change append hvals mget to bytes

Signed-off-by: lior sventitzky <liorsve@amazon.com>

* fix lint

Signed-off-by: lior sventitzky <liorsve@amazon.com>

* change hget field type and decoder docs

Signed-off-by: lior sventitzky <liorsve@amazon.com>

---------

Signed-off-by: lior sventitzky <liorsve@amazon.com>
  • Loading branch information
liorsve authored Aug 19, 2024
1 parent 048812b commit 850a265
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 17 deletions.
39 changes: 29 additions & 10 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ export class BaseClient {
* @param key - The key of the string.
* @param start - The starting offset.
* @param end - The ending offset.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
* @returns A substring extracted from the value stored at `key`.
*
* @example
Expand All @@ -1026,11 +1027,14 @@ export class BaseClient {
* ```
*/
public async getrange(
key: string,
key: GlideString,
start: number,
end: number,
): Promise<string | null> {
return this.createWritePromise(createGetRange(key, start, end));
decoder?: Decoder,
): Promise<GlideString | null> {
return this.createWritePromise(createGetRange(key, start, end), {
decoder: decoder,
});
}

/** Set the given key with the given value. Return value is dependent on the passed options.
Expand Down Expand Up @@ -1178,6 +1182,7 @@ export class BaseClient {
* @remarks When in cluster mode, the command may route to multiple nodes when `keys` map to different hash slots.
*
* @param keys - A list of keys to retrieve values for.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
* @returns A list of values corresponding to the provided keys. If a key is not found,
* its corresponding value in the list will be null.
*
Expand All @@ -1190,8 +1195,11 @@ export class BaseClient {
* console.log(result); // Output: ['value1', 'value2']
* ```
*/
public async mget(keys: string[]): Promise<(string | null)[]> {
return this.createWritePromise(createMGet(keys));
public async mget(
keys: GlideString[],
decoder?: Decoder,
): Promise<(GlideString | null)[]> {
return this.createWritePromise(createMGet(keys), { decoder: decoder });
}

/** Set multiple keys to multiple values in a single operation.
Expand Down Expand Up @@ -1562,6 +1570,7 @@ export class BaseClient {
*
* @param key - The key of the hash.
* @param field - The field in the hash stored at `key` to retrieve from the database.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
* @returns the value associated with `field`, or null when `field` is not present in the hash or `key` does not exist.
*
* @example
Expand All @@ -1579,8 +1588,14 @@ export class BaseClient {
* console.log(result); // Output: null
* ```
*/
public async hget(key: string, field: string): Promise<string | null> {
return this.createWritePromise(createHGet(key, field));
public async hget(
key: GlideString,
field: GlideString,
decoder?: Decoder,
): Promise<GlideString | null> {
return this.createWritePromise(createHGet(key, field), {
decoder: decoder,
});
}

/** Sets the specified fields to their respective values in the hash stored at `key`.
Expand Down Expand Up @@ -1831,6 +1846,7 @@ export class BaseClient {
* @see {@link https://valkey.io/commands/hvals/|valkey.io} for more details.
*
* @param key - The key of the hash.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
* @returns a list of values in the hash, or an empty list when the key does not exist.
*
* @example
Expand All @@ -1840,8 +1856,11 @@ export class BaseClient {
* console.log(result); // Output: ["value1", "value2", "value3"] - Returns all the values stored in the hash "my_hash".
* ```
*/
public async hvals(key: string): Promise<string[]> {
return this.createWritePromise(createHVals(key));
public async hvals(
key: GlideString,
decoder?: Decoder,
): Promise<GlideString[]> {
return this.createWritePromise(createHVals(key), { decoder: decoder });
}

/**
Expand Down Expand Up @@ -5974,7 +5993,7 @@ export class BaseClient {
* // new value of "Hello world" with a length of 11.
* ```
*/
public async append(key: string, value: string): Promise<number> {
public async append(key: GlideString, value: GlideString): Promise<number> {
return this.createWritePromise(createAppend(key, value));
}

Expand Down
14 changes: 7 additions & 7 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function createGetDel(key: GlideString): command_request.Command {
* @internal
*/
export function createGetRange(
key: string,
key: GlideString,
start: number,
end: number,
): command_request.Command {
Expand Down Expand Up @@ -320,7 +320,7 @@ export function createConfigResetStat(): command_request.Command {
/**
* @internal
*/
export function createMGet(keys: string[]): command_request.Command {
export function createMGet(keys: GlideString[]): command_request.Command {
return createCommand(RequestType.MGet, keys);
}

Expand Down Expand Up @@ -402,8 +402,8 @@ export function createConfigSet(
* @internal
*/
export function createHGet(
key: string,
field: string,
key: GlideString,
field: GlideString,
): command_request.Command {
return createCommand(RequestType.HGet, [key, field]);
}
Expand Down Expand Up @@ -1221,7 +1221,7 @@ export function createHLen(key: string): command_request.Command {
/**
* @internal
*/
export function createHVals(key: string): command_request.Command {
export function createHVals(key: GlideString): command_request.Command {
return createCommand(RequestType.HVals, [key]);
}

Expand Down Expand Up @@ -3623,8 +3623,8 @@ export function createSetRange(

/** @internal */
export function createAppend(
key: string,
value: string,
key: GlideString,
value: GlideString,
): command_request.Command {
return createCommand(RequestType.Append, [key, value]);
}
Expand Down
65 changes: 65 additions & 0 deletions node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,21 @@ export function runBaseTests<Context>(config: {
[key2]: value,
[key3]: value,
};
const valueEncoded = Buffer.from(value);

expect(await client.mset(keyValueList)).toEqual("OK");
expect(
await client.mget([key1, key2, "nonExistingKey", key3]),
).toEqual([value, value, null, value]);

//mget with binary buffers
expect(await client.mset(keyValueList)).toEqual("OK");
expect(
await client.mget(
[key1, key2, "nonExistingKey", key3],
Decoder.Bytes,
),
).toEqual([valueEncoded, valueEncoded, null, valueEncoded]);
}, protocol);
},
config.timeout,
Expand Down Expand Up @@ -1217,6 +1228,7 @@ export function runBaseTests<Context>(config: {
await runTest(async (client: BaseClient, cluster) => {
const key = uuidv4();
const nonStringKey = uuidv4();
const valueEncoded = Buffer.from("This is a string");

expect(await client.set(key, "This is a string")).toEqual("OK");
expect(await client.getrange(key, 0, 3)).toEqual("This");
Expand All @@ -1225,6 +1237,18 @@ export function runBaseTests<Context>(config: {
"This is a string",
);

// range of binary buffer
expect(await client.set(key, "This is a string")).toEqual("OK");
expect(await client.getrange(key, 0, 3, Decoder.Bytes)).toEqual(
valueEncoded.subarray(0, 4),
);
expect(
await client.getrange(key, -3, -1, Decoder.Bytes),
).toEqual(valueEncoded.subarray(-3, valueEncoded.length));
expect(
await client.getrange(key, 0, -1, Decoder.Bytes),
).toEqual(valueEncoded.subarray(0, valueEncoded.length));

// out of range
expect(await client.getrange(key, 10, 100)).toEqual("string");
expect(await client.getrange(key, -200, -3)).toEqual(
Expand Down Expand Up @@ -1267,12 +1291,25 @@ export function runBaseTests<Context>(config: {
[field1]: value,
[field2]: value,
};
const valueEncoded = Buffer.from(value);

expect(await client.hset(key, fieldValueMap)).toEqual(2);
expect(await client.hget(key, field1)).toEqual(value);
expect(await client.hget(key, field2)).toEqual(value);
expect(await client.hget(key, "nonExistingField")).toEqual(
null,
);

//hget with binary buffer
expect(await client.hget(key, field1, Decoder.Bytes)).toEqual(
valueEncoded,
);
expect(await client.hget(key, field2, Decoder.Bytes)).toEqual(
valueEncoded,
);
expect(
await client.hget(key, "nonExistingField", Decoder.Bytes),
).toEqual(null);
}, protocol);
},
config.timeout,
Expand Down Expand Up @@ -1765,18 +1802,33 @@ export function runBaseTests<Context>(config: {
async (protocol) => {
await runTest(async (client: BaseClient) => {
const key1 = uuidv4();
const key2 = uuidv4();
const field1 = uuidv4();
const field2 = uuidv4();
const fieldValueMap = {
[field1]: "value1",
[field2]: "value2",
};

const value1Encoded = Buffer.from("value1");
const value2Encoded = Buffer.from("value2");

expect(await client.hset(key1, fieldValueMap)).toEqual(2);
expect(await client.hvals(key1)).toEqual(["value1", "value2"]);
expect(await client.hdel(key1, [field1])).toEqual(1);
expect(await client.hvals(key1)).toEqual(["value2"]);
expect(await client.hvals("nonExistingHash")).toEqual([]);

//hvals with binary buffers
expect(await client.hset(key2, fieldValueMap)).toEqual(2);
expect(await client.hvals(key2, Decoder.Bytes)).toEqual([
value1Encoded,
value2Encoded,
]);
expect(await client.hdel(key2, [field1])).toEqual(1);
expect(await client.hvals(key2, Decoder.Bytes)).toEqual([
value2Encoded,
]);
}, protocol);
},
config.timeout,
Expand Down Expand Up @@ -6026,7 +6078,9 @@ export function runBaseTests<Context>(config: {
await runTest(async (client: BaseClient) => {
const key1 = uuidv4();
const key2 = uuidv4();
const key3 = uuidv4();
const value = uuidv4();
const valueEncoded = Buffer.from(value);

// Append on non-existing string(similar to SET)
expect(await client.append(key1, value)).toBe(value.length);
Expand All @@ -6038,6 +6092,17 @@ export function runBaseTests<Context>(config: {
await expect(client.append(key2, "_")).rejects.toThrow(
RequestError,
);

// Key and value as buffers
expect(await client.append(key3, valueEncoded)).toBe(
value.length,
);
expect(await client.append(key3, valueEncoded)).toBe(
valueEncoded.length * 2,
);
expect(await client.get(key3, Decoder.Bytes)).toEqual(
Buffer.concat([valueEncoded, valueEncoded]),
);
}, protocol);
},
config.timeout,
Expand Down

0 comments on commit 850a265

Please sign in to comment.