From fcdadc8bd486c32bf7362794f56aca4398e3e887 Mon Sep 17 00:00:00 2001 From: Sebastian Listl <s.listl@adito.de> Date: Fri, 30 Oct 2020 11:36:53 +0100 Subject: [PATCH] Utils.clone support for Map, Set and Symbol properties --- process/Sql_lib/process.js | 27 +++++------------------ process/Util_lib/process.js | 43 ++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index d0c827e77c..fc73644c52 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -801,8 +801,6 @@ function SqlBuilder (pAlias) this._where = {}; this._initWhere(); - - SqlBuilder.defineCanBuildSql(this); } /** @@ -823,6 +821,8 @@ SqlBuilder.checkCanBuildSql = function (pObject) return pObject[SqlBuilder.getCanBuildSqlSymbol()]; } +SqlBuilder.defineCanBuildSql(SqlBuilder.prototype); + /** * Deep copies the SqlBuilder object and returns a new one.<br/> * Use this if you want to add for example add additional parameters without modifying the current builder. @@ -830,25 +830,7 @@ SqlBuilder.checkCanBuildSql = function (pObject) */ SqlBuilder.prototype.copy = function() { - var newBuilder = _deepCopyByJson(this, new SqlBuilder()); - return newBuilder; - - // NOTE: this works only with simple data types. - // Here we only use strings, arrays, booleans and null, so this should work - function _deepCopyByJson(pObject, pNewObject) - { - // deep copy by using json - var deepCopied = JSON.parse(JSON.stringify(pObject)); - - // set the props of the new object to the deepCopied ones. - // without this all functions would be lost - for (let prop in deepCopied) - { - pNewObject[prop] = deepCopied[prop] - } - - return pNewObject; - } + return Utils.clone(this); } // errors which are thrown by the SqlBuilder @@ -3117,9 +3099,10 @@ SqlBuilder._CaseStatement = function () this._whenThens = []; this._elseValue = null; this._afterWhenMask = new SqlBuilder._CaseWhen(this); - SqlBuilder.defineCanBuildSql(this); } +SqlBuilder.defineCanBuildSql(SqlBuilder._CaseStatement.prototype); + /** * @param {String|String[]|SqlBuilder|PreparedSqlArray} [pFieldOrCond] If this is the only parameter, it is used as Subselect <br/> * else it is used as Field. <br/> diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js index 97545be173..778e4ae46c 100644 --- a/process/Util_lib/process.js +++ b/process/Util_lib/process.js @@ -53,7 +53,7 @@ Utils.isNullOrEmpty = function (pObject) } /** - * Creates a deep copy of the given object. Also works with arrays. + * Creates a deep copy of the given object. Also works with arrays, maps and sets. * * @param {Object} pObject the object to create a copy of * @return {Object} the cloned object @@ -69,7 +69,7 @@ Utils.isNullOrEmpty = function (pObject) * * logging.log(original.name != copy.name); //true * logging.log(copy instanceof MyObject()); //true, prototypes are set correctly - * logging.log(copy.obj1 === copy.obj2); //true, relative object references are kept + * logging.log(copy.obj1 === copy.obj2); //true, relative object references are preserved */ Utils.clone = function (pObject) { @@ -84,20 +84,47 @@ Utils.clone = function (pObject) if (referenceMap.has(pObject)) return referenceMap.get(pObject); - var clonedObject = Array.isArray(pObject) - ? [] - : Object.create(Object.getPrototypeOf(pObject)); //set the prototype of the given object + var clonedObject; + if (Array.isArray(pObject)) + clonedObject = []; + else if (pObject instanceof Map) + clonedObject = new Map(); + else if (pObject instanceof Set) + clonedObject = new Set(); + else + clonedObject = Object.create(Object.getPrototypeOf(pObject)); //set the prototype of the given object /* keeps track of all encountered objects and maps the original to the copy, this makes it possible to: - have the same relative references in the copy as in the original - copy cyclic references without error */ referenceMap.set(pObject, clonedObject); - for (let key in pObject) + if (pObject instanceof Map) + { + pObject.forEach(function (value, key) + { + clonedObject.set(_clone(key), _clone(value)); + }); + } + else if (pObject instanceof Set) { - var value = pObject[key]; - clonedObject[key] = _clone(value); //Recursively (deep) copy for nested objects, including arrays + pObject.forEach(function (value) + { + clonedObject.add(_clone(value)); + }); } + else + { + for (let key in pObject) + { + clonedObject[key] = _clone(pObject[key]); //Recursively (deep) copy for nested objects, including arrays + } + } + + Object.getOwnPropertySymbols(pObject).forEach(function (sym) + { + clonedObject[sym] = _clone(pObject[sym]); + }); return clonedObject; } -- GitLab