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

Added transaction supports for DUMP and RESTORE #2159

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 @@ -69,6 +69,7 @@
* Node: Added WATCH and UNWATCH commands ([#2076](https:/valkey-io/valkey-glide/pull/2076))
* Node: Added WAIT command ([#2113](https:/valkey-io/valkey-glide/pull/2113))
* Node: Added DUMP and RESTORE commands ([#2126](https:/valkey-io/valkey-glide/pull/2126))
* Node: Added transaction supports for DUMP and RESTORE ([#2159](https:/valkey-io/valkey-glide/pull/2159))
* Node: Added ZLEXCOUNT command ([#2022](https:/valkey-io/valkey-glide/pull/2022))
* Node: Added ZREMRANGEBYLEX command ([#2025](https:/valkey-io/valkey-glide/pull/2025))
* Node: Added ZRANGESTORE command ([#2068](https:/valkey-io/valkey-glide/pull/2068))
Expand Down
4 changes: 2 additions & 2 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ export class BaseClient {
/**
* Serialize the value stored at `key` in a Valkey-specific format and return it to the user.
*
* @See {@link https://valkey.io/commands/dump/|valkey.io} for details.
* @see {@link https://valkey.io/commands/dump/|valkey.io} for details.
*
* @param key - The `key` to serialize.
* @returns The serialized value of the data stored at `key`. If `key` does not exist, `null` will be returned.
Expand All @@ -1135,7 +1135,7 @@ export class BaseClient {
* Create a `key` associated with a `value` that is obtained by deserializing the provided
* serialized `value` (obtained via {@link dump}).
*
* @See {@link https://valkey.io/commands/restore/|valkey.io} for details.
* @see {@link https://valkey.io/commands/restore/|valkey.io} for details.
* @remarks `options.idletime` and `options.frequency` modifiers cannot be set at the same time.
*
* @param key - The `key` to create.
Expand Down
41 changes: 40 additions & 1 deletion node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import {
BaseClient, // eslint-disable-line @typescript-eslint/no-unused-vars
Decoder, // eslint-disable-line @typescript-eslint/no-unused-vars
GlideString,
ReadFrom, // eslint-disable-line @typescript-eslint/no-unused-vars
} from "./BaseClient";
Expand Down Expand Up @@ -47,6 +46,7 @@ import {
RangeByIndex,
RangeByLex,
RangeByScore,
RestoreOptions,
ReturnTypeXinfoStream, // eslint-disable-line @typescript-eslint/no-unused-vars
ScoreFilter,
SearchOrigin,
Expand Down Expand Up @@ -86,6 +86,7 @@ import {
createDecr,
createDecrBy,
createDel,
createDump,
createEcho,
createExists,
createExpire,
Expand Down Expand Up @@ -175,6 +176,7 @@ import {
createRandomKey,
createRename,
createRenameNX,
createRestore,
createSAdd,
createSCard,
createSDiff,
Expand Down Expand Up @@ -417,6 +419,43 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createDel(keys));
}

/**
* Serialize the value stored at `key` in a Valkey-specific format and return it to the user.
*
* @see {@link https://valkey.io/commands/dump/|valkey.io} for details.
* @remarks To execute a transaction with a `dump` command, the `exec` command requires `Decoder.Bytes` to handle the response.
*
* @param key - The `key` to serialize.
*
* Command Response - The serialized value of the data stored at `key`. If `key` does not exist, `null` will be returned.
yipin-chen marked this conversation as resolved.
Show resolved Hide resolved
*/
public dump(key: GlideString): T {
return this.addAndReturn(createDump(key));
}

/**
* Create a `key` associated with a `value` that is obtained by deserializing the provided
* serialized `value` (obtained via {@link dump}).
*
* @see {@link https://valkey.io/commands/restore/|valkey.io} for details.
* @remarks `options.idletime` and `options.frequency` modifiers cannot be set at the same time.
*
* @param key - The `key` to create.
* @param ttl - The expiry time (in milliseconds). If `0`, the `key` will persist.
* @param value - The serialized value to deserialize and assign to `key`.
* @param options - (Optional) Restore options {@link RestoreOptions}.
*
* Command Response - Return "OK" if the `key` was successfully restored with a `value`.
yipin-chen marked this conversation as resolved.
Show resolved Hide resolved
*/
public restore(
key: GlideString,
ttl: number,
value: Buffer,
options?: RestoreOptions,
): T {
return this.addAndReturn(createRestore(key, ttl, value, options));
}

/** Get the name of the connection on which the transaction is being executed.
* @see {@link https://valkey.io/commands/client-getname/|valkey.io} for details.
*
Expand Down
54 changes: 53 additions & 1 deletion node/tests/SharedTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6244,6 +6244,8 @@ export function runBaseTests(config: {
const key1 = "{key}-1" + uuidv4();
const key2 = "{key}-2" + uuidv4();
const key3 = "{key}-3" + uuidv4();
const key4 = "{key}-4" + uuidv4();
const key5 = "{key}-5" + uuidv4();
const nonExistingkey = "{nonExistingkey}-" + uuidv4();
const value = "orange";
const valueEncode = Buffer.from(value);
Expand All @@ -6254,7 +6256,7 @@ export function runBaseTests(config: {
expect(await client.dump(nonExistingkey)).toBeNull();

// Dump existing key
const data = (await client.dump(key1)) as Buffer;
let data = (await client.dump(key1)) as Buffer;
expect(data).not.toBeNull();

// Restore to a new key without option
Expand Down Expand Up @@ -6342,6 +6344,56 @@ export function runBaseTests(config: {
await expect(
client.restore(key2, 0, valueEncode, { replace: true }),
).rejects.toThrow("DUMP payload version or checksum are wrong");

// Transaction tests
let response =
client instanceof GlideClient
? await client.exec(
new Transaction().dump(key1),
Decoder.Bytes,
)
: await client.exec(
new ClusterTransaction().dump(key1),
{ decoder: Decoder.Bytes },
);
expect(response?.[0]).not.toBeNull();
data = response?.[0] as Buffer;

// Restore with `String` exec decoder
response =
client instanceof GlideClient
? await client.exec(
new Transaction()
.restore(key4, 0, data)
.get(key4),
Decoder.String,
)
: await client.exec(
new ClusterTransaction()
.restore(key4, 0, data)
.get(key4),
{ decoder: Decoder.String },
);
expect(response?.[0]).toEqual("OK");
expect(response?.[1]).toEqual(value);

// Restore with `Bytes` exec decoder
response =
client instanceof GlideClient
? await client.exec(
new Transaction()
.restore(key5, 0, data)
.get(key5),
Decoder.Bytes,
)
: await client.exec(
new ClusterTransaction()
.restore(key5, 0, data)
.get(key5),
{ decoder: Decoder.Bytes },
);
expect(response?.[0]).toEqual("OK");
expect(response?.[1]).toEqual(valueEncode);
}, protocol);
},
config.timeout,
Expand Down
Loading