diff --git a/index.js b/index.js index 036ad3d85a..e8b02131b1 100644 --- a/index.js +++ b/index.js @@ -391,14 +391,14 @@ RedisClient.prototype.on_ready = function () { // Restore modal commands from previous connection. The order of the commands is important if (this.selected_db !== undefined) { - this.send_command('select', [this.selected_db]); + this.internal_send_command('select', [this.selected_db]); } if (this.old_state !== null) { this.monitoring = this.old_state.monitoring; this.pub_sub_mode = this.old_state.pub_sub_mode; } if (this.monitoring) { // Monitor has to be fired before pub sub commands - this.send_command('monitor', []); + this.internal_send_command('monitor', []); } var callback_count = Object.keys(this.subscription_set).length; if (!this.options.disable_resubscribing && callback_count) { @@ -415,7 +415,7 @@ RedisClient.prototype.on_ready = function () { for (var key in this.subscription_set) { // jshint ignore: line var command = key.slice(0, key.indexOf('_')); var args = self.subscription_set[key]; - self.send_command(command, [args], callback); + self.internal_send_command(command, [args], callback); } this.send_offline_queue(); return; @@ -478,7 +478,7 @@ RedisClient.prototype.ready_check = function () { RedisClient.prototype.send_offline_queue = function () { for (var command_obj = this.offline_queue.shift(); command_obj; command_obj = this.offline_queue.shift()) { debug('Sending offline command: ' + command_obj.command); - this.send_command(command_obj.command, command_obj.args, command_obj.callback); + this.internal_send_command(command_obj.command, command_obj.args, command_obj.callback); } this.drain(); // Even though items were shifted off, Queue backing store still uses memory until next add, so just get a new Queue @@ -760,13 +760,14 @@ function handle_offline_command (self, command_obj) { self.should_buffer = true; } -RedisClient.prototype.send_command = function (command, args, callback) { - var args_copy, arg, prefix_keys; +RedisClient.prototype.internal_send_command = function (command, args, callback) { + var arg, prefix_keys; var i = 0; var command_str = ''; - var len = 0; + var len = args.length; var big_data = false; var buffer_args = false; + var args_copy = new Array(len); if (process.domain && callback) { callback = process.domain.bind(callback); @@ -778,13 +779,6 @@ RedisClient.prototype.send_command = function (command, args, callback) { return false; // Indicate buffering } - if (typeof args === 'undefined') { - args_copy = []; - } else { - len = args.length; - args_copy = new Array(len); - } - for (i = 0; i < len; i += 1) { if (typeof args[i] === 'string') { // 30000 seemed to be a good value to switch to buffers after testing and checking the pros and cons diff --git a/lib/commands.js b/lib/commands.js index 734e7b7060..a99d025714 100644 --- a/lib/commands.js +++ b/lib/commands.js @@ -42,7 +42,7 @@ commands.list.forEach(function (command) { arr[i] = arguments[i]; } } - return this.send_command(command, arr, callback); + return this.internal_send_command(command, arr, callback); }; } diff --git a/lib/individualCommands.js b/lib/individualCommands.js index cf277b1c7e..2bfeb6eb42 100644 --- a/lib/individualCommands.js +++ b/lib/individualCommands.js @@ -25,7 +25,8 @@ RedisClient.prototype.batch = RedisClient.prototype.BATCH = function batch (args // Store db in this.select_db to restore it on reconnect RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) { var self = this; - return this.send_command('select', [db], function (err, res) { + db = Array.isArray(db) && db.length === 1 ? db[0] : db; + return this.internal_send_command('select', [db], function (err, res) { if (err === null) { self.selected_db = db; } @@ -36,7 +37,7 @@ RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (d RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function (callback) { // Use a individual command, as this is a special case that does not has to be checked for any other command var self = this; - return this.send_command('monitor', [], function (err, res) { + return this.internal_send_command('monitor', [], function (err, res) { if (err === null) { self.reply_parser.returnReply = function (reply) { // If in monitor mode, all normal commands are still working and we only want to emit the streamlined commands @@ -86,7 +87,7 @@ RedisClient.prototype.quit = RedisClient.prototype.QUIT = function (callback) { } utils.callback_or_emit(self, callback, err, res); }; - var backpressure_indicator = this.send_command('quit', [], callback_hook); + var backpressure_indicator = this.internal_send_command('quit', [], callback_hook); // Calling quit should always end the connection, no matter if there's a connection or not this.closing = true; return backpressure_indicator; @@ -103,7 +104,7 @@ RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section args = Array.isArray(section) ? section : [section]; } this.ready = ready || this.offline_queue.length === 0; // keep the execution order intakt - var tmp = this.send_command('info', args, function (err, res) { + var tmp = this.internal_send_command('info', args, function (err, res) { if (res) { var obj = {}; var lines = res.toString().split('\r\n'); @@ -148,9 +149,10 @@ RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, c debug('Sending auth to ' + self.address + ' id ' + self.connection_id); // Stash auth for connect and reconnect. + pass = Array.isArray(pass) && pass.length === 1 ? pass[0] : pass; this.auth_pass = pass; this.ready = this.offline_queue.length === 0; // keep the execution order intakt - var tmp = this.send_command('auth', [pass], function (err, res) { + var tmp = this.internal_send_command('auth', [pass], function (err, res) { if (err) { if (no_password_is_set.test(err.message)) { self.warn('Warning: Redis server does not require a password, but a password was supplied.'); @@ -207,5 +209,5 @@ RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function hmset () { arr[i] = arguments[i]; } } - return this.send_command('hmset', arr, callback); + return this.internal_send_command('hmset', arr, callback); }; diff --git a/lib/multi.js b/lib/multi.js index 4d9834378b..ca7afda481 100644 --- a/lib/multi.js +++ b/lib/multi.js @@ -147,7 +147,7 @@ Multi.prototype.exec_transaction = function exec_transaction (callback) { pipeline_transaction_command(self, command, args[1], index, cb); } - self._client.send_command('exec', [], function (err, replies) { + self._client.internal_send_command('exec', [], function (err, replies) { multi_callback(self, err, replies); }); self._client.uncork(); @@ -207,10 +207,10 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct } else { cb = callback_without_own_cb; } - if (callback && index === len - 1) { + if (typeof callback === 'function' && index === len - 1) { cb = last_callback(cb); } - self._client.send_command(command, args[1], cb); + self._client.internal_send_command(command, args[1], cb); index++; } self.queue = new Queue(); diff --git a/test/commands/info.spec.js b/test/commands/info.spec.js index e0a01457ec..ce4d486fb7 100644 --- a/test/commands/info.spec.js +++ b/test/commands/info.spec.js @@ -56,7 +56,7 @@ describe("The 'info' method", function () { it('check redis v.2.4 support', function (done) { var end = helper.callFuncAfter(done, 2); - client.send_command = function (command, args, callback) { + client.internal_send_command = function (command, args, callback) { assert.strictEqual(args.length, 0); assert.strictEqual(command, 'info'); end();