Added logging, changed some directory structure

This commit is contained in:
2018-01-13 21:33:40 -05:00
parent f079a5f067
commit 8e72ffb917
73656 changed files with 35284 additions and 53718 deletions

View File

@@ -0,0 +1,29 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
*.rdb
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules
# Users Environment Variables
.lock-wscript

View File

@@ -0,0 +1,9 @@
language: node_js
sudo: false
node_js:
- "0.10"
- "0.12"
- "4"
- "5"
after_success:
- CODECLIMATE_REPO_TOKEN=b57723fafcf0516f275d6b380cd506fd082ea88d86507eb82c8abd489b9b9a09 node ./node_modules/.bin/codeclimate-test-reporter < coverage/lcov.info

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 NodeRedis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,51 @@
# Redis Commands
[![Build Status](https://travis-ci.org/NodeRedis/redis-commands.png?branch=master)](https://travis-ci.org/NodeRedis/redis-commands)
[![Code Climate](https://codeclimate.com/github/NodeRedis/redis-commands/badges/gpa.svg)](https://codeclimate.com/github/NodeRedis/redis-commands)
[![Test Coverage](https://codeclimate.com/github/NodeRedis/redis-commands/badges/coverage.svg)](https://codeclimate.com/github/NodeRedis/redis-commands/coverage)
This module exports all the commands that Redis supports.
## Install
```shell
$ npm install redis-commands
```
## Usage
```javascript
var commands = require('redis-commands');
```
`.list` is an array contains all the lowercased commands:
```javascript
commands.list.forEach(function (command) {
console.log(command);
});
```
`.exists()` is used to check if the command exists:
```javascript
commands.exists('set') // true
commands.exists('other-command') // false
```
`.hasFlag()` is used to check if the command has the flag:
```javascript
commands.hasFlag('set', 'readonly') // false
```
`.getKeyIndexes()` is used to get the indexes of keys in the command arguments:
```javascript
commands.getKeyIndexes('set', ['key', 'value']) // [0]
commands.getKeyIndexes('mget', ['key1', 'key2']) // [0, 1]
```
## Acknowledgment
Thank [@Yuan Chuan](https://github.com/yuanchuan) for the package name. The original redis-commands is renamed to [@yuanchuan/redis-commands](https://www.npmjs.com/package/@yuanchuan/redis-commands).

View File

@@ -0,0 +1,32 @@
## v.1.3.1 - 25 Jan, 2017
Bugfix
- Fix require for for webpack
## v.1.3.0 - 20 Oct, 2016
Features
- Rebuild the commands with the newest Redis unstable release
## v.1.2.0 - 21 Apr, 2016
Features
- Added support for `MIGRATE [...] KEYS key1, key2` (Redis >= v.3.0.6)
- Added build sanity check for unhandled commands with moveable keys
- Rebuild the commands with the newest unstable release
- Improved performance of .getKeyIndexes()
Bugfix
- Fixed command command returning the wrong arity due to a Redis bug
- Fixed brpop command returning the wrong keystop due to a Redis bug
## v.1.1.0 - 09 Feb, 2016
Features
- Added .exists() to check for command existence
- Improved performance of .hasFlag()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
'use strict'
var commands = require('./commands.json')
/**
* Redis command list
*
* All commands are lowercased.
*
* @var {string[]}
* @public
*/
exports.list = Object.keys(commands)
var flags = {}
exports.list.forEach(function (commandName) {
flags[commandName] = commands[commandName].flags.reduce(function (flags, flag) {
flags[flag] = true
return flags
}, {})
})
/**
* Check if the command exists
*
* @param {string} commandName - the command name
* @return {boolean} result
* @public
*/
exports.exists = function (commandName) {
return Boolean(commands[commandName])
}
/**
* Check if the command has the flag
*
* Some of possible flags: readonly, noscript, loading
* @param {string} commandName - the command name
* @param {string} flag - the flag to check
* @return {boolean} result
* @public
*/
exports.hasFlag = function (commandName, flag) {
if (!flags[commandName]) {
throw new Error('Unknown command ' + commandName)
}
return Boolean(flags[commandName][flag])
}
/**
* Get indexes of keys in the command arguments
*
* @param {string} commandName - the command name
* @param {string[]} args - the arguments of the command
* @param {object} [options] - options
* @param {boolean} [options.parseExternalKey] - parse external keys
* @return {number[]} - the list of the index
* @public
*
* @example
* ```javascript
* getKeyIndexes('set', ['key', 'value']) // [0]
* getKeyIndexes('mget', ['key1', 'key2']) // [0, 1]
* ```
*/
exports.getKeyIndexes = function (commandName, args, options) {
var command = commands[commandName]
if (!command) {
throw new Error('Unknown command ' + commandName)
}
if (!Array.isArray(args)) {
throw new Error('Expect args to be an array')
}
var keys = []
var i, keyStart, keyStop, parseExternalKey
switch (commandName) {
case 'zunionstore':
case 'zinterstore':
keys.push(0)
// fall through
case 'eval':
case 'evalsha':
keyStop = Number(args[1]) + 2
for (i = 2; i < keyStop; i++) {
keys.push(i)
}
break
case 'sort':
parseExternalKey = options && options.parseExternalKey
keys.push(0)
for (i = 1; i < args.length - 1; i++) {
if (typeof args[i] !== 'string') {
continue
}
var directive = args[i].toUpperCase()
if (directive === 'GET') {
i += 1
if (args[i] !== '#') {
if (parseExternalKey) {
keys.push([i, getExternalKeyNameLength(args[i])])
} else {
keys.push(i)
}
}
} else if (directive === 'BY') {
i += 1
if (parseExternalKey) {
keys.push([i, getExternalKeyNameLength(args[i])])
} else {
keys.push(i)
}
} else if (directive === 'STORE') {
i += 1
keys.push(i)
}
}
break
case 'migrate':
if (args[2] === '') {
for (i = 5; i < args.length - 1; i++) {
if (args[i].toUpperCase() === 'KEYS') {
for (var j = i + 1; j < args.length; j++) {
keys.push(j)
}
break
}
}
} else {
keys.push(2)
}
break
default:
// step has to be at least one in this case, otherwise the command does not contain a key
if (command.step > 0) {
keyStart = command.keyStart - 1
keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1
for (i = keyStart; i < keyStop; i += command.step) {
keys.push(i)
}
}
break
}
return keys
}
function getExternalKeyNameLength (key) {
if (typeof key !== 'string') {
key = String(key)
}
var hashPos = key.indexOf('->')
return hashPos === -1 ? key.length : hashPos
}

View File

@@ -0,0 +1,72 @@
{
"_args": [
[
"redis-commands@1.3.1",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project"
]
],
"_from": "redis-commands@1.3.1",
"_id": "redis-commands@1.3.1",
"_inBundle": false,
"_integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=",
"_location": "/redis/redis-commands",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "redis-commands@1.3.1",
"name": "redis-commands",
"escapedName": "redis-commands",
"rawSpec": "1.3.1",
"saveSpec": null,
"fetchSpec": "1.3.1"
},
"_requiredBy": [
"/redis"
],
"_resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
"_spec": "1.3.1",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project",
"author": {
"name": "luin",
"email": "i@zihua.li",
"url": "http://zihua.li"
},
"bugs": {
"url": "https://github.com/NodeRedis/redis-commonds/issues"
},
"description": "Redis commands",
"devDependencies": {
"chai": "^3.4.0",
"codeclimate-test-reporter": "^0.4.0",
"ioredis": "^2.0.0",
"istanbul": "^0.4.3",
"json-stable-stringify": "^1.0.0",
"mocha": "^3.0.0",
"snazzy": "^6.0.0",
"standard": "^8.0.0"
},
"homepage": "https://github.com/NodeRedis/redis-commonds",
"keywords": [
"redis",
"commands",
"prefix"
],
"license": "MIT",
"main": "index.js",
"name": "redis-commands",
"repository": {
"type": "git",
"url": "git+https://github.com/NodeRedis/redis-commands.git"
},
"scripts": {
"build": "node tools/build",
"coverage": "node ./node_modules/istanbul/lib/cli.js cover --preserve-comments ./node_modules/mocha/bin/_mocha -- -R spec",
"coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 100 --statement 100",
"lint": "standard --fix --verbose | snazzy",
"posttest": "npm run coverage && npm run coverage:check",
"pretest": "npm run lint",
"test": "mocha"
},
"version": "1.3.1"
}

View File

@@ -0,0 +1,120 @@
'use strict'
/* global describe, it */
var commands = require('..')
var expect = require('chai').expect
describe('redis-commands', function () {
describe('.list', function () {
it('should be an array', function () {
expect(commands.list).to.be.instanceof(Array)
})
it('should ensure every command is lowercase', function () {
commands.list.forEach(function (command) {
expect(command.toLowerCase()).to.eql(command)
})
})
it('should ensure quit command is added to the commands list', function () {
expect(commands.list.indexOf('quit')).not.to.eql(-1)
})
it('should not contain multi-word commands', function () {
commands.list.forEach(function (command) {
expect(command.indexOf(' ')).to.eql(-1)
})
})
})
describe('.exists()', function () {
it('should return true for existing commands', function () {
expect(commands.exists('set')).to.eql(true)
expect(commands.exists('get')).to.eql(true)
expect(commands.exists('cluster')).to.eql(true)
expect(commands.exists('quit')).to.eql(true)
expect(commands.exists('config')).to.eql(true)
})
it('should return false for non-existing commands', function () {
expect(commands.exists('SET')).to.eql(false)
expect(commands.exists('set get')).to.eql(false)
expect(commands.exists('other-command')).to.eql(false)
})
})
describe('.hasFlag()', function () {
it('should return true if the command has the flag', function () {
expect(commands.hasFlag('set', 'write')).to.eql(true)
expect(commands.hasFlag('set', 'denyoom')).to.eql(true)
expect(commands.hasFlag('select', 'fast')).to.eql(true)
})
it('should return false otherwise', function () {
expect(commands.hasFlag('set', 'fast')).to.eql(false)
expect(commands.hasFlag('set', 'readonly')).to.eql(false)
expect(commands.hasFlag('select', 'denyoom')).to.eql(false)
expect(commands.hasFlag('quit', 'denyoom')).to.eql(false)
})
it('should throw on unknown commands', function () {
expect(function () { commands.hasFlag('UNKNOWN') }).to.throw(Error)
})
})
describe('.getKeyIndexes()', function () {
var index = commands.getKeyIndexes
it('should throw on unknown commands', function () {
expect(function () { index('UNKNOWN') }).to.throw(Error)
})
it('should throw on faulty args', function () {
expect(function () { index('get', 'foo') }).to.throw(Error)
})
it('should return an empty array if no keys exist', function () {
expect(index('auth', [])).to.eql([])
})
it('should return key indexes', function () {
expect(index('set', ['foo', 'bar'])).to.eql([0])
expect(index('del', ['foo'])).to.eql([0])
expect(index('get', ['foo'])).to.eql([0])
expect(index('mget', ['foo', 'bar'])).to.eql([0, 1])
expect(index('mset', ['foo', 'v1', 'bar', 'v2'])).to.eql([0, 2])
expect(index('hmset', ['key', 'foo', 'v1', 'bar', 'v2'])).to.eql([0])
expect(index('blpop', ['key1', 'key2', '17'])).to.eql([0, 1])
expect(index('evalsha', ['23123', '2', 'foo', 'bar', 'zoo'])).to.eql([2, 3])
expect(index('sort', ['key'])).to.eql([0])
expect(index('zunionstore', ['out', '2', 'zset1', 'zset2', 'WEIGHTS', '2', '3'])).to.eql([0, 2, 3])
expect(index('migrate', ['127.0.0.1', 6379, 'foo', 0, 0, 'COPY'])).to.eql([2])
expect(index('migrate', ['127.0.0.1', 6379, '', 0, 0, 'REPLACE', 'KEYS', 'foo', 'bar'])).to.eql([7, 8])
expect(index('migrate', ['127.0.0.1', 6379, '', 0, 0, 'KEYS', 'foo', 'bar'])).to.eql([6, 7])
})
it('should support numeric argument', function () {
expect(index('evalsha', ['23123', 2, 'foo', 'bar', 'zoo'])).to.eql([2, 3])
expect(index('zinterstore', ['out', 2, 'zset1', 'zset2', 'WEIGHTS', 2, 3])).to.eql([0, 2, 3])
})
describe('disable parseExternalKey', function () {
it('should not parse external keys', function () {
expect(index('sort', ['key', 'BY', 'hash:*->field'])).to.eql([0, 2])
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', 'gk', 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'])).to.eql([0, 2, 7, 11, 15])
})
})
describe('enable parseExternalKey', function () {
it('should parse external keys', function () {
expect(index('sort', ['key', 'BY', 'hash:*->field'], {
parseExternalKey: true
})).to.eql([0, [2, 6]])
expect(index('sort', ['key', 'BY', 'hash:*->field', 'LIMIT', 2, 3, 'GET', new Buffer('gk'), 'GET', '#', 'Get', 'gh->f*', 'DESC', 'ALPHA', 'STORE', 'store'], {
parseExternalKey: true
})).to.eql([0, [2, 6], [7, 2], [11, 2], 15])
})
})
})
})

View File

@@ -0,0 +1,62 @@
var fs = require('fs')
var path = require('path')
var stringify = require('json-stable-stringify')
var commandPath = path.join(__dirname, '..', 'commands.json')
var redisCommands = require('../')
var Redis = require('ioredis')
var redis = new Redis(process.env.REDIS_URI)
redis.command().then(function (res) {
redis.disconnect()
// Find all special handled cases
var movableKeys = String(redisCommands.getKeyIndexes).match(/case '[a-z-]+':/g).map(function (entry) {
return entry.replace(/^case '|':$/g, '')
})
var commands = res.reduce(function (prev, current) {
var currentCommandPos = movableKeys.indexOf(current[0])
if (currentCommandPos !== -1 && current[2].indexOf('movablekeys') !== -1) {
movableKeys.splice(currentCommandPos, 1)
}
// https://github.com/antirez/redis/issues/2598
if (current[0] === 'brpop' && current[4] === 1) {
current[4] = -2
}
prev[current[0]] = {
arity: current[1] || 1, // https://github.com/antirez/redis/pull/2986
flags: current[2],
keyStart: current[3],
keyStop: current[4],
step: current[5]
}
return prev
}, {})
// Future proof. Redis might implement this at some point
// https://github.com/antirez/redis/pull/2982
if (!commands.quit) {
commands.quit = {
arity: 1,
flags: [
'loading',
'stale',
'readonly'
],
keyStart: 0,
keyStop: 0,
step: 0
}
}
if (movableKeys.length !== 0) {
throw new Error('Not all commands (\'' + movableKeys.join('\', \'') + '\') with the "movablekeys" flag are handled in the code')
}
// Use json-stable-stringify instead fo JSON.stringify
// for easier diffing
var content = stringify(commands, { space: ' ' })
fs.writeFile(commandPath, content)
})