diff --git a/process/JditoFilter_lib/process.js b/process/JditoFilter_lib/process.js index 0bf0df5dfe93040bf83bc6648b39e3c5ba9cc649..db3530bb225daae9d9e2a33de38bba19a19bd273 100644 --- a/process/JditoFilter_lib/process.js +++ b/process/JditoFilter_lib/process.js @@ -1,292 +1,292 @@ -import("Sql_lib"); - -//private scope to make only JditoFilterUtils public -var JditoFilterUtils = (function () -{ - -/** - * object for filtering records - * - * @param {Array} pColumns the column names - * @param {Object} pFilter the filter object - * @param {Object} pCustomCheckFns - * @param {Object} pCheckFnThisArg - * - * @private - */ -function JditoFilterHelper (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg) -{ - var columnMap = {}; - for (let i = 0, l = pColumns.length; i < l; i++) - { - let col = pColumns[i]; - if (col) - columnMap[col] = { - index : i, - checkFn : pCustomCheckFns[col] || {} - }; - } - this.columnMap = columnMap; - this.filter = pFilter; - this.checkFnThisArg = pCheckFnThisArg || null; -} - -/** - * tests the given row if it matches the filter - * - * @param {Array} pRow one record - * - * @return {boolean} true, if it matches the condition - */ -JditoFilterHelper.prototype.checkRecord = function (pRow) -{ - if (this.filter.length == 0) - return true; - - return _testRecord.call(this, this.filter); - - /** - * recursive function to test the row against the condition - */ - function _testRecord (pCondition) - { - if (pCondition.type == "row") - { - let value = pRow[this.columnMap[pCondition.name].index]; - let testFn = this.columnMap[pCondition.name].checkFn || _testValue; - return testFn.call(this.checkFnThisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow); - } - else if (pCondition.type == "group") - { - if (pCondition.operator == "AND") - return pCondition.childs.every(_testRecord, this); - return pCondition.childs.some(_testRecord, this); - } - return true; - } - - /** - * compares two values with the given operator - */ - function _testValue (pRowValue, pFilterValue, pOperator) - { - switch (pOperator) - { - case "CONTAINS": - return (new RegExp(pFilterValue)).test(pRowValue); - case "CONTAINSNOT": - return !(new RegExp(pFilterValue)).test(pRowValue); - case "STARTSWITH": - return (new RegExp("^" + pFilterValue)).test(pRowValue); - case "ENDSWITH": - return (new RegExp(pFilterValue + "$")).test(pRowValue); - case "EQUAL": - return (new RegExp("^" + pFilterValue + "$")).test(pRowValue); - case "NOT_EQUAL": - return !(new RegExp("^" + pFilterValue + "$")).test(pRowValue); - case "LESS": - return pRowValue < pFilterValue; - case "LESS_OR_EQUAL": - return pRowValue <= pFilterValue; - case "GREATER": - return pRowValue > pFilterValue; - case "GREATER_OR_EQUAL": - return pRowValue >= pFilterValue; - case "ISNULL": - return pRowValue == ""; - case "ISNOTNULL": - return pRowValue != ""; - } - } -} - - - -/** - * Provides functions for using the filter with jdito recordcontainers - * - * Do not instanciate this! - * - * @class - */ -function JditoFilterUtils () {} - -JditoFilterUtils.getFilterFields = function (pFilterJsonRootNode) -{ - let filterFields = []; - for(var filterChildNode in pFilterJsonRootNode) - { - var currentNode = pFilterJsonRootNode[filterChildNode]; - if(currentNode.type == "row") - { - let fieldName = currentNode.name; - filterFields.push(fieldName); - } - else - { - JditoFilterUtils.getFilterFields(filterChildNode); - } - } - return filterFields; -} - -/** - * Filters the given records manually. If you get the records using a sql query, you might consider using - * JditoFilterUtils.getSqlCondition instead for better performance. - * - * @param {Array} pColumns one dimensional array with all column names (only the columns with the idValue, displayValue columns should be null or ""), - * the order has to match the columns of the recordFields property in the recordcontainer - * @param {Array} pRecords two dimensional array with all records - * @param {String|Object} pFilter the value of vars.get($local.filter).filter - * @param {Object} [pCustomCheckFns] Object of custom functions that should be used to ckeck records. The key has to be the name of the fields you want to - * check. The provided function will be called with the arguments (recordValue, filterValue, operator, record) and should return a boolean (or something truthy or falsy). - * @param {Object} [pCheckFnThisArg] The object that should be the this-context when the custom check functions are called. This can be useful if you - * need some kind of storage for extra data you need in your function that you don't have to load for every record. - * - * @return {Array} the filtered records - */ -JditoFilterUtils.filterRecords = function (pColumns, pRecords, pFilter, pCustomCheckFns, pCheckFnThisArg) -{ - if (!pFilter) - return pRecords; - - var filter = new JditoFilterHelper(pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg); - - return pRecords.filter(function (row) - { - return this.checkRecord(row); - }, filter); -} - -/** - * builds an sql condition from the given filter - * - * @param {Object} pFilter the filter object - * @param {String} pTable the database table - * @param {String} [pTableAlias=null] the database table alias - * @param {Object} [pColumnOrFnMap=null] Custom mapping for the fields to the DB columns or functions that return a SqlCondition, this is necessary - * if the fields are from different tables. Structure has to be like this: - * { - * FIELD1 : "TABLE1.COLUMN1", - * FIELD2 : ["TABLE2", "COLUMN2", "TABLE2ALIAS"], //do it like this if the table has an alias - * FIELD3 : function (pValue, pOperator) //function if you need to build a special condition - * { - * var cond = new SqlCondition(); - * ... - * return cond; - * } - * } - * - * @example - * var condition = SqlCondition.begin(); - * if (vars.exists("$local.filter") && vars.get("$local.filter")) - * { - * var filter = vars.get("$local.filter"); - * if (filter.filter) - * condition.andSqlCondition((JditoFilterUtils.getSqlCondition(filter.filter, "AB_ATTRIBUTE"))); - * } - * var attributeSql = condition.buildSql("select AB_ATTRIBUTEID from AB_ATTRIBUTE"); - * - * @return {SqlCondition} the SqlCondition object - */ -JditoFilterUtils.getSqlCondition = function (pFilter, pTable, pTableAlias, pColumnOrFnMap) -{ - var condition = new SqlCondition(); - - if (!pFilter) - return condition; - if (!pColumnOrFnMap) - pColumnOrFnMap = {}; - - _addCondition.call(condition, pFilter, pFilter.operator); - - return condition; - - //recursive function (for compatibility with a condition tree) that - //builds the SqlCondition - function _addCondition (pCondition, pOperator) - { - if (pCondition.type == "row") - { - if (pCondition.name in pColumnOrFnMap) - pCondition.name = pColumnOrFnMap[pCondition.name]; - else if (pTable && pTableAlias) - pCondition.name = [pTable, pCondition.name, pTableAlias]; - else if (pTable) - pCondition.name = pTable + "." + pCondition.name; - - pCondition.value = (pCondition.key || pCondition.value); - - var condition; - if (typeof(pCondition.name) === "function") - { - condition = pCondition.name.call(null, pCondition.value, pCondition.operator); - if (pOperator == "AND") - this.andSqlCondition(condition); - else if (pOperator == "OR") - this.orSqlCondition(condition); - } - else - { - condition = _getCondition.call(pCondition, pCondition.value, pCondition.operator); - if (pOperator == "AND") - this.andPrepare(pCondition.name, pCondition.value, condition); - else if (pOperator == "OR") - this.orPrepare(pCondition.name, pCondition.value, condition); - } - } - else if (pCondition.type == "group") - { - let subCondition = new SqlCondition(); - let operator = pCondition.operator; - pCondition.childs.forEach(function (cond) - { - _addCondition.call(subCondition, cond, operator); - }); - if (pOperator == "AND") - this.andSqlCondition(subCondition); - else if (pOperator == "OR") - this.orSqlCondition(subCondition); - } - } - - //returns the condition depending on the operator and - //adds wildcards to the value if necessary - function _getCondition (pValue, pOperator) - { - switch (pOperator) - { - case "CONTAINS": - this.value = "%" + pValue + "%"; - return "# like ?"; - case "CONTAINSNOT": - this.value = "%" + pValue + "%"; - return "# not like ?"; - case "STARTSWITH": - this.value = pValue + "%"; - return "# like ?"; - case "ENDSWITH": - this.value = "%" + pValue; - return "# like ?"; - case "EQUAL": - return "# = ?"; - case "NOT_EQUAL": - return "# != ?"; - case "LESS": - return "# < ?"; - case "LESS_OR_EQUAL": - return "# <= ?"; - case "GREATER": - return "# > ?"; - case "GREATER_OR_EQUAL": - return "# >= ?"; - case "ISNULL": - return "# is null"; - case "ISNOTNULL": - return "# is not null"; - } - } -} - return JditoFilterUtils; //return only functions that should be public - +import("Sql_lib"); + +//private scope to make only JditoFilterUtils public +var JditoFilterUtils = (function () +{ + +/** + * object for filtering records + * + * @param {Array} pColumns the column names + * @param {Object} pFilter the filter object + * @param {Object} pCustomCheckFns + * @param {Object} pCheckFnThisArg + * + * @private + */ +function JditoFilterHelper (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg) +{ + var columnMap = {}; + for (let i = 0, l = pColumns.length; i < l; i++) + { + let col = pColumns[i]; + if (col) + columnMap[col] = { + index : i, + checkFn : pCustomCheckFns[col]//or nothing when there is no custom function + }; + } + this.columnMap = columnMap; + this.filter = pFilter; + this.checkFnThisArg = pCheckFnThisArg || null; +} + +/** + * tests the given row if it matches the filter + * + * @param {Array} pRow one record + * + * @return {boolean} true, if it matches the condition + */ +JditoFilterHelper.prototype.checkRecord = function (pRow) +{ + if (this.filter.length == 0) + return true; + + return _testRecord.call(this, this.filter); + + /** + * recursive function to test the row against the condition + */ + function _testRecord (pCondition) + { + if (pCondition.type == "row") + { + let value = pRow[this.columnMap[pCondition.name].index]; + let testFn = this.columnMap[pCondition.name].checkFn || _testValue; + return testFn.call(this.checkFnThisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow); + } + else if (pCondition.type == "group") + { + if (pCondition.operator == "AND") + return pCondition.childs.every(_testRecord, this); + return pCondition.childs.some(_testRecord, this); + } + return true; + } + + /** + * compares two values with the given operator + */ + function _testValue (pRowValue, pFilterValue, pOperator) + { + switch (pOperator) + { + case "CONTAINS": + return (new RegExp(pFilterValue)).test(pRowValue); + case "CONTAINSNOT": + return !(new RegExp(pFilterValue)).test(pRowValue); + case "STARTSWITH": + return (new RegExp("^" + pFilterValue)).test(pRowValue); + case "ENDSWITH": + return (new RegExp(pFilterValue + "$")).test(pRowValue); + case "EQUAL": + return (new RegExp("^" + pFilterValue + "$")).test(pRowValue); + case "NOT_EQUAL": + return !(new RegExp("^" + pFilterValue + "$")).test(pRowValue); + case "LESS": + return pRowValue < pFilterValue; + case "LESS_OR_EQUAL": + return pRowValue <= pFilterValue; + case "GREATER": + return pRowValue > pFilterValue; + case "GREATER_OR_EQUAL": + return pRowValue >= pFilterValue; + case "ISNULL": + return pRowValue == ""; + case "ISNOTNULL": + return pRowValue != ""; + } + } +} + + + +/** + * Provides functions for using the filter with jdito recordcontainers + * + * Do not instanciate this! + * + * @class + */ +function JditoFilterUtils () {} + +JditoFilterUtils.getFilterFields = function (pFilterJsonRootNode) +{ + let filterFields = []; + for(var filterChildNode in pFilterJsonRootNode) + { + var currentNode = pFilterJsonRootNode[filterChildNode]; + if(currentNode.type == "row") + { + let fieldName = currentNode.name; + filterFields.push(fieldName); + } + else + { + JditoFilterUtils.getFilterFields(filterChildNode); + } + } + return filterFields; +} + +/** + * Filters the given records manually. If you get the records using a sql query, you might consider using + * JditoFilterUtils.getSqlCondition instead for better performance. + * + * @param {Array} pColumns one dimensional array with all column names (only the columns with the idValue, displayValue columns should be null or ""), + * the order has to match the columns of the recordFields property in the recordcontainer + * @param {Array} pRecords two dimensional array with all records + * @param {String|Object} pFilter the value of vars.get($local.filter).filter + * @param {Object} [pCustomCheckFns] Object of custom functions that should be used to ckeck records. The key has to be the name of the fields you want to + * check. The provided function will be called with the arguments (recordValue, filterValue, operator, record) and should return a boolean (or something truthy or falsy). + * @param {Object} [pCheckFnThisArg] The object that should be the this-context when the custom check functions are called. This can be useful if you + * need some kind of storage for extra data you need in your function that you don't have to load for every record. + * + * @return {Array} the filtered records + */ +JditoFilterUtils.filterRecords = function (pColumns, pRecords, pFilter, pCustomCheckFns, pCheckFnThisArg) +{ + if (!pFilter) + return pRecords; + + var filter = new JditoFilterHelper(pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg); + + return pRecords.filter(function (row) + { + return this.checkRecord(row); + }, filter); +} + +/** + * builds an sql condition from the given filter + * + * @param {Object} pFilter the filter object + * @param {String} pTable the database table + * @param {String} [pTableAlias=null] the database table alias + * @param {Object} [pColumnOrFnMap=null] Custom mapping for the fields to the DB columns or functions that return a SqlCondition, this is necessary + * if the fields are from different tables. Structure has to be like this: + * { + * FIELD1 : "TABLE1.COLUMN1", + * FIELD2 : ["TABLE2", "COLUMN2", "TABLE2ALIAS"], //do it like this if the table has an alias + * FIELD3 : function (pValue, pOperator) //function if you need to build a special condition + * { + * var cond = new SqlCondition(); + * ... + * return cond; + * } + * } + * + * @example + * var condition = SqlCondition.begin(); + * if (vars.exists("$local.filter") && vars.get("$local.filter")) + * { + * var filter = vars.get("$local.filter"); + * if (filter.filter) + * condition.andSqlCondition((JditoFilterUtils.getSqlCondition(filter.filter, "AB_ATTRIBUTE"))); + * } + * var attributeSql = condition.buildSql("select AB_ATTRIBUTEID from AB_ATTRIBUTE"); + * + * @return {SqlCondition} the SqlCondition object + */ +JditoFilterUtils.getSqlCondition = function (pFilter, pTable, pTableAlias, pColumnOrFnMap) +{ + var condition = new SqlCondition(); + + if (!pFilter) + return condition; + if (!pColumnOrFnMap) + pColumnOrFnMap = {}; + + _addCondition.call(condition, pFilter, pFilter.operator); + + return condition; + + //recursive function (for compatibility with a condition tree) that + //builds the SqlCondition + function _addCondition (pCondition, pOperator) + { + if (pCondition.type == "row") + { + if (pCondition.name in pColumnOrFnMap) + pCondition.name = pColumnOrFnMap[pCondition.name]; + else if (pTable && pTableAlias) + pCondition.name = [pTable, pCondition.name, pTableAlias]; + else if (pTable) + pCondition.name = pTable + "." + pCondition.name; + + pCondition.value = (pCondition.key || pCondition.value); + + var condition; + if (typeof(pCondition.name) === "function") + { + condition = pCondition.name.call(null, pCondition.value, pCondition.operator); + if (pOperator == "AND") + this.andSqlCondition(condition); + else if (pOperator == "OR") + this.orSqlCondition(condition); + } + else + { + condition = _getCondition.call(pCondition, pCondition.value, pCondition.operator); + if (pOperator == "AND") + this.andPrepare(pCondition.name, pCondition.value, condition); + else if (pOperator == "OR") + this.orPrepare(pCondition.name, pCondition.value, condition); + } + } + else if (pCondition.type == "group") + { + let subCondition = new SqlCondition(); + let operator = pCondition.operator; + pCondition.childs.forEach(function (cond) + { + _addCondition.call(subCondition, cond, operator); + }); + if (pOperator == "AND") + this.andSqlCondition(subCondition); + else if (pOperator == "OR") + this.orSqlCondition(subCondition); + } + } + + //returns the condition depending on the operator and + //adds wildcards to the value if necessary + function _getCondition (pValue, pOperator) + { + switch (pOperator) + { + case "CONTAINS": + this.value = "%" + pValue + "%"; + return "# like ?"; + case "CONTAINSNOT": + this.value = "%" + pValue + "%"; + return "# not like ?"; + case "STARTSWITH": + this.value = pValue + "%"; + return "# like ?"; + case "ENDSWITH": + this.value = "%" + pValue; + return "# like ?"; + case "EQUAL": + return "# = ?"; + case "NOT_EQUAL": + return "# != ?"; + case "LESS": + return "# < ?"; + case "LESS_OR_EQUAL": + return "# <= ?"; + case "GREATER": + return "# > ?"; + case "GREATER_OR_EQUAL": + return "# >= ?"; + case "ISNULL": + return "# is null"; + case "ISNOTNULL": + return "# is not null"; + } + } +} + return JditoFilterUtils; //return only functions that should be public + })(); \ No newline at end of file