From 9871c1811b0d365d50008a28b36b361db08397cb Mon Sep 17 00:00:00 2001
From: "j.goderbauer" <j.goderbauer@adito.de>
Date: Thu, 29 Nov 2018 10:26:24 +0100
Subject: [PATCH] [Projekt: Entwicklung - Neon][TicketNr.: 1027750][JDito -
 libray Standard ist komplett definiert und wird in allen libs verwendet]

---
 process/Sql_lib/process.js  | 718 +++++++++---------------------------
 process/Util_lib/process.js |  32 --
 2 files changed, 168 insertions(+), 582 deletions(-)

diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index a69021b68b8..9cc2ce5f5d3 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -24,6 +24,7 @@ function SqlCondition(alias){
     this.cachedTypes = {};
     this.lastWasOr = false;
 }
+
 /**
  * append with SQL-and; no paranthesize of existing conditions is done
  * @param {String} cond the condition string which shall be appended
@@ -201,7 +202,8 @@ SqlCondition.prototype.build = function(alternativeCond){
  * @return {Array[][][]} Prepared condition with [condition, [[field1, type1], [field2, type2]]]
  */
 SqlCondition.prototype.buildSelect = function(beforeCondition, alternativeCond, afterCondition) {
-    if (afterCondition == undefined) { afterCondition = "" };
+    if (afterCondition == undefined)
+        afterCondition = "" 
     return [beforeCondition  + " " + this.toWhereString(alternativeCond) + " " + afterCondition, this.preparedValues];
 }
 
@@ -317,6 +319,7 @@ function SqlMaskingUtils(alias){
         }
     });
     this.dbType = null;
+    //provide the possibility to just set dbType (e.g. for testing) with no association to an alias
     Object.defineProperty(this, "dbType", {
         set: function(v){
             this._alias = null;
@@ -333,6 +336,31 @@ function SqlMaskingUtils(alias){
         this.alias = alias;
 }
 
+/**
+ * returns the concat symbol depending on database type
+ * @return {String} Concat Symbol
+ */
+SqlMaskingUtils.prototype.getConcatSymbol = function()
+{
+    var concatSymbol;
+    switch(Number(this.dbType)) {
+        case db.DBTYPE_SQLSERVER2000:
+            concatSymbol = " + ";
+            break;
+        case db.DBTYPE_MARIADB10:
+        case db.DBTYPE_MYSQL4:
+        case db.DBTYPE_ORACLE10_CLUSTER:
+        case db.DBTYPE_ORACLE10_THIN:
+        case db.DBTYPE_ORACLE10_OCI:
+        case db.DBTYPE_POSTGRESQL8:
+        case db.DBTYPE_DERBY10:
+        default:
+            concatSymbol = " || ";
+            break;
+    }
+    return concatSymbol;
+}
+
 /**
 *  returns the trim function depending on the database behin the given alias
 *  note that this function does not verifiy where the types of your expression are trimable or not
@@ -528,6 +556,33 @@ SqlMaskingUtils.prototype.castLob = function(field, targetLength) {
     return res;
 }
 
+/**
+ *  returns the function which determines the length of binary data
+ *
+ * @param {String} fieldName name of the checked field
+ *
+ * @return {String}
+ */
+SqlMaskingUtils.prototype.binDataLength = function(fieldName) {
+    var res;
+
+    switch(this.dbType) {
+        case db.DBTYPE_MARIADB10:
+        case db.DBTYPE_MYSQL4:
+        case db.DBTYPE_ORACLE10_CLUSTER:
+        case db.DBTYPE_ORACLE10_THIN:
+        case db.DBTYPE_ORACLE10_OCI:
+        case db.DBTYPE_POSTGRESQL8:
+        case db.DBTYPE_DERBY10:
+            res = "LENGTH(" + fieldName + ")";
+            break;
+        case db.DBTYPE_SQLSERVER2000:
+            res = "DATALENGTH(" + fieldName + ")";
+            break;
+    }
+    return res;
+}
+
 /**
     * masks the sql function substring
     *
@@ -585,7 +640,7 @@ SqlMaskingUtils.prototype.concat = function(fields, separatorCharacter, autoTrim
         return "''";
     else if (fields.length == 1)
         return fields[0];
-    concatSql = " || ";
+    concatSql = this.getConcatSymbol();
     isNotEmptyStrSql =  " != '' ";
     isNotNullSql = " is not null ";
     separatorSql = separatorCharacter == undefined ? " " : separatorCharacter;
@@ -611,7 +666,6 @@ SqlMaskingUtils.prototype.concat = function(fields, separatorCharacter, autoTrim
         case db.DBTYPE_SQLSERVER2000:
             //MS SQL Server supports "concat_ws" (and ignoring null values) from version SQL Server 2017 and newer:
             //https://docs.microsoft.com/de-de/sql/t-sql/functions/concat-ws-transact-sql?view=sql-server-2017
-            concatSql = " + ";
             break;
         case db.DBTYPE_DERBY10:
             break;
@@ -689,10 +743,10 @@ SqlUtils.getSingleColumnType = function(fieldOrTableName, columnName, alias) {
         } else if (fieldVarType != "object") {
             throw new TypeError(translate.text("${SQL_LIB_WRONG_FIELD_TYPE}"));
         }
-        
+
         if (fieldOrTableName.hasOwnProperty("length")) {
             if (fieldOrTableName.length == 2) {
-                
+
             } else {
                 throw new TypeError(translate.text("${SQL_LIB_WRONG_FIELD_TYPE}"))
             }
@@ -714,539 +768,25 @@ SqlUtils.getSingleColumnType = function(fieldOrTableName, columnName, alias) {
         alias = db.getCurrentAlias();
 
     return db.getColumnTypes(tableName, [columnName], alias)[0];
-}
-
-/**
- *Class containing utilities for SQL
- *@deprecated use SqlMaskingUtils
- *@todo: shift to newer objects or remove
- *@class
- */
-function LegacySqlUtils()
-{
-    var that = this;
-    /**
-    * builds a condition out of multiple conditions
-    *
-    * @param {Array} pArray req Array containing the conditions
-    * @param {String} pOperator req Operator that concatenates the conditions (AND/OR)
-    *
-    * @return {String} concatenated Condition
-    */
-    this.concatConditions = function(pArray, pOperator)
-    {
-        var resultCondition = "";
-
-        for(var i = 0; i < pArray.length; i++)
-        {
-            if(pArray[i] != null && pArray[i] != '')
-            {
-                if(resultCondition.length > 0)
-                    resultCondition += (" " + pOperator + " ");
-
-                resultCondition += pArray[i];
-            }
-        }
-
-        return resultCondition;
-    }
-    /**
-    * Checks if a new entry already exists
-    *
-    * @param {String} pTable req Databasetable(z.B. "comm")
-    * @param {Array} pColumns req colums, like sqlInsert
-    * @param {Array} pTypes req die datatypes, like sqlInsert
-    * @param {Array} pValues req values, like sqlInsert
-    * @param {Array} pExcludeFields opt columns, that should not be checked
-    * @param {String} pAlias opt Database alias
-    *
-    * @return {Integer}
-    */
-    this.isDuplicat = function(pTable, pColumns, pTypes, pValues, pExcludeFields, pAlias)
-    {
-        var col = new Array();
-        var typ = new Array();
-        var val = new Array();
-        var excludefields = ["DATE_NEW" ,"DATE_EDIT" ,"USER_NEW" ,"USER_EDIT", "KEYVALUE",  "KEYSORT", pTable.toUpperCase() + "ID"];
-
-        if(pExcludeFields != undefined) 
-            excludefields = excludefields.concat(pExcludeFields);
-        if(pAlias == undefined)  
-            pAlias = vars.getString("$sys.dbalias");
-
-        for(var i = 0; i < pColumns.length; i++)
-        {
-            if(!hasElement(excludefields, pColumns[i], true) && pValues[i] != "" && pTypes[i] != SQLTYPES.LONGVARCHAR && pTypes[i] != SQLTYPES.CLOB)
-            {
-                col.push(pColumns[i]);
-                typ.push(pTypes[i]);
-                val.push(pValues[i]);
-            }
-        }
-        var count = db.getRowCount(pTable, col, typ, val, pAlias);
-        return count;
-    }
-
-    /**
-    * returns the day of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.dayFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'dd')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "DAY(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (DAY from " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the month of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.monthFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'MM')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "MONTH(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (MONTH FROM " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the year of a date
-    *
-    * @param {Datetime} pDate req the date
-    * @param {String} pAlias req database alias
-    *
-    * @return {String}
-    */
-    this.yearFromDate = function(pDate, pAlias)
-    {
-        var usedAlias = pAlias;
-        if(pAlias == undefined) 
-            usedAlias = vars.getString("$sys.dbalias");
-
-        var dbAlias = db.getDatabaseType(usedAlias);
-        var string = "";
-
-        switch(Number(dbAlias))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-                string = "to_char(" + pDate + ",'yyyy')";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_SQLSERVER2000:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                string = "YEAR(" + pDate + ")";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                string = "EXTRACT (YEAR FROM " + pDate + ")";
-                break;
-        }
-        return string;
-    }
-    /**
-    * returns the function for current date depending on database
-    *
-    * @return {String} expression
-    */
-    this.currentDate = function()
-    {
-        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
-        var expression = "";
-
-        switch (Number(dbtype))
-        {
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_DERBY10:
-                expression = "CURRENT_DATE";
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                expression = "GETDATE()";
-                break;
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                expression = "NOW()";
-                break;
-        }
-        return expression;
-    }
-    /**
-    * returns the current search string incl placeholders
-    *
-    * @param {String} pfield req the search field
-    * @param {String} pfind req the search string
-    * @param {String} pIgnoreCase opt (true/false)
-    * @param {String} pPlaceHolder opt (Platzhalter config)
-    *
-    * @return {String}
-    */
-    this.getPlacerholderCondition = function( pfield, pfind, pIgnoreCase, pPlaceHolder )
-    {
-        var user = tools.getCurrentUser();
-        var IgCa;
-        var PlHo;
-
-        //wenn optoinal IgnoreCase und PlaceHolder vorhanden, dann diese verwenden
-        if(pIgnoreCase != undefined)
-            IgCa = pIgnoreCase;
-        else
-            IgCa = user[tools.PARAMS][tools.SELECTION_IGNORECASE];
-
-        if(pPlaceHolder != undefined)
-            PlHo = pPlaceHolder;
-        else
-            PlHo = user[tools.PARAMS][tools.SELECTION_PLACEHOLDER];
-
-        if ( pfind )
-        {
-            pfind = pfind.replace( new RegExp("\\'", "g"), "''");
-            pfind = pfind.replace( new RegExp("\\*", "g"), "%");
-            var ic = (IgCa == "true" ? "UPPER" : "");
-            var cond = "";
-            switch( PlHo )
-            {
-                case "1":
-                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "%')";
-                    break;
-                case "2":
-                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "')";
-                    break;
-                case "3":
-                    cond = ic + "(" + pfield + ") like " + ic + "('%" + pfind + "%')";
-                    break;
-                case "4":
-                    cond = ic + "(" + pfield + ") like " + ic + "('" + pfind + "')";
-                    break;
-                default:
-                    cond = ic + "(" + pfield + ") = " + ic + "('" + pfind + "')";
-                    break;
-            }
-        }
-        return cond;
-    }
-    /**
-    * returns SQLSystax for a date.
-    *
-    * @param {String} pColumn req Column name
-    * @param {String} pAlias opt Database alias
-    * @param {Boolean} pWithTime opt if true, then add time hh:mm:ss
-    * @param {String} pFormat opt type of the format, e.g. yyyy-MM-dd; possible placeholers are: -dd -MM -yyyy
-    *
-    *@return {String} sqlstr, fully functional select for sql for different types of databases
-    */
-    this.getSqlFormattedDate = function(pColumn, pAlias, pWithTime, pFormat)
-    {
-        if(pAlias == undefined)  
-            pAlias = vars.getString("$sys.dbalias");
-
-        var pDatabaseType = db.getDatabaseType(pAlias);
-
-        if (pFormat == undefined)
-            pFormat = translate.text("yyyy-MM-dd");
-
-        var str = "";
-
-        switch(Number(pDatabaseType))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                day = "right('0' + cast(day(" + pColumn + ") as varchar(2)) , 2)";
-                month = "right('0' + cast(month(" + pColumn + ") as varchar(2)) , 2)";
-                year = "cast(year(" + pColumn + ") as char(4))";
-                time = pWithTime == true? that.concat(["' '","cast(cast(" + pColumn + " as time) as char(8))"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_POSTGRESQL8:
-                day = "extract(day from " + pColumn + ")";
-                month = "extract(month from " + pColumn + ")";
-                year = "extract(year from " + pColumn + ")";
-                time = pWithTime == true? that.concat(["' '","extract(time from" + pColumn + ")"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_DERBY10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_MARIADB10:
-                // concat will try to have a leading blank space if the number is => 10. This is why we had to use substr.
-                day = that.substring(that.concat(["case when day(" + pColumn + ") <= 9 then '00' else '0' end "
-                    , " trim(cast(day(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
-                month = that.substring(that.concat(["case when month(" + pColumn + ") <= 9 then '00' else '0' end "
-                    , "trim(cast(month(" + pColumn + ") as char(2)))"], "", pAlias), 2, 2, pAlias);
-                year = "trim(cast(year(" + pColumn + ") as char(4)))";
-                time = pWithTime == true? that.concat(["cast(' ' as char(1))", "trim(cast(time(" + pColumn + ") as char(8)))"], "", pAlias) : "";
-                break;
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_ORACLE10_THIN:
-
-                day = "to_char(" + pColumn + ", 'dd') ";
-                month = "to_char(" + pColumn + ", 'MM') ";
-                year = "to_char(" + pColumn + ", 'yyyy') ";
-                time = pWithTime == true ? " to_char(" + pColumn + ", ' hh24:mi:ss')" : "";
-                break;
-            default:
-                str = "cast(" + pColumn + " as varchar (10))";
-                return str;
-                break;
-        }
-
-        var re = /(dd)|(MM)|(yyyy)/g        // Regex to check the date
-        var matchResult;
-        var endOfLastMatch = 0;
-        var res = [];
-
-        while ((matchResult = re.exec(pFormat)) !== null) 
-        {
-            if( endOfLastMatch != matchResult.index)
-            {
-                res.push("'" + db.quote(pFormat.substring(endOfLastMatch, matchResult.index), pAlias) + "'");     // making sure we get the correct amount of quotations
-            }
-            switch(matchResult[0])
-            {
-                case "dd":
-                    res.push(day);
-                    break;
-                case "MM":
-                    res.push(month);
-                    break;
-                case "yyyy":
-                    res.push(year);
-                    break;
-            }
-            endOfLastMatch = re.lastIndex;
-        }
-        // making sure we get the correct amount of quotations
-        // allows us to add custom strings behind the format which will be shown in the output
-        // e.g. "yyyy-MM-dd 00:00", "date: MM/dd/yyyy"
-        res.push("'" + db.quote(pFormat.slice(endOfLastMatch), pAlias) + "'");
-
-        if(time != "")
-            res.push(time);
-
-        str = concat(res, "", pAlias);
-
-        return str;
-    }
-    /**
-    * returns a SQL operator depending on an integer value, i.e. $local.operator
-    *
-    * @param {int} pVal
-    *
-    * @return {string}
-    */
-    this.getSQLOperator = function(pVal)
-    {
-        var retval = "";
-        switch(Number(pVal))
-        {
-            case 1:
-                retval = "=";
-                break; //equals
-            case 2:
-                retval = "<>";
-                break; //not equal
-            case 3:
-                retval = ">";
-                break; //greater
-            case 4:
-                retval = "<";
-                break; //lesser
-            case 5:
-                retval = "<=";
-                break; //lesser or equal
-            case 6:
-                retval = ">=";
-                break; //greater or equal
-            case 7:
-                retval = "like";
-                break; //contains
-            case 8:
-                retval = "not like";
-                break; //contains not
-            case 9:
-                retval = "";
-                break;
-            case 10:
-                retval = "";
-                break;
-            case 11:
-                retval = "is not null";
-                break;
-            case 12:
-                retval = "is null";
-                break;
-        }
-        return retval;
-    }
-    /**
-    *  returns the function which determines the length of binary data, depending on db type
-    *
-    * @param {String} pField name of the checked field
-    *
-    * @return {String}
-    */
-    this.binDataLength = function(pField)
-    {
-        var dbtype = db.getDatabaseType(vars.getString("$sys.dbalias"));
-        var length;
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_MARIADB10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_POSTGRESQL8:
-            case db.DBTYPE_DERBY10:
-                length = "LENGTH("+pField+")";
-                break;
-            case db.DBTYPE_SQLSERVER2000:
-                length = "DATALENGTH("+pField+")";
-                break;
-        }
-        return length;
-    }
-
-    /**
-    * returns the concat symbol depending on database type
-    *
-    * @param {String} pAlias opt database alias
-    *
-    * @return {String} Concat Symbol
-    */
-    this.getConcatSymbol = function(pAlias)
-    {
-        if(pAlias == undefined || pAlias == "")  
-            pAlias =  vars.getString("$sys.dbalias");
-
-        var dbtype = db.getDatabaseType(pAlias);
-        var concatSymbol = " ";
-
-        switch(Number(dbtype))
-        {
-            case db.DBTYPE_SQLSERVER2000:
-                concatSymbol = " + ";
-                break;
-            case db.DBTYPE_MARIADB10:
-            case db.DBTYPE_MYSQL4:
-            case db.DBTYPE_ORACLE10_CLUSTER:
-            case db.DBTYPE_ORACLE10_THIN:
-            case db.DBTYPE_ORACLE10_OCI:
-            case db.DBTYPE_POSTGRESQL8:
-            case db.DBTYPE_DERBY10:
-            default:
-                concatSymbol = " || ";
-                break;
-        }
-
-        return concatSymbol;
-    }
-    /**
-     * Builds a SQL IN condition, while accounting for the 1000 elements maximum
-     * Single conditions are concatenated with OR, which can be devastating for performance!
-     *
-     * @param {String} pFieldname req name of the field with table alias
-     *                                z.B ORGREL.RELATIONID
-     * @param {String[]|String[][]} pData req Data as ID Array
-     * @param {String} pQuoteSymbol opt symbol for quoting values,
-     *                                  Strings i.e.: ' default is no symbol
-     *
-     * @return {String} SQL condition: where VALS in (1,2,3)
-     */
-    this.getSqlInStatement = function(pFieldname, pData, pQuoteSymbol)
-    {
-        if (pData.length == 0)
-            return " 1 = 2 ";
-
-        var res = "";
-        var qs = pQuoteSymbol || "";
-
-        var MAX_COUNT = 1000;
-        //pData.length -1 um für den Fall, dass MAX_COUNT == pData.length ist trotzdem nur einen Aufruf
-        //zu machen
-        var count = ((pData.length -1) / MAX_COUNT) >> 0;//aus kommazahl eine ganzzahl machen
-        //<= verwenden, da bei einer Länge von "126" der Vorgang einmal ausgeführt werden soll
-        for (var i = 0; i <= count; i++)
-        {
-            if (i > 0)
-                res += "or ";
-
-            res += pFieldname + " in (" + qs + pData.slice(i * MAX_COUNT, i * MAX_COUNT + MAX_COUNT)
-            .join(qs + ", " + qs) + qs + ") ";
-        }
-
-        //wenn mehrere Zeilen mit "or" verknüpft wurden nochmal klammern
-        if (count > 0)
-            res = "(" + res + ")";
-
-        return res;
-    }
+};
 
+//scope for internal functions;
+//it's extremly important that the semicolon of the function expression above is correctly set because otherwise the function is called immediately
+(function(){
     /**
     * calls a given function for N blocks of sql-data as long as records are available or the paging-process is manually canceled
     *
-    * @param {Object|String} pSql req sql statement that shall be executed
+    * @param {Object|String} sqlStatement the sql statement that shall be executed
     *                                 String: SQL-query in a simple text form
     *                                 Object: prepared-sql-query: [sqlStr, [[value1, type1], [valueN, typeN]]]
-    * @param {Number} pBlockSize req Amount of records that shall be read per block. (you need to specify an ORDER BY in your SQL-query)
+    * @param {Number} blockSize Amount of records that shall be read per block. (you need to specify an ORDER BY in your SQL-query)
     *                                "0" <=> all records
-    * @param {Object (function)} pCallback req a callback-function that is called for every block and has the following params:
+    * @param {Object (function)} callbackFn a callback-function that is called for every block and has the following params:
     *                                            myCallback(myDataBlockAs2Darray, myLoopCountThatStartsWith1)
     *                                          If "false" is returned sqlPageData will abort the paging process and return false
-    * @param {String} pDbAlias opt Database-Aliasname, where the SQL-Statement shall be executed; default is the current dbalias
-    * @param {Number} pTimeout opt Timeout in milliseconds; When it's reached the SQL-Statement will abort; default is in PREFERENCES configured
-    * @param {Number} pStartOffset opt Position where to begin with  the data-reading-process; default is 0
+    * @param {String} [dbAlias=the current alias] Database-Aliasname, where the SQL-Statement shall be executed; default is the current dbalias
+    * @param {Number} [timeout=configured dbTimeout in Preferences] Timeout in milliseconds; When it's reached the SQL-Statement will abort; default is in PREFERENCES configured
+    * @param {Number} [startOffset=0] Position where to begin with  the data-reading-process; default is 0
     *
     *
     * @return {bool} returns whether the function read all available data or not:
@@ -1284,36 +824,114 @@ function LegacySqlUtils()
     * logging.show(letValues);//contains orgnames
     * logging.show(varValues);//contains orgnames
     */
-    this.sqlPageData = function(pSql, pBlockSize, pCallback, pDbAlias, pTimeout, pStartOffset)
-    {
-        if (pDbAlias == undefined)
-            pDbAlias = db.getCurrentAlias();
+    SqlUtils.pageTableData = function(sqlStatement, blockSize, callbackFn, dbAlias, timeout, startOffset) {
+        return _pageData(null, sqlStatement, blockSize, callbackFn, dbAlias, timeout, startOffset);
+    };
 
-        if (pStartOffset == undefined)
-            pStartOffset = 0;
-
-        let count = 0;
-        while (pStartOffset > -1)
-        {
-            let data;
-            if (pTimeout == undefined)
-                data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize);
-            else
-                data = db.tablePage(pSql, pDbAlias, pStartOffset, pBlockSize, pTimeout);
+    /**
+    * calls a given function for N blocks of sql-data as long as records are available or the paging-process is manually canceled
+    *
+    * @param {Object|String} sqlStatement the sql statement that shall be executed
+    *                                 String: SQL-query in a simple text form
+    *                                 Object: prepared-sql-query: [sqlStr, [[value1, type1], [valueN, typeN]]]
+    * @param {Number} blockSize Amount of records that shall be read per block. (you need to specify an ORDER BY in your SQL-query)
+    *                                "0" <=> all records
+    * @param {Object (function)} callbackFn a callback-function that is called for every block and has the following params:
+    *                                            myCallback(myColumnDataBlockAsArray, myLoopCountThatStartsWith1)
+    *                                          If "false" is returned sqlPageData will abort the paging process and return false
+    * @param {String} [dbAlias=the current alias] Database-Aliasname, where the SQL-Statement shall be executed; default is the current dbalias
+    * @param {Number} [timeout=configured dbTimeout in Preferences] Timeout in milliseconds; When it's reached the SQL-Statement will abort; default is in PREFERENCES configured
+    * @param {Number} [startOffset=0] Position where to begin with  the data-reading-process; default is 0
+    *
+    *
+    * @return {bool} returns whether the function read all available data or not:
+    *                        false if the callback-function returned false, otherwise true
+    *
+    * @example
+    * similar to sqlTablePageData -> take a look at the example there
+    */
+    SqlUtils.pageColumnData = function(sqlStatement, blockSize, callbackFn, dbAlias, timeout, startOffset) {
+        return _pageData(db.COLUMN, sqlStatement, blockSize, callbackFn, dbAlias, timeout, startOffset);
+    };
+    
+    //internal function for paging through data; for description take a look at sqlArrayPageData
+    function _pageData(sqlType ,sqlStatement, blockSize, callbackFn, dbAlias, timeout, startOffset){
+        if (dbAlias == undefined)
+            dbAlias = db.getCurrentAlias();
+        if (startOffset == undefined)
+            startOffset = 0;
+
+        var count = 0;
+        while (startOffset > -1) {
+            var data;
+            if (sqlType == null) {
+                if (timeout == undefined)
+                    data = db.tablePage(sqlStatement, dbAlias, startOffset, blockSize);
+                else
+                    data = db.tablePage(sqlStatement, dbAlias, startOffset, blockSize, timeout);
+            }
+            else {
+                if (timeout == undefined)
+                    data = db.arrayPage(sqlType, sqlStatement, dbAlias, startOffset, blockSize);
+                else
+                    data = db.arrayPage(sqlType, sqlStatement, dbAlias, startOffset, blockSize, timeout);
+            }
 
-            pStartOffset += pBlockSize;
+            startOffset += blockSize;
 
-            //this happens when all-records % pBlockSize == 0
+            //this happens when all-records % blockSize == 0
             //we do not want to call the callback-fn
             if (data.length == 0)
                 return true;
-            else if (data.length < pBlockSize || pBlockSize == 0)//blocksize 0 is everything
-                pStartOffset = -1;//call callback the last time
+            else if (data.length < blockSize || blockSize == 0)//blocksize 0 is everything
+                startOffset = -1;//call callback the last time
 
-            if (pCallback.call(this, data, ++count) === false)
+            if (callbackFn.call(this, data, ++count) === false)
                 return false;//callback can return false to manually stop the paging-process
-
         }
         return true;
     }
+})();
+
+
+
+/**
+     * Builds a SQL IN condition, while accounting for the 1000 elements maximum
+     * Single conditions are concatenated with OR, which can be devastating for performance!
+     *
+     * @param {String} pFieldname req name of the field with table alias
+     *                                z.B ORGREL.RELATIONID
+     * @param {String[]|String[][]} pData req Data as ID Array
+     * @param {String} pQuoteSymbol opt symbol for quoting values,
+     *                                  Strings i.e.: ' default is no symbol
+     *
+     * @return {String} SQL condition: where VALS in (1,2,3)
+     */
+this.getSqlInStatement = function(pFieldname, pData, pQuoteSymbol)
+{
+    if (pData.length == 0)
+        return " 1 = 2 ";
+
+    var res = "";
+    var qs = pQuoteSymbol || "";
+
+    var MAX_COUNT = 1000;
+    //pData.length -1 um für den Fall, dass MAX_COUNT == pData.length ist trotzdem nur einen Aufruf
+    //zu machen
+    var count = ((pData.length -1) / MAX_COUNT) >> 0;//aus kommazahl eine ganzzahl machen
+    //<= verwenden, da bei einer Länge von "126" der Vorgang einmal ausgeführt werden soll
+    for (var i = 0; i <= count; i++)
+    {
+        if (i > 0)
+            res += "or ";
+
+        res += pFieldname + " in (" + qs + pData.slice(i * MAX_COUNT, i * MAX_COUNT + MAX_COUNT)
+        .join(qs + ", " + qs) + qs + ") ";
+    }
+
+    //wenn mehrere Zeilen mit "or" verknüpft wurden nochmal klammern
+    if (count > 0)
+        res = "(" + res + ")";
+
+    return res;
 }
diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js
index ace960b642d..51cbe5d0afd 100644
--- a/process/Util_lib/process.js
+++ b/process/Util_lib/process.js
@@ -452,35 +452,3 @@ function JDitoUtils()
         return dbAliases;
     }
 }
-
-
-/**
- * Class containing String utility functions
- * @class
- * @deprecated
- * @todo: remove this funciton
- */
-function StringUtils(){}
-{
-    
-    /**
-    * uses the right translate method, depending on the parameters
-    *
-    * @param {String} pText string to be translated
-    * @param {String} pLocale locale for translating
-    *
-    * @return {String}
-    *
-    * 
-    */
-    this.translateStr = function( pText, pLocale )
-    {
-        if ( pLocale == undefined )   
-            return translate.text(pText);
-        else 
-            return translate.text(pText, pLocale)
-    }
-    
-
-}
-
-- 
GitLab