1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

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 <me@leibale.com>
This commit is contained in:
Moshe L
2023-09-19 02:45:33 +03:00
committed by GitHub
parent 8ecfd3ebda
commit 01ca54e907
5 changed files with 140 additions and 1 deletions

View File

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

View File

@@ -0,0 +1,22 @@
// This example demonstrates the use of the DUMP and RESTORE commands
import { commandOptions, createClient } from 'redis';
const client = createClient();
await client.connect();
// DUMP a specific key into a local variable
const dump = await client.dump(
commandOptions({ returnBuffers: true }),
'source'
);
// RESTORE into a new key
await client.restore('destination', 0, dump);
// RESTORE and REPLACE an existing key
await client.restore('destination', 0, dump, {
REPLACE: true
});
await client.quit();

View File

@@ -110,6 +110,7 @@ import * as PTTL from '../commands/PTTL';
import * as PUBLISH from '../commands/PUBLISH'; import * as PUBLISH from '../commands/PUBLISH';
import * as RENAME from '../commands/RENAME'; import * as RENAME from '../commands/RENAME';
import * as RENAMENX from '../commands/RENAMENX'; import * as RENAMENX from '../commands/RENAMENX';
import * as RESTORE from '../commands/RESTORE';
import * as RPOP_COUNT from '../commands/RPOP_COUNT'; import * as RPOP_COUNT from '../commands/RPOP_COUNT';
import * as RPOP from '../commands/RPOP'; import * as RPOP from '../commands/RPOP';
import * as RPOPLPUSH from '../commands/RPOPLPUSH'; import * as RPOPLPUSH from '../commands/RPOPLPUSH';
@@ -434,6 +435,8 @@ export default {
rename: RENAME, rename: RENAME,
RENAMENX, RENAMENX,
renameNX: RENAMENX, renameNX: RENAMENX,
RESTORE,
restore: RESTORE,
RPOP_COUNT, RPOP_COUNT,
rPopCount: RPOP_COUNT, rPopCount: RPOP_COUNT,
RPOP, RPOP,

View File

@@ -0,0 +1,74 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './RESTORE';
describe('RESTORE', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
transformArguments('key', 0, 'value'),
['RESTORE', 'key', '0', 'value']
);
});
it('with REPLACE', () => {
assert.deepEqual(
transformArguments('key', 0, 'value', {
REPLACE: true
}),
['RESTORE', 'key', '0', 'value', 'REPLACE']
);
});
it('with ABSTTL', () => {
assert.deepEqual(
transformArguments('key', 0, 'value', {
ABSTTL: true
}),
['RESTORE', 'key', '0', 'value', 'ABSTTL']
);
});
it('with IDLETIME', () => {
assert.deepEqual(
transformArguments('key', 0, 'value', {
IDLETIME: 1
}),
['RESTORE', 'key', '0', 'value', 'IDLETIME', '1']
);
});
it('with FREQ', () => {
assert.deepEqual(
transformArguments('key', 0, 'value', {
FREQ: 1
}),
['RESTORE', 'key', '0', 'value', 'FREQ', '1']
);
});
it('with REPLACE, ABSTTL, IDLETIME and FREQ', () => {
assert.deepEqual(
transformArguments('key', 0, 'value', {
REPLACE: true,
ABSTTL: true,
IDLETIME: 1,
FREQ: 2
}),
['RESTORE', 'key', '0', 'value', 'REPLACE', 'ABSTTL', 'IDLETIME', '1', 'FREQ', '2']
);
});
});
testUtils.testWithClient('client.restore', async client => {
const [, dump] = await Promise.all([
client.set('source', 'value'),
client.dump(client.commandOptions({ returnBuffers: true }), 'source')
]);
assert.equal(
await client.restore('destination', 0, dump),
'OK'
);
}, GLOBAL.SERVERS.OPEN);
});

View File

@@ -0,0 +1,39 @@
import { RedisCommandArgument, RedisCommandArguments } from '.';
export const FIRST_KEY_INDEX = 1;
interface RestoreOptions {
REPLACE?: true;
ABSTTL?: true;
IDLETIME?: number;
FREQ?: number;
}
export function transformArguments(
key: RedisCommandArgument,
ttl: number,
serializedValue: RedisCommandArgument,
options?: RestoreOptions
): RedisCommandArguments {
const args = ['RESTORE', key, ttl.toString(), serializedValue];
if (options?.REPLACE) {
args.push('REPLACE');
}
if (options?.ABSTTL) {
args.push('ABSTTL');
}
if (options?.IDLETIME) {
args.push('IDLETIME', options.IDLETIME.toString());
}
if (options?.FREQ) {
args.push('FREQ', options.FREQ.toString());
}
return args;
}
export declare function transformReply(): 'OK';