mirror of
https://github.com/abrendan/MicDropMessages.git
synced 2025-08-25 14:02:03 +02:00
Initial commit
This commit is contained in:
16
node_modules/redis/lib/command.js
generated
vendored
Normal file
16
node_modules/redis/lib/command.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
var betterStackTraces = /development/i.test(process.env.NODE_ENV) || /\bredis\b/i.test(process.env.NODE_DEBUG);
|
||||
|
||||
function Command (command, args, callback, call_on_write) {
|
||||
this.command = command;
|
||||
this.args = args;
|
||||
this.buffer_args = false;
|
||||
this.callback = callback;
|
||||
this.call_on_write = call_on_write;
|
||||
if (betterStackTraces) {
|
||||
this.error = new Error();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command;
|
121
node_modules/redis/lib/commands.js
generated
vendored
Normal file
121
node_modules/redis/lib/commands.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
'use strict';
|
||||
|
||||
var commands = require('redis-commands');
|
||||
var Multi = require('./multi');
|
||||
var RedisClient = require('../').RedisClient;
|
||||
var Command = require('./command');
|
||||
// Feature detect if a function may change it's name
|
||||
var changeFunctionName = (function () {
|
||||
var fn = function abc () {};
|
||||
try {
|
||||
Object.defineProperty(fn, 'name', {
|
||||
value: 'foobar'
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}());
|
||||
|
||||
var addCommand = function (command) {
|
||||
// Some rare Redis commands use special characters in their command name
|
||||
// Convert those to a underscore to prevent using invalid function names
|
||||
var commandName = command.replace(/(?:^([0-9])|[^a-zA-Z0-9_$])/g, '_$1');
|
||||
|
||||
// Do not override existing functions
|
||||
if (!RedisClient.prototype[command]) {
|
||||
RedisClient.prototype[command.toUpperCase()] = RedisClient.prototype[command] = function () {
|
||||
var arr;
|
||||
var len = arguments.length;
|
||||
var callback;
|
||||
var i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
if (len === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
} else if (len > 1 && Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else {
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command(command, arr, callback));
|
||||
};
|
||||
// Alias special function names (e.g. NR.RUN becomes NR_RUN and nr_run)
|
||||
if (commandName !== command) {
|
||||
RedisClient.prototype[commandName.toUpperCase()] = RedisClient.prototype[commandName] = RedisClient.prototype[command];
|
||||
}
|
||||
if (changeFunctionName) {
|
||||
Object.defineProperty(RedisClient.prototype[command], 'name', {
|
||||
value: commandName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Do not override existing functions
|
||||
if (!Multi.prototype[command]) {
|
||||
Multi.prototype[command.toUpperCase()] = Multi.prototype[command] = function () {
|
||||
var arr;
|
||||
var len = arguments.length;
|
||||
var callback;
|
||||
var i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
if (len === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
} else if (len > 1 && Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else {
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
this.queue.push(new Command(command, arr, callback));
|
||||
return this;
|
||||
};
|
||||
// Alias special function names (e.g. NR.RUN becomes NR_RUN and nr_run)
|
||||
if (commandName !== command) {
|
||||
Multi.prototype[commandName.toUpperCase()] = Multi.prototype[commandName] = Multi.prototype[command];
|
||||
}
|
||||
if (changeFunctionName) {
|
||||
Object.defineProperty(Multi.prototype[command], 'name', {
|
||||
value: commandName
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
commands.list.forEach(addCommand);
|
||||
|
||||
module.exports = addCommand;
|
80
node_modules/redis/lib/createClient.js
generated
vendored
Normal file
80
node_modules/redis/lib/createClient.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var URL = require('url');
|
||||
|
||||
module.exports = function createClient (port_arg, host_arg, options) {
|
||||
|
||||
if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) {
|
||||
|
||||
var host;
|
||||
if (typeof host_arg === 'string') {
|
||||
host = host_arg;
|
||||
} else {
|
||||
if (options && host_arg) {
|
||||
throw new TypeError('Unknown type of connection in createClient()');
|
||||
}
|
||||
options = options || host_arg;
|
||||
}
|
||||
options = utils.clone(options);
|
||||
options.host = host || options.host;
|
||||
options.port = port_arg;
|
||||
|
||||
} else if (typeof port_arg === 'string' || port_arg && port_arg.url) {
|
||||
|
||||
options = utils.clone(port_arg.url ? port_arg : host_arg || options);
|
||||
var url = port_arg.url || port_arg;
|
||||
var parsed = URL.parse(url, true, true);
|
||||
|
||||
// [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
|
||||
if (parsed.slashes) { // We require slashes
|
||||
if (parsed.auth) {
|
||||
options.password = parsed.auth.split(':')[1];
|
||||
}
|
||||
if (parsed.protocol && parsed.protocol !== 'redis:') {
|
||||
console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
|
||||
}
|
||||
if (parsed.pathname && parsed.pathname !== '/') {
|
||||
options.db = parsed.pathname.substr(1);
|
||||
}
|
||||
if (parsed.hostname) {
|
||||
options.host = parsed.hostname;
|
||||
}
|
||||
if (parsed.port) {
|
||||
options.port = parsed.port;
|
||||
}
|
||||
if (parsed.search !== '') {
|
||||
var elem;
|
||||
for (elem in parsed.query) {
|
||||
// If options are passed twice, only the parsed options will be used
|
||||
if (elem in options) {
|
||||
if (options[elem] === parsed.query[elem]) {
|
||||
console.warn('node_redis: WARNING: You passed the ' + elem + ' option twice!');
|
||||
} else {
|
||||
throw new RangeError('The ' + elem + ' option is added twice and does not match');
|
||||
}
|
||||
}
|
||||
options[elem] = parsed.query[elem];
|
||||
}
|
||||
}
|
||||
} else if (parsed.hostname) {
|
||||
throw new RangeError('The redis url must begin with slashes "//" or contain slashes after the redis protocol');
|
||||
} else {
|
||||
options.path = url;
|
||||
}
|
||||
|
||||
} else if (typeof port_arg === 'object' || port_arg === undefined) {
|
||||
options = utils.clone(port_arg || options);
|
||||
options.host = options.host || host_arg;
|
||||
|
||||
if (port_arg && arguments.length !== 1) {
|
||||
throw new TypeError('To many arguments passed to createClient. Please only pass the options object');
|
||||
}
|
||||
}
|
||||
|
||||
if (!options) {
|
||||
throw new TypeError('Unknown type of connection in createClient()');
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
59
node_modules/redis/lib/customErrors.js
generated
vendored
Normal file
59
node_modules/redis/lib/customErrors.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
var RedisError = require('redis-parser').RedisError;
|
||||
var ADD_STACKTRACE = false;
|
||||
|
||||
function AbortError (obj, stack) {
|
||||
assert(obj, 'The options argument is required');
|
||||
assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object');
|
||||
|
||||
RedisError.call(this, obj.message, ADD_STACKTRACE);
|
||||
Object.defineProperty(this, 'message', {
|
||||
value: obj.message || '',
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
if (stack || stack === undefined) {
|
||||
Error.captureStackTrace(this, AbortError);
|
||||
}
|
||||
for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) {
|
||||
this[key] = obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
function AggregateError (obj) {
|
||||
assert(obj, 'The options argument is required');
|
||||
assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object');
|
||||
|
||||
AbortError.call(this, obj, ADD_STACKTRACE);
|
||||
Object.defineProperty(this, 'message', {
|
||||
value: obj.message || '',
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
Error.captureStackTrace(this, AggregateError);
|
||||
for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) {
|
||||
this[key] = obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
util.inherits(AbortError, RedisError);
|
||||
util.inherits(AggregateError, AbortError);
|
||||
|
||||
Object.defineProperty(AbortError.prototype, 'name', {
|
||||
value: 'AbortError',
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
Object.defineProperty(AggregateError.prototype, 'name', {
|
||||
value: 'AggregateError',
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
AbortError: AbortError,
|
||||
AggregateError: AggregateError
|
||||
};
|
11
node_modules/redis/lib/debug.js
generated
vendored
Normal file
11
node_modules/redis/lib/debug.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var index = require('../');
|
||||
|
||||
function debug () {
|
||||
if (index.debug_mode) {
|
||||
console.error.apply(null, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = debug;
|
113
node_modules/redis/lib/extendedApi.js
generated
vendored
Normal file
113
node_modules/redis/lib/extendedApi.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var debug = require('./debug');
|
||||
var RedisClient = require('../').RedisClient;
|
||||
var Command = require('./command');
|
||||
var noop = function () {};
|
||||
|
||||
/**********************************************
|
||||
All documented and exposed API belongs in here
|
||||
**********************************************/
|
||||
|
||||
// Redirect calls to the appropriate function and use to send arbitrary / not supported commands
|
||||
RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = function (command, args, callback) {
|
||||
// Throw to fail early instead of relying in order in this case
|
||||
if (typeof command !== 'string') {
|
||||
throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name');
|
||||
}
|
||||
command = command.toLowerCase();
|
||||
if (!Array.isArray(args)) {
|
||||
if (args === undefined || args === null) {
|
||||
args = [];
|
||||
} else if (typeof args === 'function' && callback === undefined) {
|
||||
callback = args;
|
||||
args = [];
|
||||
} else {
|
||||
throw new TypeError('Wrong input type "' + args.constructor.name + '" for args');
|
||||
}
|
||||
}
|
||||
if (typeof callback !== 'function' && callback !== undefined) {
|
||||
throw new TypeError('Wrong input type "' + (callback !== null ? callback.constructor.name : 'null') + '" for callback function');
|
||||
}
|
||||
|
||||
// Using the raw multi command is only possible with this function
|
||||
// If the command is not yet added to the client, the internal function should be called right away
|
||||
// Otherwise we need to redirect the calls to make sure the internal functions don't get skipped
|
||||
// The internal functions could actually be used for any non hooked function
|
||||
// but this might change from time to time and at the moment there's no good way to distinguish them
|
||||
// from each other, so let's just do it do it this way for the time being
|
||||
if (command === 'multi' || typeof this[command] !== 'function') {
|
||||
return this.internal_send_command(new Command(command, args, callback));
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
args = args.concat([callback]); // Prevent manipulating the input array
|
||||
}
|
||||
return this[command].apply(this, args);
|
||||
};
|
||||
|
||||
RedisClient.prototype.end = function (flush) {
|
||||
// Flush queue if wanted
|
||||
if (flush) {
|
||||
this.flush_and_error({
|
||||
message: 'Connection forcefully ended and command aborted.',
|
||||
code: 'NR_CLOSED'
|
||||
});
|
||||
} else if (arguments.length === 0) {
|
||||
this.warn(
|
||||
'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' +
|
||||
'Please check the doku (https://github.com/NodeRedis/node_redis) and explictly use flush.'
|
||||
);
|
||||
}
|
||||
// Clear retry_timer
|
||||
if (this.retry_timer) {
|
||||
clearTimeout(this.retry_timer);
|
||||
this.retry_timer = null;
|
||||
}
|
||||
this.stream.removeAllListeners();
|
||||
this.stream.on('error', noop);
|
||||
this.connected = false;
|
||||
this.ready = false;
|
||||
this.closing = true;
|
||||
return this.stream.destroySoon();
|
||||
};
|
||||
|
||||
RedisClient.prototype.unref = function () {
|
||||
if (this.connected) {
|
||||
debug("Unref'ing the socket connection");
|
||||
this.stream.unref();
|
||||
} else {
|
||||
debug('Not connected yet, will unref later');
|
||||
this.once('connect', function () {
|
||||
this.unref();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
RedisClient.prototype.duplicate = function (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
var existing_options = utils.clone(this.options);
|
||||
options = utils.clone(options);
|
||||
for (var elem in options) {
|
||||
existing_options[elem] = options[elem];
|
||||
}
|
||||
var client = new RedisClient(existing_options);
|
||||
client.selected_db = this.selected_db;
|
||||
if (typeof callback === 'function') {
|
||||
var ready_listener = function () {
|
||||
callback(null, client);
|
||||
client.removeAllListeners(error_listener);
|
||||
};
|
||||
var error_listener = function (err) {
|
||||
callback(err);
|
||||
client.end(true);
|
||||
};
|
||||
client.once('ready', ready_listener);
|
||||
client.once('error', error_listener);
|
||||
return;
|
||||
}
|
||||
return client;
|
||||
};
|
617
node_modules/redis/lib/individualCommands.js
generated
vendored
Normal file
617
node_modules/redis/lib/individualCommands.js
generated
vendored
Normal file
@@ -0,0 +1,617 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var debug = require('./debug');
|
||||
var Multi = require('./multi');
|
||||
var Command = require('./command');
|
||||
var no_password_is_set = /no password is set/;
|
||||
var loading = /LOADING/;
|
||||
var RedisClient = require('../').RedisClient;
|
||||
|
||||
/********************************************************************************************
|
||||
Replace built-in redis functions
|
||||
|
||||
The callback may be hooked as needed. The same does not apply to the rest of the function.
|
||||
State should not be set outside of the callback if not absolutly necessary.
|
||||
This is important to make sure it works the same as single command or in a multi context.
|
||||
To make sure everything works with the offline queue use the "call_on_write" function.
|
||||
This is going to be executed while writing to the stream.
|
||||
|
||||
TODO: Implement individal command generation as soon as possible to prevent divergent code
|
||||
on single and multi calls!
|
||||
********************************************************************************************/
|
||||
|
||||
RedisClient.prototype.multi = RedisClient.prototype.MULTI = function multi (args) {
|
||||
var multi = new Multi(this, args);
|
||||
multi.exec = multi.EXEC = multi.exec_transaction;
|
||||
return multi;
|
||||
};
|
||||
|
||||
// ATTENTION: This is not a native function but is still handled as a individual command as it behaves just the same as multi
|
||||
RedisClient.prototype.batch = RedisClient.prototype.BATCH = function batch (args) {
|
||||
return new Multi(this, args);
|
||||
};
|
||||
|
||||
function select_callback (self, db, callback) {
|
||||
return function (err, res) {
|
||||
if (err === null) {
|
||||
// Store db in this.select_db to restore it on reconnect
|
||||
self.selected_db = db;
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) {
|
||||
return this.internal_send_command(new Command('select', [db], select_callback(this, db, callback)));
|
||||
};
|
||||
|
||||
Multi.prototype.select = Multi.prototype.SELECT = function select (db, callback) {
|
||||
this.queue.push(new Command('select', [db], select_callback(this._client, db, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function monitor (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;
|
||||
var call_on_write = function () {
|
||||
// Activating monitor mode has to happen before Redis returned the callback. The monitor result is returned first.
|
||||
// Therefore we expect the command to be properly processed. If this is not the case, it's not an issue either.
|
||||
self.monitoring = true;
|
||||
};
|
||||
return this.internal_send_command(new Command('monitor', [], callback, call_on_write));
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback) {
|
||||
// Use a individual command, as this is a special case that does not has to be checked for any other command
|
||||
if (this.exec !== this.exec_transaction) {
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
self._client.monitoring = true;
|
||||
};
|
||||
this.queue.push(new Command('monitor', [], callback, call_on_write));
|
||||
return this;
|
||||
}
|
||||
// Set multi monitoring to indicate the exec that it should abort
|
||||
// Remove this "hack" as soon as Redis might fix this
|
||||
this.monitoring = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
function quit_callback (self, callback) {
|
||||
return function (err, res) {
|
||||
if (err && err.code === 'NR_CLOSED') {
|
||||
// Pretent the quit command worked properly in this case.
|
||||
// Either the quit landed in the offline queue and was flushed at the reconnect
|
||||
// or the offline queue is deactivated and the command was rejected right away
|
||||
// or the stream is not writable
|
||||
// or while sending the quit, the connection ended / closed
|
||||
err = null;
|
||||
res = 'OK';
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
if (self.stream.writable) {
|
||||
// If the socket is still alive, kill it. This could happen if quit got a NR_CLOSED error code
|
||||
self.stream.destroy();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
RedisClient.prototype.QUIT = RedisClient.prototype.quit = function quit (callback) {
|
||||
// TODO: Consider this for v.3
|
||||
// Allow the quit command to be fired as soon as possible to prevent it landing in the offline queue.
|
||||
// this.ready = this.offline_queue.length === 0;
|
||||
var backpressure_indicator = this.internal_send_command(new Command('quit', [], quit_callback(this, callback)));
|
||||
// Calling quit should always end the connection, no matter if there's a connection or not
|
||||
this.closing = true;
|
||||
this.ready = false;
|
||||
return backpressure_indicator;
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.QUIT = Multi.prototype.quit = function quit (callback) {
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
// If called in a multi context, we expect redis is available
|
||||
self.closing = true;
|
||||
self.ready = false;
|
||||
};
|
||||
this.queue.push(new Command('quit', [], quit_callback(self, callback), call_on_write));
|
||||
return this;
|
||||
};
|
||||
|
||||
function info_callback (self, callback) {
|
||||
return function (err, res) {
|
||||
if (res) {
|
||||
var obj = {};
|
||||
var lines = res.toString().split('\r\n');
|
||||
var line, parts, sub_parts;
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
parts = lines[i].split(':');
|
||||
if (parts[1]) {
|
||||
if (parts[0].indexOf('db') === 0) {
|
||||
sub_parts = parts[1].split(',');
|
||||
obj[parts[0]] = {};
|
||||
while (line = sub_parts.pop()) {
|
||||
line = line.split('=');
|
||||
obj[parts[0]][line[0]] = +line[1];
|
||||
}
|
||||
} else {
|
||||
obj[parts[0]] = parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.versions = [];
|
||||
if (obj.redis_version) {
|
||||
obj.redis_version.split('.').forEach(function (num) {
|
||||
obj.versions.push(+num);
|
||||
});
|
||||
}
|
||||
// Expose info key/vals to users
|
||||
self.server_info = obj;
|
||||
} else {
|
||||
self.server_info = {};
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
// Store info in this.server_info after each call
|
||||
RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section, callback) {
|
||||
var args = [];
|
||||
if (typeof section === 'function') {
|
||||
callback = section;
|
||||
} else if (section !== undefined) {
|
||||
args = Array.isArray(section) ? section : [section];
|
||||
}
|
||||
return this.internal_send_command(new Command('info', args, info_callback(this, callback)));
|
||||
};
|
||||
|
||||
Multi.prototype.info = Multi.prototype.INFO = function info (section, callback) {
|
||||
var args = [];
|
||||
if (typeof section === 'function') {
|
||||
callback = section;
|
||||
} else if (section !== undefined) {
|
||||
args = Array.isArray(section) ? section : [section];
|
||||
}
|
||||
this.queue.push(new Command('info', args, info_callback(this._client, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
function auth_callback (self, pass, callback) {
|
||||
return 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.');
|
||||
err = null;
|
||||
res = 'OK';
|
||||
} else if (loading.test(err.message)) {
|
||||
// If redis is still loading the db, it will not authenticate and everything else will fail
|
||||
debug('Redis still loading, trying to authenticate later');
|
||||
setTimeout(function () {
|
||||
self.auth(pass, callback);
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, callback) {
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connection_id);
|
||||
|
||||
// Stash auth for connect and reconnect.
|
||||
this.auth_pass = pass;
|
||||
var ready = this.ready;
|
||||
this.ready = ready || this.offline_queue.length === 0;
|
||||
var tmp = this.internal_send_command(new Command('auth', [pass], auth_callback(this, pass, callback)));
|
||||
this.ready = ready;
|
||||
return tmp;
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.auth = Multi.prototype.AUTH = function auth (pass, callback) {
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connection_id);
|
||||
|
||||
// Stash auth for connect and reconnect.
|
||||
this.auth_pass = pass;
|
||||
this.queue.push(new Command('auth', [pass], auth_callback(this._client, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.client = RedisClient.prototype.CLIENT = function client () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
callback = arguments[1];
|
||||
} else if (Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = undefined;
|
||||
// CLIENT REPLY ON|OFF|SKIP
|
||||
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
|
||||
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
|
||||
var reply_on_off = arr[1].toString().toUpperCase();
|
||||
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') {
|
||||
call_on_write = function () {
|
||||
self.reply = reply_on_off;
|
||||
};
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command('client', arr, callback, call_on_write));
|
||||
};
|
||||
|
||||
Multi.prototype.client = Multi.prototype.CLIENT = function client () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
callback = arguments[1];
|
||||
} else if (Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = undefined;
|
||||
// CLIENT REPLY ON|OFF|SKIP
|
||||
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
|
||||
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
|
||||
var reply_on_off = arr[1].toString().toUpperCase();
|
||||
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') {
|
||||
call_on_write = function () {
|
||||
self.reply = reply_on_off;
|
||||
};
|
||||
}
|
||||
}
|
||||
this.queue.push(new Command('client', arr, callback, call_on_write));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function hmset () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
callback = arguments[1];
|
||||
} else if (Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else if (typeof arguments[1] === 'object' && (arguments.length === 2 || arguments.length === 3 && (typeof arguments[2] === 'function' || typeof arguments[2] === 'undefined'))) {
|
||||
arr = [arguments[0]];
|
||||
for (var field in arguments[1]) {
|
||||
arr.push(field, arguments[1][field]);
|
||||
}
|
||||
callback = arguments[2];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command('hmset', arr, callback));
|
||||
};
|
||||
|
||||
Multi.prototype.hmset = Multi.prototype.HMSET = function hmset () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0];
|
||||
callback = arguments[1];
|
||||
} else if (Array.isArray(arguments[1])) {
|
||||
if (len === 3) {
|
||||
callback = arguments[2];
|
||||
}
|
||||
len = arguments[1].length;
|
||||
arr = new Array(len + 1);
|
||||
arr[0] = arguments[0];
|
||||
for (; i < len; i += 1) {
|
||||
arr[i + 1] = arguments[1][i];
|
||||
}
|
||||
} else if (typeof arguments[1] === 'object' && (arguments.length === 2 || arguments.length === 3 && (typeof arguments[2] === 'function' || typeof arguments[2] === 'undefined'))) {
|
||||
arr = [arguments[0]];
|
||||
for (var field in arguments[1]) {
|
||||
arr.push(field, arguments[1][field]);
|
||||
}
|
||||
callback = arguments[2];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
this.queue.push(new Command('hmset', arr, callback));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.subscribe = RedisClient.prototype.SUBSCRIBE = function subscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('subscribe', arr, callback, call_on_write));
|
||||
};
|
||||
|
||||
Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('subscribe', arr, callback, call_on_write));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.unsubscribe = RedisClient.prototype.UNSUBSCRIBE = function unsubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('unsubscribe', arr, callback, call_on_write));
|
||||
};
|
||||
|
||||
Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('unsubscribe', arr, callback, call_on_write));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.psubscribe = RedisClient.prototype.PSUBSCRIBE = function psubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('psubscribe', arr, callback, call_on_write));
|
||||
};
|
||||
|
||||
Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('psubscribe', arr, callback, call_on_write));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.punsubscribe = RedisClient.prototype.PUNSUBSCRIBE = function punsubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('punsubscribe', arr, callback, call_on_write));
|
||||
};
|
||||
|
||||
Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscribe () {
|
||||
var arr,
|
||||
len = arguments.length,
|
||||
callback,
|
||||
i = 0;
|
||||
if (Array.isArray(arguments[0])) {
|
||||
arr = arguments[0].slice(0);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
len = arguments.length;
|
||||
// The later should not be the average use case
|
||||
if (len !== 0 && (typeof arguments[len - 1] === 'function' || typeof arguments[len - 1] === 'undefined')) {
|
||||
len--;
|
||||
callback = arguments[len];
|
||||
}
|
||||
arr = new Array(len);
|
||||
for (; i < len; i += 1) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('punsubscribe', arr, callback, call_on_write));
|
||||
return this;
|
||||
};
|
187
node_modules/redis/lib/multi.js
generated
vendored
Normal file
187
node_modules/redis/lib/multi.js
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
'use strict';
|
||||
|
||||
var Queue = require('double-ended-queue');
|
||||
var utils = require('./utils');
|
||||
var Command = require('./command');
|
||||
|
||||
function Multi (client, args) {
|
||||
this._client = client;
|
||||
this.queue = new Queue();
|
||||
var command, tmp_args;
|
||||
if (args) { // Either undefined or an array. Fail hard if it's not an array
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
command = args[i][0];
|
||||
tmp_args = args[i].slice(1);
|
||||
if (Array.isArray(command)) {
|
||||
this[command[0]].apply(this, command.slice(1).concat(tmp_args));
|
||||
} else {
|
||||
this[command].apply(this, tmp_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pipeline_transaction_command (self, command_obj, index) {
|
||||
// Queueing is done first, then the commands are executed
|
||||
var tmp = command_obj.callback;
|
||||
command_obj.callback = function (err, reply) {
|
||||
// Ignore the multi command. This is applied by node_redis and the user does not benefit by it
|
||||
if (err && index !== -1) {
|
||||
if (tmp) {
|
||||
tmp(err);
|
||||
}
|
||||
err.position = index;
|
||||
self.errors.push(err);
|
||||
}
|
||||
// Keep track of who wants buffer responses:
|
||||
// By the time the callback is called the command_obj got the buffer_args attribute attached
|
||||
self.wants_buffers[index] = command_obj.buffer_args;
|
||||
command_obj.callback = tmp;
|
||||
};
|
||||
self._client.internal_send_command(command_obj);
|
||||
}
|
||||
|
||||
Multi.prototype.exec_atomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function exec_atomic (callback) {
|
||||
if (this.queue.length < 2) {
|
||||
return this.exec_batch(callback);
|
||||
}
|
||||
return this.exec(callback);
|
||||
};
|
||||
|
||||
function multi_callback (self, err, replies) {
|
||||
var i = 0, command_obj;
|
||||
|
||||
if (err) {
|
||||
err.errors = self.errors;
|
||||
if (self.callback) {
|
||||
self.callback(err);
|
||||
// Exclude connection errors so that those errors won't be emitted twice
|
||||
} else if (err.code !== 'CONNECTION_BROKEN') {
|
||||
self._client.emit('error', err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (replies) {
|
||||
while (command_obj = self.queue.shift()) {
|
||||
if (replies[i] instanceof Error) {
|
||||
var match = replies[i].message.match(utils.err_code);
|
||||
// LUA script could return user errors that don't behave like all other errors!
|
||||
if (match) {
|
||||
replies[i].code = match[1];
|
||||
}
|
||||
replies[i].command = command_obj.command.toUpperCase();
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback(replies[i]);
|
||||
}
|
||||
} else {
|
||||
// If we asked for strings, even in detect_buffers mode, then return strings:
|
||||
replies[i] = self._client.handle_reply(replies[i], command_obj.command, self.wants_buffers[i]);
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback(null, replies[i]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.callback) {
|
||||
self.callback(null, replies);
|
||||
}
|
||||
}
|
||||
|
||||
Multi.prototype.exec_transaction = function exec_transaction (callback) {
|
||||
if (this.monitoring || this._client.monitoring) {
|
||||
var err = new RangeError(
|
||||
'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.'
|
||||
);
|
||||
err.command = 'EXEC';
|
||||
err.code = 'EXECABORT';
|
||||
return utils.reply_in_order(this._client, callback, err);
|
||||
}
|
||||
var self = this;
|
||||
var len = self.queue.length;
|
||||
self.errors = [];
|
||||
self.callback = callback;
|
||||
self._client.cork();
|
||||
self.wants_buffers = new Array(len);
|
||||
pipeline_transaction_command(self, new Command('multi', []), -1);
|
||||
// Drain queue, callback will catch 'QUEUED' or error
|
||||
for (var index = 0; index < len; index++) {
|
||||
// The commands may not be shifted off, since they are needed in the result handler
|
||||
pipeline_transaction_command(self, self.queue.get(index), index);
|
||||
}
|
||||
|
||||
self._client.internal_send_command(new Command('exec', [], function (err, replies) {
|
||||
multi_callback(self, err, replies);
|
||||
}));
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
};
|
||||
|
||||
function batch_callback (self, cb, i) {
|
||||
return function batch_callback (err, res) {
|
||||
if (err) {
|
||||
self.results[i] = err;
|
||||
// Add the position to the error
|
||||
self.results[i].position = i;
|
||||
} else {
|
||||
self.results[i] = res;
|
||||
}
|
||||
cb(err, res);
|
||||
};
|
||||
}
|
||||
|
||||
Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = function exec_batch (callback) {
|
||||
var self = this;
|
||||
var len = self.queue.length;
|
||||
var index = 0;
|
||||
var command_obj;
|
||||
if (len === 0) {
|
||||
utils.reply_in_order(self._client, callback, null, []);
|
||||
return !self._client.should_buffer;
|
||||
}
|
||||
self._client.cork();
|
||||
if (!callback) {
|
||||
while (command_obj = self.queue.shift()) {
|
||||
self._client.internal_send_command(command_obj);
|
||||
}
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
}
|
||||
var callback_without_own_cb = function (err, res) {
|
||||
if (err) {
|
||||
self.results.push(err);
|
||||
// Add the position to the error
|
||||
var i = self.results.length - 1;
|
||||
self.results[i].position = i;
|
||||
} else {
|
||||
self.results.push(res);
|
||||
}
|
||||
// Do not emit an error here. Otherwise each error would result in one emit.
|
||||
// The errors will be returned in the result anyway
|
||||
};
|
||||
var last_callback = function (cb) {
|
||||
return function (err, res) {
|
||||
cb(err, res);
|
||||
callback(null, self.results);
|
||||
};
|
||||
};
|
||||
self.results = [];
|
||||
while (command_obj = self.queue.shift()) {
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback = batch_callback(self, command_obj.callback, index);
|
||||
} else {
|
||||
command_obj.callback = callback_without_own_cb;
|
||||
}
|
||||
if (typeof callback === 'function' && index === len - 1) {
|
||||
command_obj.callback = last_callback(command_obj.callback);
|
||||
}
|
||||
this._client.internal_send_command(command_obj);
|
||||
index++;
|
||||
}
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
};
|
||||
|
||||
module.exports = Multi;
|
134
node_modules/redis/lib/utils.js
generated
vendored
Normal file
134
node_modules/redis/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
|
||||
// hgetall converts its replies to an Object. If the reply is empty, null is returned.
|
||||
// These function are only called with internal data and have therefore always the same instanceof X
|
||||
function replyToObject (reply) {
|
||||
// The reply might be a string or a buffer if this is called in a transaction (multi)
|
||||
if (reply.length === 0 || !(reply instanceof Array)) {
|
||||
return null;
|
||||
}
|
||||
var obj = {};
|
||||
for (var i = 0; i < reply.length; i += 2) {
|
||||
obj[reply[i].toString('binary')] = reply[i + 1];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function replyToStrings (reply) {
|
||||
if (reply instanceof Buffer) {
|
||||
return reply.toString();
|
||||
}
|
||||
if (reply instanceof Array) {
|
||||
var res = new Array(reply.length);
|
||||
for (var i = 0; i < reply.length; i++) {
|
||||
// Recusivly call the function as slowlog returns deep nested replies
|
||||
res[i] = replyToStrings(reply[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
function print (err, reply) {
|
||||
if (err) {
|
||||
// A error always begins with Error:
|
||||
console.log(err.toString());
|
||||
} else {
|
||||
console.log('Reply: ' + reply);
|
||||
}
|
||||
}
|
||||
|
||||
var camelCase;
|
||||
// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error)
|
||||
// Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions)
|
||||
// All capital letters are going to be replaced with a lower case letter and a underscore infront of it
|
||||
function clone (obj) {
|
||||
var copy;
|
||||
if (Array.isArray(obj)) {
|
||||
copy = new Array(obj.length);
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
copy[i] = clone(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
if (Object.prototype.toString.call(obj) === '[object Object]') {
|
||||
copy = {};
|
||||
var elems = Object.keys(obj);
|
||||
var elem;
|
||||
while (elem = elems.pop()) {
|
||||
if (elem === 'tls') { // special handle tls
|
||||
copy[elem] = obj[elem];
|
||||
continue;
|
||||
}
|
||||
// Accept camelCase options and convert them to snake_case
|
||||
var snake_case = elem.replace(/[A-Z][^A-Z]/g, '_$&').toLowerCase();
|
||||
// If camelCase is detected, pass it to the client, so all variables are going to be camelCased
|
||||
// There are no deep nested options objects yet, but let's handle this future proof
|
||||
if (snake_case !== elem.toLowerCase()) {
|
||||
camelCase = true;
|
||||
}
|
||||
copy[snake_case] = clone(obj[elem]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function convenienceClone (obj) {
|
||||
camelCase = false;
|
||||
obj = clone(obj) || {};
|
||||
if (camelCase) {
|
||||
obj.camel_case = true;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function callbackOrEmit (self, callback, err, res) {
|
||||
if (callback) {
|
||||
callback(err, res);
|
||||
} else if (err) {
|
||||
self.emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
function replyInOrder (self, callback, err, res, queue) {
|
||||
// If the queue is explicitly passed, use that, otherwise fall back to the offline queue first,
|
||||
// as there might be commands in both queues at the same time
|
||||
var command_obj;
|
||||
/* istanbul ignore if: TODO: Remove this as soon as we test Redis 3.2 on travis */
|
||||
if (queue) {
|
||||
command_obj = queue.peekBack();
|
||||
} else {
|
||||
command_obj = self.offline_queue.peekBack() || self.command_queue.peekBack();
|
||||
}
|
||||
if (!command_obj) {
|
||||
process.nextTick(function () {
|
||||
callbackOrEmit(self, callback, err, res);
|
||||
});
|
||||
} else {
|
||||
var tmp = command_obj.callback;
|
||||
command_obj.callback = tmp ?
|
||||
function (e, r) {
|
||||
tmp(e, r);
|
||||
callbackOrEmit(self, callback, err, res);
|
||||
} :
|
||||
function (e, r) {
|
||||
if (e) {
|
||||
self.emit('error', e);
|
||||
}
|
||||
callbackOrEmit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
reply_to_strings: replyToStrings,
|
||||
reply_to_object: replyToObject,
|
||||
print: print,
|
||||
err_code: /^([A-Z]+)\s+(.+)$/,
|
||||
monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/,
|
||||
clone: convenienceClone,
|
||||
callback_or_emit: callbackOrEmit,
|
||||
reply_in_order: replyInOrder
|
||||
};
|
Reference in New Issue
Block a user