1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-04 15:02:09 +03:00

Use a own clone function instead of using JSON.parse(JSON.stringify())

This will also clone functions
This commit is contained in:
Ruben Bridgewater
2016-01-21 22:36:07 +01:00
parent 60eee34de1
commit 518e46dcc7
2 changed files with 34 additions and 8 deletions

View File

@@ -15,7 +15,6 @@ var default_port = 6379;
var default_host = '127.0.0.1'; var default_host = '127.0.0.1';
function noop () {} function noop () {}
function clone (obj) { return JSON.parse(JSON.stringify(obj || {})); }
function debug (msg) { if (exports.debug_mode) { console.error(msg); } } function debug (msg) { if (exports.debug_mode) { console.error(msg); } }
function handle_detect_buffers_reply (reply, command, buffer_args) { function handle_detect_buffers_reply (reply, command, buffer_args) {
@@ -35,7 +34,7 @@ exports.debug_mode = /\bredis\b/i.test(process.env.NODE_DEBUG);
function RedisClient (options) { function RedisClient (options) {
// Copy the options so they are not mutated // Copy the options so they are not mutated
options = clone(options); options = utils.clone(options);
events.EventEmitter.call(this); events.EventEmitter.call(this);
var cnx_options = {}; var cnx_options = {};
var self = this; var self = this;
@@ -205,8 +204,8 @@ RedisClient.prototype.cork = noop;
RedisClient.prototype.uncork = noop; RedisClient.prototype.uncork = noop;
RedisClient.prototype.duplicate = function (options) { RedisClient.prototype.duplicate = function (options) {
var existing_options = clone(this.options); var existing_options = utils.clone(this.options);
options = clone(options); options = utils.clone(options);
for (var elem in options) { // jshint ignore: line for (var elem in options) { // jshint ignore: line
existing_options[elem] = options[elem]; existing_options[elem] = options[elem];
} }
@@ -1293,11 +1292,11 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct
var createClient = function (port_arg, host_arg, options) { var createClient = function (port_arg, host_arg, options) {
if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) { if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) {
options = clone(options); options = utils.clone(options);
options.host = host_arg; options.host = host_arg;
options.port = port_arg; options.port = port_arg;
} else if (typeof port_arg === 'string' || port_arg && port_arg.url) { } else if (typeof port_arg === 'string' || port_arg && port_arg.url) {
options = clone(port_arg.url ? port_arg : host_arg || options); options = utils.clone(port_arg.url ? port_arg : host_arg || options);
var parsed = URL.parse(port_arg.url || port_arg, true, true); var parsed = URL.parse(port_arg.url || port_arg, true, true);
// [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]] // [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
if (parsed.hostname || parsed.slashes) { // The host might be an empty string if (parsed.hostname || parsed.slashes) { // The host might be an empty string
@@ -1326,7 +1325,7 @@ var createClient = function (port_arg, host_arg, options) {
options.path = port_arg; options.path = port_arg;
} }
} else if (typeof port_arg === 'object' || port_arg === undefined) { } else if (typeof port_arg === 'object' || port_arg === undefined) {
options = clone(port_arg || options); options = utils.clone(port_arg || options);
options.host = options.host || host_arg; options.host = options.host || host_arg;
} }
if (!options) { if (!options) {

View File

@@ -38,9 +38,36 @@ function print (err, reply) {
var redisErrCode = /^([A-Z]+)\s+(.+)$/; var redisErrCode = /^([A-Z]+)\s+(.+)$/;
// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error)
function clone (obj) {
if (obj) {
var copy;
if (obj.constructor === Array) {
copy = new Array(obj.length);
for (var i = 0; i < obj.length; i++) {
copy[i] = clone(obj[i]);
}
return copy;
}
if (obj.constructor === Object) {
copy = {};
for (var elem in obj) {
if (!obj.hasOwnProperty(elem)) {
// Do not add non own properties to the cloned object
continue;
}
copy[elem] = clone(obj[elem]);
}
return copy;
}
}
return obj;
}
module.exports = { module.exports = {
reply_to_strings: replyToStrings, reply_to_strings: replyToStrings,
reply_to_object: replyToObject, reply_to_object: replyToObject,
print: print, print: print,
err_code: redisErrCode err_code: redisErrCode,
clone: clone
}; };