Skip to content
Snippets Groups Projects
Commit 0f5fdda6 authored by Sebastian Listl's avatar Sebastian Listl :speech_balloon:
Browse files

#1067300 SqlMaskingUtils concat fixed for oracle db

parent 07fb72b3
No related branches found
No related tags found
No related merge requests found
......@@ -3099,12 +3099,12 @@ function SqlMaskingUtils(alias) {
* returns the concat symbol depending on database type
* @return {String} Concat Symbol
*/
SqlMaskingUtils.prototype.getConcatSymbol = function() {
var concatSymbol;
switch(Number(this.dbType)) {
SqlMaskingUtils.prototype.getConcatSymbol = function()
{
switch(Number(this.dbType))
{
case db.DBTYPE_SQLSERVER2000:
concatSymbol = " + ";
break;
return " + ";
case db.DBTYPE_MARIADB10:
case db.DBTYPE_MYSQL4:
case db.DBTYPE_ORACLE10_CLUSTER:
......@@ -3113,10 +3113,8 @@ SqlMaskingUtils.prototype.getConcatSymbol = function() {
case db.DBTYPE_POSTGRESQL8:
case db.DBTYPE_DERBY10:
default:
concatSymbol = " || ";
break;
return " || ";
}
return concatSymbol;
}
/**
......@@ -3131,18 +3129,11 @@ SqlMaskingUtils.prototype.getConcatSymbol = function() {
* @return {String} <p>
* Returns the trimmed string.<br>
*/
SqlMaskingUtils.prototype.trim = function(pField) {
var dbType, resultStr;
dbType = this.dbType;
switch(dbType) {
case db.DBTYPE_SQLSERVER2000:
resultStr = "ltrim(rtrim(" + pField + "))";
break;
default:
resultStr = "trim(" + pField + ")"
break;
}
return resultStr;
SqlMaskingUtils.prototype.trim = function(pField)
{
if (this.dbType == db.DBTYPE_SQLSERVER2000)
return "ltrim(rtrim(" + pField + "))";
return "trim(" + pField + ")";
}
/**
......@@ -3267,10 +3258,10 @@ SqlMaskingUtils.prototype.cast = function(field, targetDatatype, targetLength) {
switch(targetDatatype)
{
case SQLTYPES.VARCHAR:
datatype = "varchar2";
sqlDataType = "varchar2";
break;
case SQLTYPES.INTEGER:
datatype = "number";
sqlDataType = "number";
targetLength = "10"
break;
case SQLTYPES.CHAR:
......@@ -3417,41 +3408,41 @@ SqlMaskingUtils.prototype.substring = function(field, start, length) {
* if a sql field is empty no separator will be added
* note that this function will often create a lot of sql-code
*
* @param {Array} fields req fields (or expressions) that should be concatenated
* @param {String} [separatorCharacter=space-character] character for separating the fields; warning: the character will not be quoted
* @param {String} [autoTrimFields=true] autoTrimFields if true the expressions are always trimmed, false no change will be applied
* @param {Array} pFields fields (or expressions) that should be concatenated
* @param {String} [pSeparator=space-character] character for separating the fields
* @param {String} [pAutoTrimFields=true] autoTrimFields if true the expressions are always trimmed, false no change will be applied
*
* @return {String} part of SQL-querey
*/
SqlMaskingUtils.prototype.concat = function(fields, separatorCharacter, autoTrimFields) {
var concatSql, retSql, isNotEmptyStrSql, isNotNullSql, separatorSql, _isNotEmpty, _trimIfAutoTrimEnabled;
if (fields.length == 0)
SqlMaskingUtils.prototype.concat = function(pFields, pSeparator, pAutoTrimFields)
{
if (pFields.length === 0)
return "''";
else if (fields.length == 1)
return fields[0];
concatSql = this.getConcatSymbol();
isNotEmptyStrSql = " != '' ";
isNotNullSql = " is not null ";
separatorSql = separatorCharacter == undefined ? " " : separatorCharacter;
retSql = "";
if (autoTrimFields == undefined)
autoTrimFields = true;
if (pFields.length === 1)
return pFields[0];
if (pAutoTrimFields == undefined)
pAutoTrimFields = true;
if (pSeparator === null || pSeparator === undefined)
pSeparator = "' '";
else if (pSeparator)
pSeparator = "'" + db.quote(pSeparator, this.alias) + "'";
var doEmptyStringCheck = true;
switch(this.dbType)
switch (this.dbType)
{
case db.DBTYPE_MYSQL4:
case db.DBTYPE_MARIADB10:
case db.DBTYPE_POSTGRESQL8:
retSql = " concat_ws( '" + separatorSql + "'";
for (let i = 0; i < fields.length; i++) {
retSql += ", " + fields[i];
}
return retSql + ") ";
break;
if (pAutoTrimFields)
pFields = pFields.map(this.trim, this);
return " concat_ws( " + pSeparator + ", " + pFields.join(", ") + ")";
case db.DBTYPE_ORACLE10_CLUSTER:
case db.DBTYPE_ORACLE10_THIN:
case db.DBTYPE_ORACLE10_OCI:
isNotEmptyStrSql = null; //empty strings are changed to DB-null-values internally in oracle; by specifing JS-null we disable this check
doEmptyStringCheck = false; //empty strings are changed to DB-null-values internally in oracle; by specifing JS-null we disable this check
break;
case db.DBTYPE_SQLSERVER2000:
//MS SQL Server supports "concat_ws" (and ignoring null values) from version SQL Server 2017 and newer:
......@@ -3462,33 +3453,47 @@ SqlMaskingUtils.prototype.concat = function(fields, separatorCharacter, autoTrim
default:
throw new Error(translate.withArguments("${SQL_LIB_UNSUPPORTED_DBTYPE} function: %0", ["SqlMaskingUtils.prototype.concat"]));
}
separatorSql = concatSql + "'" + separatorSql + "'";
_trimIfAutoTrimEnabled = function(f){
if (autoTrimFields)
return this.trim(f);
var concatCharacter = this.getConcatSymbol();
var concatSql = "";
for (let i = 0; i < pFields.length; i++)
{
let field = pFields[i];
let isLast = i + 1 === pFields.length;
if (!_isFixedValue(field))
concatSql += (pAutoTrimFields ? this.trim(this.isNull(field)) : this.isNull(field));
else
return f;
}
_trimIfAutoTrimEnabled = _trimIfAutoTrimEnabled.bind(this);
_isNotEmpty = function(f){
return _trimIfAutoTrimEnabled(f) + isNotEmptyStrSql + " and " + f + isNotNullSql;
concatSql += (pAutoTrimFields ? "'" + field.slice(1, -1).trim() + "'" : field);
if (!isLast)
{
concatSql += concatCharacter;
let nextField = pFields[i+1];
if (pSeparator && _isFixedValue(nextField))
{
if (nextField.slice(1, -1).trim())
concatSql += pSeparator + concatCharacter;
}
else if (pSeparator)
{
let nextFieldTrimmed = pAutoTrimFields ? this.trim(nextField) : nextField;
let nextNotNullCondition = nextField + " is not null ";
if (doEmptyStringCheck || pAutoTrimFields)
nextNotNullCondition += " and " + nextFieldTrimmed + " != '' ";
concatSql += "case when " + nextNotNullCondition + " then " + pSeparator + " else '' end " + concatCharacter;
}
}
}
_isNotEmpty = _isNotEmpty.bind(this);
for (let i = 0; i < fields.length; i++) {
if (retSql != "")
retSql += concatSql;
retSql += "case when " + _isNotEmpty(fields[i]) + " then ";
if ( i < fields.length - 1 ) //Prüfen, ob ein nachfolgender Wert kommt, sonst braucht man keinen Separator
retSql += " case when " + _isNotEmpty(fields[i + 1]) + " then " + _trimIfAutoTrimEnabled(fields[i]) + separatorSql + " else " + _trimIfAutoTrimEnabled(fields[i]) + " end ";
else
retSql += _trimIfAutoTrimEnabled(fields[i]);
//this blank is used just as in the old concat function which means this concat function has the same (wrong) behaviour
//TODO: find way to fix the case when separator is not a whitepsace (e.g. space)
//this concat-function does not work properly if you concat [<<value>>, <<null>>, <<value>>] by comma
retSql += " else ' ' end ";
return concatSql;
function _isFixedValue (pSqlField)
{
return pSqlField.startsWith("'") && pSqlField.endsWith("'") && !pSqlField.slice(1, -1).includes("'");
}
return retSql;
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment