Skip to content

Commit 004f76d

Browse files
committed
Merge pull request #3 from NodeRedis/v.1.2
v.1.2
2 parents 1197dea + b93a6db commit 004f76d

File tree

9 files changed

+107
-28
lines changed

9 files changed

+107
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ logs
66
pids
77
*.pid
88
*.seed
9+
*.rdb
910

1011
# Directory for instrumented libs generated by jscoverage/JSCover
1112
lib-cov

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ node_js:
55
- "0.12"
66
- "4"
77
- "5"
8+
after_success:
9+
- CODECLIMATE_REPO_TOKEN=b57723fafcf0516f275d6b380cd506fd082ea88d86507eb82c8abd489b9b9a09 node ./node_modules/.bin/codeclimate-test-reporter < coverage/lcov.info

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Redis Commands
22

33
[![Build Status](https://travis-ci.org/NodeRedis/redis-commands.png?branch=master)](https://travis-ci.org/NodeRedis/redis-commands)
4+
[![Code Climate](https://codeclimate.com/github/NodeRedis/redis-commands/badges/gpa.svg)](https://codeclimate.com/github/NodeRedis/redis-commands)
5+
[![Test Coverage](https://codeclimate.com/github/NodeRedis/redis-commands/badges/coverage.svg)](https://codeclimate.com/github/NodeRedis/redis-commands/coverage)
46

57
This module exports all the commands that Redis supports.
68

changelog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## v.1.2.0 - xx Apr, 2016
2+
3+
Features
4+
5+
- Added support for `MIGRATE [...] KEYS key1, key2` (Redis >= v.3.0.6)
6+
- Added build sanity check for unhandled commands with moveable keys
7+
- Rebuild the commands with the newest unstable release
8+
- Improved performance of .getKeyIndexes()
9+
10+
Bugfix
11+
12+
- Fixed command command returning the wrong arity due to a Redis bug
13+
- Fixed brpop command returning the wrong keystop due to a Redis bug
14+
115
## v.1.1.0 - 09 Feb, 2016
216

317
Features

commands.json

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@
6060
"keyStop": 1,
6161
"step": 1
6262
},
63+
"bitfield": {
64+
"arity": -2,
65+
"flags": [
66+
"write",
67+
"denyoom"
68+
],
69+
"keyStart": 1,
70+
"keyStop": 1,
71+
"step": 1
72+
},
6373
"bitop": {
6474
"arity": -4,
6575
"flags": [
@@ -96,7 +106,7 @@
96106
"noscript"
97107
],
98108
"keyStart": 1,
99-
"keyStop": 1,
109+
"keyStop": -2,
100110
"step": 1
101111
},
102112
"brpoplpush": {
@@ -131,7 +141,7 @@
131141
"step": 0
132142
},
133143
"command": {
134-
"arity": 0,
144+
"arity": 1,
135145
"flags": [
136146
"readonly",
137147
"loading",
@@ -351,7 +361,7 @@
351361
"georadius": {
352362
"arity": -6,
353363
"flags": [
354-
"readonly"
364+
"write"
355365
],
356366
"keyStart": 1,
357367
"keyStop": 1,
@@ -360,7 +370,7 @@
360370
"georadiusbymember": {
361371
"arity": -5,
362372
"flags": [
363-
"readonly"
373+
"write"
364374
],
365375
"keyStart": 1,
366376
"keyStop": 1,
@@ -745,11 +755,12 @@
745755
"migrate": {
746756
"arity": -6,
747757
"flags": [
748-
"write"
758+
"write",
759+
"movablekeys"
749760
],
750-
"keyStart": 3,
751-
"keyStop": 3,
752-
"step": 1
761+
"keyStart": 0,
762+
"keyStop": 0,
763+
"step": 0
753764
},
754765
"monitor": {
755766
"arity": 1,

index.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,12 @@ exports.getKeyIndexes = function (commandName, args, options) {
7373
throw new Error('Expect args to be an array');
7474
}
7575

76-
var parseExternalKey = options && options.parseExternalKey;
77-
7876
var keys = [];
79-
var i, range, keyStart, keyStop;
77+
var i, keyStart, keyStop, parseExternalKey;
8078
switch (commandName) {
79+
case 'zunionstore':
80+
case 'zinterstore':
81+
keys.push(0);
8182
case 'eval':
8283
case 'evalsha':
8384
keyStop = Number(args[1]) + 2;
@@ -86,6 +87,7 @@ exports.getKeyIndexes = function (commandName, args, options) {
8687
}
8788
break;
8889
case 'sort':
90+
parseExternalKey = options && options.parseExternalKey;
8991
keys.push(0);
9092
for (i = 1; i < args.length - 1; i++) {
9193
if (typeof args[i] !== 'string') {
@@ -114,18 +116,25 @@ exports.getKeyIndexes = function (commandName, args, options) {
114116
}
115117
}
116118
break;
117-
case 'zunionstore':
118-
case 'zinterstore':
119-
keys.push(0);
120-
keyStop = Number(args[1]) + 2;
121-
for (i = 2; i < keyStop; i++) {
122-
keys.push(i);
119+
case 'migrate':
120+
if (args[2] === '') {
121+
for (i = 5; i < args.length - 1; i++) {
122+
if (args[i].toUpperCase() === 'KEYS') {
123+
for (var j = i + 1; j < args.length; j++) {
124+
keys.push(j);
125+
}
126+
break;
127+
}
128+
}
129+
} else {
130+
keys.push(2);
123131
}
124132
break;
125133
default:
126-
keyStart = command.keyStart - 1;
127-
keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1;
128-
if (keyStart >= 0 && keyStop <= args.length && keyStop > keyStart && command.step > 0) {
134+
// step has to be at least one in this case, otherwise the command does not contain a key
135+
if (command.step > 0) {
136+
keyStart = command.keyStart - 1;
137+
keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1;
129138
for (i = keyStart; i < keyStop; i += command.step) {
130139
keys.push(i);
131140
}

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"main": "index.js",
66
"scripts": {
77
"test": "mocha",
8+
"posttest": "npm run coverage && npm run coverage:check",
9+
"coverage": "node ./node_modules/istanbul/lib/cli.js cover --preserve-comments ./node_modules/mocha/bin/_mocha -- -R spec",
10+
"coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 100 --statement 100",
811
"build": "node tools/build"
912
},
1013
"repository": {
@@ -24,7 +27,9 @@
2427
"homepage": "https://github.com/NodeRedis/redis-commonds",
2528
"devDependencies": {
2629
"chai": "^3.4.0",
27-
"ioredis": "^1.0.8",
30+
"codeclimate-test-reporter": "^0.3.1",
31+
"ioredis": "^2.0.0-rc2",
32+
"istanbul": "^0.4.3",
2833
"json-stable-stringify": "^1.0.0",
2934
"mocha": "^2.2.1"
3035
}

test/index.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,30 @@ describe('redis-commands', function () {
5555
expect(commands.hasFlag('select', 'denyoom')).to.eql(false);
5656
expect(commands.hasFlag('quit', 'denyoom')).to.eql(false);
5757
});
58+
59+
it('should throw on unknown commands', function () {
60+
expect(function () { commands.hasFlag('UNKNOWN'); }).to.throw(Error);
61+
});
5862
});
5963

6064
describe('.getKeyIndexes()', function () {
6165
var index = commands.getKeyIndexes;
6266

67+
it('should throw on unknown commands', function () {
68+
expect(function () { index('UNKNOWN'); }).to.throw(Error);
69+
});
70+
71+
it('should throw on faulty args', function () {
72+
expect(function () { index('get', 'foo'); }).to.throw(Error);
73+
});
74+
75+
it('should return an empty array if no keys exist', function () {
76+
expect(index('auth', [])).to.eql([]);
77+
});
78+
6379
it('should return key indexes', function () {
6480
expect(index('set', ['foo', 'bar'])).to.eql([0]);
81+
expect(index('del', ['foo'])).to.eql([0]);
6582
expect(index('get', ['foo'])).to.eql([0]);
6683
expect(index('mget', ['foo', 'bar'])).to.eql([0, 1]);
6784
expect(index('mset', ['foo', 'v1', 'bar', 'v2'])).to.eql([0, 2]);
@@ -70,6 +87,9 @@ describe('redis-commands', function () {
7087
expect(index('evalsha', ['23123', '2', 'foo', 'bar', 'zoo'])).to.eql([2, 3]);
7188
expect(index('sort', ['key'])).to.eql([0]);
7289
expect(index('zunionstore', ['out', '2', 'zset1', 'zset2', 'WEIGHTS', '2', '3'])).to.eql([0, 2, 3]);
90+
expect(index('migrate', ['127.0.0.1', 6379, 'foo', 0, 0, 'COPY'])).to.eql([2]);
91+
expect(index('migrate', ['127.0.0.1', 6379, '', 0, 0, 'REPLACE', 'KEYS', 'foo', 'bar'])).to.eql([7, 8]);
92+
expect(index('migrate', ['127.0.0.1', 6379, '', 0, 0, 'KEYS', 'foo', 'bar'])).to.eql([6, 7]);
7393
});
7494

7595
it('should support numeric argument', function () {
@@ -89,7 +109,7 @@ describe('redis-commands', function () {
89109
expect(index('sort', ['key', 'BY', 'hash:*->field'], {
90110
parseExternalKey: true
91111
})).to.eql([0, [2, 6]]);
92-
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', 'gk', 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'], {
112+
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', new Buffer('gk'), 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'], {
93113
parseExternalKey: true
94114
})).to.eql([0, [2, 6], [7, 2], [11, 2], 15]);
95115
});

tools/build.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,30 @@ var fs = require('fs');
22
var path = require('path');
33
var stringify = require('json-stable-stringify');
44
var commandPath = path.join(__dirname, '..', 'commands.json');
5+
var redisCommands = require('../');
56

67
var Redis = require('ioredis');
78
var redis = new Redis(process.env.REDIS_URI);
89

9-
redis.command(function (err, res) {
10+
redis.command().then(function (res) {
1011
redis.disconnect();
1112

12-
if (err) {
13-
throw err;
14-
}
13+
// Find all special handled cases
14+
var movableKeys = String(redisCommands.getKeyIndexes).match(/case '[a-z-]+':/g).map(function (entry) {
15+
return entry.replace(/^case \'|\':$/g, '');
16+
});
1517

1618
var commands = res.reduce(function (prev, current) {
19+
var currentCommandPos = movableKeys.indexOf(current[0]);
20+
if (currentCommandPos !== -1 && current[2].indexOf('movablekeys') !== -1) {
21+
movableKeys.splice(currentCommandPos, 1);
22+
}
23+
// https://github.com/antirez/redis/issues/2598
24+
if (current[0] === 'brpop' && current[4] === 1) {
25+
current[4] = -2;
26+
}
1727
prev[current[0]] = {
18-
arity: current[1],
28+
arity: current[1] || 1, // https://github.com/antirez/redis/pull/2986
1929
flags: current[2],
2030
keyStart: current[3],
2131
keyStop: current[4],
@@ -24,7 +34,8 @@ redis.command(function (err, res) {
2434
return prev;
2535
}, {});
2636

27-
// Future proof. Redis might implement this soon
37+
// Future proof. Redis might implement this at some point
38+
// https://github.com/antirez/redis/pull/2982
2839
if (!commands.quit) {
2940
commands.quit = {
3041
arity: 1,
@@ -39,6 +50,10 @@ redis.command(function (err, res) {
3950
}
4051
}
4152

53+
if (movableKeys.length !== 0) {
54+
throw new Error('Not all commands (\'' + movableKeys.join('\', \'') + '\') with the "movablekeys" flag are handled in the code');
55+
}
56+
4257
// Use json-stable-stringify instead fo JSON.stringify
4358
// for easier diffing
4459
var content = stringify(commands, { space: ' ' });

0 commit comments

Comments
 (0)