com.sap.cds.jdbc.generic.GenericFunctionMapper Maven / Gradle / Ivy
/************************************************************************
* © 2020-2023 SAP SE or an SAP affiliate company. All rights reserved. *
************************************************************************/
package com.sap.cds.jdbc.generic;
import static java.util.stream.Collectors.joining;
import java.text.MessageFormat;
import java.util.List;
import java.util.Locale;
import com.sap.cds.impl.parser.builder.ExpressionBuilder;
import com.sap.cds.impl.parser.token.CqnPlainImpl;
import com.sap.cds.jdbc.spi.FunctionMapper;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Predicate;
import com.sap.cds.ql.cqn.CqnPlain;
import com.sap.cds.ql.cqn.CqnValue;
public class GenericFunctionMapper implements FunctionMapper {
private static final String TOLOWER = "tolower";
protected static final CqnPlain LIKE = CqnPlainImpl.plain("LIKE");
protected static final CqnPlain ILIKE = CqnPlainImpl.plain("ILIKE");
protected static final CqnPlain ESCAPE = CqnPlainImpl.plain("ESCAPE");
@Override
public String toSql(String cqnFunc, List args) {
String func = cqnFunc.toLowerCase(Locale.US);
switch (func) { // NOSONAR
case "countdistinct":
return "COUNT(DISTINCT " + args.get(0) + ")";
case TOLOWER:
return genericFuncToSql("LOWER", args);
case "toupper":
return genericFuncToSql("UPPER", args);
case "current_date":
return "current_date";
case "current_time":
return "current_time";
case "current_timestamp":
return "current_timestamp";
case "singlevalue":
String col = args.get(0);
return MessageFormat.format("(case when min({0}) = max({0}) then min ({0}) end)", col);
case "count":
if (args.isEmpty()) {
return "COUNT(*)";
}
break;
case "matchespattern":
return genericFuncToSql("LIKE_REGEX", args);
}
return genericFuncToSql(cqnFunc, args);
}
protected String genericFuncToSql(String func, List args) {
return func.toUpperCase(Locale.US) + args.stream().collect(joining(", ", "(", ")"));
}
@Override
public Predicate like(CqnValue value, CqnValue pattern, String esc, boolean caseInsensitive) {
if (caseInsensitive) {
value = CQL.func(TOLOWER, value);
pattern = CQL.func(TOLOWER, pattern);
}
return ExpressionBuilder.create(value, LIKE, pattern, ESCAPE, CQL.constant(esc)).predicate();
}
protected Predicate ilike(CqnValue value, CqnValue pattern, String esc, boolean caseInsensitive) {
CqnPlain operator = caseInsensitive ? ILIKE : LIKE;
return ExpressionBuilder.create(value, operator, pattern, ESCAPE, CQL.constant(esc)).predicate();
}
}