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.
145 lines
3.9 KiB
145 lines
3.9 KiB
'use strict'; |
|
|
|
var _ = require('lodash'); |
|
var Command = require('./command'); |
|
var Script = require('./script'); |
|
|
|
/** |
|
* Commander |
|
* |
|
* This is the base class of Redis, Redis.Cluster and Pipeline |
|
* |
|
* @param {boolean} [options.showFriendlyErrorStack=false] - Whether to show a friendly error stack. Will decrease the performance significantly. |
|
* @constructor |
|
*/ |
|
function Commander() { |
|
this.options = _.defaults({}, this.options || {}, { |
|
showFriendlyErrorStack: false |
|
}); |
|
this.scriptsSet = {}; |
|
} |
|
|
|
var commands = _.difference(_.keys(require('../commands'), ['monitor'])); |
|
commands.push('sentinel', 'quit'); |
|
|
|
/** |
|
* Return supported builtin commands |
|
* |
|
* @return {string[]} command list |
|
* @public |
|
*/ |
|
Commander.prototype.getBuiltinCommands = function () { |
|
return _.clone(commands); |
|
}; |
|
|
|
/** |
|
* Create a builtin command |
|
* |
|
* @param {string} commandName - command name |
|
* @return {object} functions |
|
* @public |
|
*/ |
|
Commander.prototype.createBuiltinCommand = function (commandName) { |
|
return { |
|
string: generateFunction(commandName, 'utf8'), |
|
buffer: generateFunction(commandName, null) |
|
}; |
|
}; |
|
|
|
_.forEach(commands, function (commandName) { |
|
Commander.prototype[commandName] = generateFunction(commandName, 'utf8'); |
|
Commander.prototype[commandName + 'Buffer'] = generateFunction(commandName, null); |
|
}); |
|
|
|
Commander.prototype.call = generateFunction('utf8'); |
|
Commander.prototype.callBuffer = generateFunction(null); |
|
Commander.prototype.send_command = Commander.prototype.call; |
|
|
|
/** |
|
* Define a custom command using lua script |
|
* |
|
* @param {string} name - the command name |
|
* @param {object} definition |
|
* @param {string} definition.lua - the lua code |
|
* @param {number} [definition.numberOfKeys=null] - the number of keys. |
|
* If omit, you have to pass the number of keys as the first argument every time you invoke the command |
|
*/ |
|
Commander.prototype.defineCommand = function (name, definition) { |
|
var script = new Script(definition.lua, definition.numberOfKeys, |
|
this.options.keyPrefix); |
|
this.scriptsSet[name] = script; |
|
this[name] = generateScriptingFunction(script, 'utf8'); |
|
this[name + 'Buffer'] = generateScriptingFunction(script, null); |
|
}; |
|
|
|
|
|
/** |
|
* Send a command |
|
* |
|
* @abstract |
|
* @public |
|
*/ |
|
Commander.prototype.sendCommand = function () {}; |
|
|
|
function generateFunction (_commandName, _encoding) { |
|
if (typeof _encoding === 'undefined') { |
|
_encoding = _commandName; |
|
_commandName = null; |
|
} |
|
return function () { |
|
var firstArgIndex = 0; |
|
var commandName = _commandName; |
|
if (commandName === null) { |
|
commandName = arguments[0]; |
|
firstArgIndex = 1; |
|
} |
|
var length = arguments.length; |
|
var lastArgIndex = length - 1; |
|
var callback = arguments[lastArgIndex]; |
|
if (typeof callback !== 'function') { |
|
callback = undefined; |
|
} else { |
|
length = lastArgIndex; |
|
} |
|
var args = new Array(length - firstArgIndex); |
|
for (var i = firstArgIndex; i < length; ++i) { |
|
args[i - firstArgIndex] = arguments[i]; |
|
} |
|
|
|
var options = { replyEncoding: _encoding }; |
|
if (this.options.showFriendlyErrorStack) { |
|
options.errorStack = new Error().stack; |
|
} |
|
if (this.options.keyPrefix) { |
|
options.keyPrefix = this.options.keyPrefix; |
|
} |
|
|
|
return this.sendCommand(new Command(commandName, args, options, callback)); |
|
}; |
|
} |
|
|
|
function generateScriptingFunction (_script, _encoding) { |
|
return function () { |
|
var length = arguments.length; |
|
var lastArgIndex = length - 1; |
|
var callback = arguments[lastArgIndex]; |
|
if (typeof callback !== 'function') { |
|
callback = undefined; |
|
} else { |
|
length = lastArgIndex; |
|
} |
|
var args = new Array(length); |
|
for (var i = 0; i < length; i++) { |
|
args[i] = arguments[i]; |
|
} |
|
|
|
var options = { replyEncoding: _encoding }; |
|
if (this.options.showFriendlyErrorStack) { |
|
options.errorStack = new Error().stack; |
|
} |
|
|
|
return _script.execute(this, args, options, callback); |
|
}; |
|
} |
|
|
|
module.exports = Commander;
|
|
|