合并列
@Slf4j
public class FieldMergeNodeHandler extends BaseOperatorNodeHandler {
/**
* 列合并函数
*/
private static final String TO_STRING = "toString";
/**
* 合并列 生成的列类型为String
*/
private static final String TYPE_STRING = "String";
public static final int EXPRESSIONS_SIZE_TWO = 2;
public static final int EXPRESSIONS_SIZE_ONE = 1;
public FieldMergeNodeHandler(DdlMutableGraphContext mutableGraph, DdlNode node) {
super(mutableGraph, node);
}
/**
* 生成连接表达式 比如 toString(date)||toString(age)||toString(name)
*
* @param expressions 表达式
* @return Concat
*/
private Concat concat(List<Expression> expressions) {
if (expressions.size() == EXPRESSIONS_SIZE_ONE) {
Concat c = new Concat();
c.setLeftExpression(expressions.get(0));
StringValue stringValue = new StringValue("");
c.setRightExpression(stringValue);
return c;
} else if (expressions.size() == EXPRESSIONS_SIZE_TWO) {
Concat c = new Concat();
c.setLeftExpression(expressions.get(0));
c.setRightExpression(expressions.get(1));
return c;
} else if (expressions.size() > EXPRESSIONS_SIZE_TWO) {
Concat c = new Concat();
c.setLeftExpression(concat(expressions.subList(0, expressions.size() - 1)));
c.setRightExpression(expressions.get(expressions.size() - 1));
return c;
}
return null;
}
@Override
public PlainSelect sql() {
PlainSelect preSql = prePlainSelect();
List<SelectItem> selectItems = preSql.getSelectItems();
List<DdlNode.Field> fields = currentNode().getOperators().getFields();
if (!CollectionUtils.isEmpty(fields)) {
//是否删除原列
DdlNode.Field field = fields.get(0);
String columns = this.checkColumns(field);
String[] split = columns.split(SqlConstants.COMMA);
List<DdlColumn> columns1 = this.columns();
List<Function> functions = Arrays.stream(split).map(t -> {
Function function = new Function();
function.setName(TO_STRING);
ExpressionList expressionList = new ExpressionList();
String type = DdlConstants.STRING;
for (DdlColumn column : columns1) {
String name = column.getName();
if (name.equals(t)) {
type = column.getType();
break;
}
}
String columnName;
if (type.contains(DdlConstants.STRING)) {
columnName = "IF(%s is not null,%s,'-')";
} else if (type.contains(DdlConstants.INT)) {
columnName = "IF(%s is not null,%s,0)";
} else {
columnName = "IF(%s is not null,%s,NOW())";
}
t = String.format(columnName, t, t);
Column column = new Column(t);
expressionList.addExpressions(column);
function.setParameters(expressionList);
return function;
}).collect(Collectors.toList());
String delimiter = field.getDelimiter();
if (delimiter.contains("\\")) {
delimiter = delimiter.replace("\\", "\\\\");
}
StringValue stringValue = new StringValue(delimiter);
List<Expression> expressions = Lists.newArrayList();
for (int i = 0; i < functions.size(); i++) {
if (i != 0) {
expressions.add(stringValue);
}
expressions.add(functions.get(i));
}
Concat concat = concat(expressions);
SelectExpressionItem selectExpressionItem = new SelectExpressionItem();
selectExpressionItem.setExpression(concat);
selectExpressionItem.setAlias(new Alias(field.getName()));
selectItems.add(selectExpressionItem);
}
preSql.setSelectItems(selectItems);
log(preSql.toString());
return preSql;
}
@Override
public List<DdlColumn> columns() {
super.checkNode();
final List<DdlColumn> ddlColumns = preColumns();
List<DdlNode.Field> fields = currentNode().getOperators().getFields();
DdlNode.Field field = fields.get(0);
String columns = this.checkColumns(field);
List<DdlColumn> collect = fields.stream().map(t -> DdlColumn.builder().name(t.getName())
.type(TYPE_STRING).build()).collect(Collectors.toList());
ddlColumns.addAll(collect);
String[] split = columns.split(SqlConstants.COMMA);
//是否删除原列
Boolean delOriginalColumn = field.getDelOriginalColumn();
return ddlColumns.stream().
filter(new FilterColumnPredicate<>(t -> delOriginalColumn && Lists.newArrayList(split).contains(t)))
.collect(Collectors.toList());
}
private String checkColumns(DdlNode.Field field) {
String columns = field.getColumns();
String name = field.getName();
if (StringUtils.isBlank(columns)) {
throw new DdlException("请选择要合并的列");
}
if (StringUtils.isBlank(name)) {
throw new DdlException("请输入新的列名称");
}
return columns;
}
}