You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.2 KiB
168 lines
4.2 KiB
'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 |
|
case 'xreadgroup': |
|
case 'xread': |
|
// Keys are 1st half of the args after STREAMS argument. |
|
for (i = commandName === 'xread' ? 0 : 3; i < args.length - 1; i++) { |
|
if (String(args[i]).toUpperCase() === 'STREAMS') { |
|
for (j = i + 1; j <= i + ((args.length - 1 - i) / 2); j++) { |
|
keys.push(j) |
|
} |
|
break |
|
} |
|
} |
|
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 |
|
}
|
|
|