diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index 39e47c805e303c5fa3de6ea28b6ed12144fd31ea..a8014755360de174c6529d7d096c9f90821e15e1 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -1541,8 +1541,11 @@ SqlBuilder.prototype._addWhere = function(pFieldOrCond, pValue, pMandatory, pCon // remove the first $ if there are two $ if (typeofValue == "string" && pValue.length >= 2 && pValue[0] == "$" && pValue[1] == "$") pValue = pValue.slice(1); - - + + //support for Set by converting to Array + if (pValue instanceof Set) + pValue = Array.from(pValue); + // pValue can be... // ... a SqlBuilder / Prepared statement array -> it is a SqlBuilder containing a complete subquery or an simple array (in statement) if (pValue instanceof SqlBuilder || Array.isArray(pValue) || (typeofValue == "string" && (pFieldOrCond == undefined || pFieldOrCond == null))) @@ -2459,7 +2462,7 @@ SqlBuilder.prototype.updateData = function(pExecuteOnlyIfConditionExists, pTable * Updates data in the database. This function calls SqlBuilder.prototype.updateData, but provides a shorter syntax to * improve the readability. * - * @param {Object} pFieldValues Object with the columns to update as keys mapped to their values + * @param {Object|Map} pFieldValues Object with the columns to update as keys mapped to their values * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set, * the table of the first where-condition is used. * @return {Number} the number of rows affected @@ -2472,22 +2475,16 @@ SqlBuilder.prototype.updateFields = function (pFieldValues, pTableName) if (!pFieldValues || typeof(pFieldValues) !== "object") throw SqlBuilder._ERROR_UPDATE_VALUES_INVALID; - var columns = []; - var values = []; - for (let field in pFieldValues) - { - columns.push(field); - values.push(pFieldValues[field].toString()); - } - if (columns.length === 0) + var columnValues = SqlBuilder._columnsValuesFromObject(pFieldValues, true); + if (columnValues.columns.length === 0) return 0; - return this.updateData(true, pTableName, columns, null, values); + return this.updateData(true, pTableName, columnValues.columns, null, columnValues.values); } /** * Builds an array containing the table and condition for an update. * - * @param {Object} pFieldValues Object with the columns to update as keys mapped to their values + * @param {Object|Map} pFieldValues Object with the columns to update as keys mapped to their values * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set, * the table of the first where-condition is used. * @return {Array} array of [tableName, columns, columnTypes, values, preparedCondition], like it is required by db.updates or null if there is no condition @@ -2502,25 +2499,51 @@ SqlBuilder.prototype.buildUpdateStatement = function (pFieldValues, pTableName) if (!pFieldValues || typeof(pFieldValues) !== "object") throw SqlBuilder._ERROR_UPDATE_VALUES_INVALID; - var columns = []; - var values = []; - for (let field in pFieldValues) + var columnValues = SqlBuilder._columnsValuesFromObject(pFieldValues, true); + if (columnValues.columns.length !== 0 && this._checkForUpdate()) { - columns.push(field); - values.push(pFieldValues[field].toString()); + if (!pTableName && !this._tableName) + throw SqlBuilder._ERROR_NO_TABLE(); + + return [ + (pTableName ? pTableName : this._tableName), + columnValues.columns, + null, + columnValues.values, + this.buildCondition() + ]; } + return null; +} + +/** + * Builds an array containing the data for an insert. + * + * @param {Object|Map} pFieldValues Object with the columns to insert into as keys mapped to their values + * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set, + * the table of the first where-condition is used. + * @param {String} [pAutoUidField] UID column that should be filled with a random UUID + * @return {Array} array of [tableName, columns, columnTypes, values, preparedCondition], like it is required by db.updates or null if there is no condition + */ +SqlBuilder.prototype.buildInsertStatement = function (pFieldValues, pTableName, pAutoUidField) +{ + if (!pFieldValues || !Utils.isObject(pFieldValues)) + throw SqlBuilder._ERROR_UPDATE_VALUES_INVALID; + + if (pAutoUidField) + pFieldValues[pAutoUidField] = util.getNewUUID(); - if (columns.length !== 0 && this._checkForUpdate()) + var columnValues = SqlBuilder._columnsValuesFromObject(pFieldValues); + if (columnValues.columns.length !== 0) { if (!pTableName && !this._tableName) throw SqlBuilder._ERROR_NO_TABLE(); return [ (pTableName ? pTableName : this._tableName), - columns, + columnValues.columns, null, - values, - this.buildCondition() + columnValues.values ]; } return null; @@ -2559,7 +2582,7 @@ SqlBuilder.prototype.insertData = function(pTableName, pColumns, pColumnTypes, p * Inserts data in the database. This function calls SqlBuilder.prototype.insertData, but provides a shorter syntax to * improve the readability. * - * @param {Object} pFieldValues Object with the columns to update as keys mapped to their values + * @param {Object|Map} pFieldValues Object with the columns to update as keys mapped to their values * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set, * the table of the first where-condition is used. * @param {String} [pAutoUidField] UID column that should be filled with a random UUID @@ -2579,19 +2602,49 @@ SqlBuilder.prototype.insertFields = function (pFieldValues, pTableName, pAutoUid if (pAutoUidField) pFieldValues[pAutoUidField] = util.getNewUUID(); + var columnValues = SqlBuilder._columnsValuesFromObject(pFieldValues); + if (columnValues.columns.length === 0) + return 0; + return this.insertData(pTableName, columnValues.columns, null, columnValues.values); +} + +SqlBuilder._columnsValuesFromObject = function (pFieldValues, pIncludeNullValues) +{ var columns = []; var values = []; - for (let field in pFieldValues) + if (Utils.isMap(pFieldValues)) + { + pFieldValues.forEach(function (value, key) + { + if (pIncludeNullValues || (value !== undefined && value !== null)) + { + columns.push(key); + values.push(_valueToString(value)); + } + }); + } + else { - if (pFieldValues[field] !== undefined && pFieldValues[field] !== null) + for (let field in pFieldValues) { - columns.push(field); - values.push(pFieldValues[field].toString()); + if (pIncludeNullValues || (pFieldValues[field] !== undefined && pFieldValues[field] !== null)) + { + columns.push(field); + values.push(_valueToString(pFieldValues[field])); + } } } - if (columns.length === 0) - return 0; - return this.insertData(pTableName, columns, null, values); + return { + columns: columns, + values: values + }; + + function _valueToString (pValue) + { + if (pValue === undefined || pValue === null) + return ""; + return pValue.toString(); + } } /** diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js index 2c687d66a4dda42890909aa061ac311e69be5ef9..74776d9ad9aa543e93d6c62979fafa33f8c63b2a 100644 --- a/process/Util_lib/process.js +++ b/process/Util_lib/process.js @@ -23,15 +23,17 @@ import("Date_lib"); function Utils () {} /** - * Checks if the given object, array or string is empty. + * Checks if the given object, array, map, set or string is empty. * - * @param {Object|Array|String} pObject the object to check + * @param {Object|Array|String|Map|Set} pObject the object to check * @return {Boolean} true if the object is empty */ Utils.isEmpty = function (pObject) { if (Utils.isString(pObject) || Array.isArray(pObject)) return pObject.length === 0; + if (pObject instanceof Set || pObject instanceof Map) + return pObject.size === 0; for (let key in pObject) { return false; @@ -175,6 +177,17 @@ Utils.isObject = function (pValue) return typeof pValue === "object"; } +/** + * Checks if the given value is a Map. + * + * @param {Object} pValue the value to check + * @return {Boolean} true if the value is a Map + */ +Utils.isMap = function (pValue) +{ + return pValue instanceof Map; +} + /** * Checks if the given value is a boolean. * @@ -203,6 +216,25 @@ Utils.toBoolean = function (pValue) return !(!pValue || pValue === "0" || pValue === "false" || pValue === "null" || pValue === "undefined" || !(pValue.valueOf())); } +/** + * Creates an object containing the keys and values of the given Map + * + * @param {Map} pMap a Map + * @return {Object} object with properties from the Map + */ +Utils.objectFromMap = function (pMap) +{ + if (!Utils.isMap(pMap)) + return pMap; //throw error? + + var mapObject = {}; //maybe use Object.create(null)? + pMap.forEach(function (value, key) + { + mapObject[key] = value; + }); + return mapObject; +} + /** * Class containing static utility functions for regular expression objects (RegExp) * Do not create an instance of this