Skip to content

Commit 01ca54e

Browse files
Moshe-RSleibale
andauthored
fix #1970 - add support for RESTORE (#2535)
* - Added RESTORE functionality * add FIRST_KEY_INDEX, fix tests, clean example, add example to examples table * use returnBuffers in test --------- Co-authored-by: Leibale Eidelman <[email protected]>
1 parent 8ecfd3e commit 01ca54e

File tree

5 files changed

+140
-1
lines changed

5 files changed

+140
-1
lines changed

examples/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This folder contains example scripts showing how to use Node Redis in different scenarios.
44

55
| File Name | Description |
6-
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
6+
|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
77
| `blocking-list-pop.js` | Block until an element is pushed to a list. |
88
| `bloom-filter.js` | Space efficient set membership checks with a [Bloom Filter](https://en.wikipedia.org/wiki/Bloom_filter) using [RedisBloom](https://redisbloom.io). |
99
| `check-connection-status.js` | Check the client's connection status. |
@@ -12,6 +12,7 @@ This folder contains example scripts showing how to use Node Redis in different
1212
| `connect-to-cluster.js` | Connect to a Redis cluster. |
1313
| `count-min-sketch.js` | Estimate the frequency of a given event using the [RedisBloom](https://redisbloom.io) Count-Min Sketch. |
1414
| `cuckoo-filter.js` | Space efficient set membership checks with a [Cuckoo Filter](https://en.wikipedia.org/wiki/Cuckoo_filter) using [RedisBloom](https://redisbloom.io). |
15+
| `dump-and-restore.js` | Demonstrates the use of the [`DUMP`](https://redis.io/commands/dump/) and [`RESTORE`](https://redis.io/commands/restore/) commands |
1516
| `get-server-time.js` | Get the time from the Redis server. |
1617
| `hyperloglog.js` | Showing use of Hyperloglog commands [PFADD, PFCOUNT and PFMERGE](https://redis.io/commands/?group=hyperloglog). |
1718
| `lua-multi-incr.js` | Define a custom lua script that allows you to perform INCRBY on multiple keys. |

examples/dump-and-restore.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// This example demonstrates the use of the DUMP and RESTORE commands
2+
3+
import { commandOptions, createClient } from 'redis';
4+
5+
const client = createClient();
6+
await client.connect();
7+
8+
// DUMP a specific key into a local variable
9+
const dump = await client.dump(
10+
commandOptions({ returnBuffers: true }),
11+
'source'
12+
);
13+
14+
// RESTORE into a new key
15+
await client.restore('destination', 0, dump);
16+
17+
// RESTORE and REPLACE an existing key
18+
await client.restore('destination', 0, dump, {
19+
REPLACE: true
20+
});
21+
22+
await client.quit();

packages/client/lib/cluster/commands.ts

+3
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import * as PTTL from '../commands/PTTL';
110110
import * as PUBLISH from '../commands/PUBLISH';
111111
import * as RENAME from '../commands/RENAME';
112112
import * as RENAMENX from '../commands/RENAMENX';
113+
import * as RESTORE from '../commands/RESTORE';
113114
import * as RPOP_COUNT from '../commands/RPOP_COUNT';
114115
import * as RPOP from '../commands/RPOP';
115116
import * as RPOPLPUSH from '../commands/RPOPLPUSH';
@@ -434,6 +435,8 @@ export default {
434435
rename: RENAME,
435436
RENAMENX,
436437
renameNX: RENAMENX,
438+
RESTORE,
439+
restore: RESTORE,
437440
RPOP_COUNT,
438441
rPopCount: RPOP_COUNT,
439442
RPOP,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import { transformArguments } from './RESTORE';
4+
5+
describe('RESTORE', () => {
6+
describe('transformArguments', () => {
7+
it('simple', () => {
8+
assert.deepEqual(
9+
transformArguments('key', 0, 'value'),
10+
['RESTORE', 'key', '0', 'value']
11+
);
12+
});
13+
14+
it('with REPLACE', () => {
15+
assert.deepEqual(
16+
transformArguments('key', 0, 'value', {
17+
REPLACE: true
18+
}),
19+
['RESTORE', 'key', '0', 'value', 'REPLACE']
20+
);
21+
});
22+
23+
it('with ABSTTL', () => {
24+
assert.deepEqual(
25+
transformArguments('key', 0, 'value', {
26+
ABSTTL: true
27+
}),
28+
['RESTORE', 'key', '0', 'value', 'ABSTTL']
29+
);
30+
});
31+
32+
it('with IDLETIME', () => {
33+
assert.deepEqual(
34+
transformArguments('key', 0, 'value', {
35+
IDLETIME: 1
36+
}),
37+
['RESTORE', 'key', '0', 'value', 'IDLETIME', '1']
38+
);
39+
});
40+
41+
it('with FREQ', () => {
42+
assert.deepEqual(
43+
transformArguments('key', 0, 'value', {
44+
FREQ: 1
45+
}),
46+
['RESTORE', 'key', '0', 'value', 'FREQ', '1']
47+
);
48+
});
49+
50+
it('with REPLACE, ABSTTL, IDLETIME and FREQ', () => {
51+
assert.deepEqual(
52+
transformArguments('key', 0, 'value', {
53+
REPLACE: true,
54+
ABSTTL: true,
55+
IDLETIME: 1,
56+
FREQ: 2
57+
}),
58+
['RESTORE', 'key', '0', 'value', 'REPLACE', 'ABSTTL', 'IDLETIME', '1', 'FREQ', '2']
59+
);
60+
});
61+
});
62+
63+
testUtils.testWithClient('client.restore', async client => {
64+
const [, dump] = await Promise.all([
65+
client.set('source', 'value'),
66+
client.dump(client.commandOptions({ returnBuffers: true }), 'source')
67+
]);
68+
69+
assert.equal(
70+
await client.restore('destination', 0, dump),
71+
'OK'
72+
);
73+
}, GLOBAL.SERVERS.OPEN);
74+
});
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '.';
2+
3+
export const FIRST_KEY_INDEX = 1;
4+
5+
interface RestoreOptions {
6+
REPLACE?: true;
7+
ABSTTL?: true;
8+
IDLETIME?: number;
9+
FREQ?: number;
10+
}
11+
12+
export function transformArguments(
13+
key: RedisCommandArgument,
14+
ttl: number,
15+
serializedValue: RedisCommandArgument,
16+
options?: RestoreOptions
17+
): RedisCommandArguments {
18+
const args = ['RESTORE', key, ttl.toString(), serializedValue];
19+
20+
if (options?.REPLACE) {
21+
args.push('REPLACE');
22+
}
23+
24+
if (options?.ABSTTL) {
25+
args.push('ABSTTL');
26+
}
27+
28+
if (options?.IDLETIME) {
29+
args.push('IDLETIME', options.IDLETIME.toString());
30+
}
31+
32+
if (options?.FREQ) {
33+
args.push('FREQ', options.FREQ.toString());
34+
}
35+
36+
return args;
37+
}
38+
39+
export declare function transformReply(): 'OK';

0 commit comments

Comments
 (0)