org.babyfish.jimmer.sql.ast.impl.CoalesceBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-sql Show documentation
Show all versions of jimmer-sql Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.sql.ast.impl;
import org.babyfish.jimmer.sql.ast.ComparableExpression;
import org.babyfish.jimmer.sql.ast.Expression;
import org.babyfish.jimmer.sql.ast.NumericExpression;
import org.babyfish.jimmer.sql.ast.StringExpression;
import org.babyfish.jimmer.sql.ast.impl.render.AbstractSqlBuilder;
import org.babyfish.jimmer.sql.runtime.SqlBuilder;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class CoalesceBuilder {
private List> expressions = new ArrayList<>();
CoalesceBuilder(Expression expression) {
expressions.add(expression);
}
public CoalesceBuilder or(Expression expr) {
if (((ExpressionImplementor>) expressions.get(0)).getType() !=
((ExpressionImplementor>)expr).getType()) {
throw new IllegalArgumentException("The branches of coalesce must belong to same type");
}
expressions.add(expr);
return this;
}
public CoalesceBuilder or(T value) {
return or(Literals.any(value));
}
@SuppressWarnings("unchecked")
public Expression build() {
List> clonedList;
if (expressions.get(0) instanceof Expr>) {
clonedList = new ArrayList<>(((Expr>)expressions.get(0)).expressions);
clonedList.addAll(expressions.subList(1, expressions.size()));
} else {
clonedList = new ArrayList<>(expressions);
}
Class> javaClass = ((ExpressionImplementor>) expressions.get(0)).getType();
if (String.class == javaClass) {
return (Expression) new StrExpr(clonedList);
}
if (javaClass.isPrimitive() || Number.class.isAssignableFrom(javaClass)) {
return (Expression) new NumExpr<>(clonedList);
}
if (Comparable.class.isAssignableFrom(javaClass)) {
return (Expression) new CmpExpr<>(clonedList);
}
return new Expr<>(clonedList);
}
public static class Str extends Cmp {
Str(Expression expression) {
super(expression);
}
@Override
public Str or(Expression expr) {
return (Str) super.or(expr);
}
@Override
public Str or(String value) {
return (Str) super.or(value);
}
@Override
public StringExpression build() {
return (StringExpression) super.build();
}
}
public static class Num> extends Cmp {
Num(Expression expression) {
super(expression);
}
@Override
public Num or(Expression expr) {
return (Num) super.or(expr);
}
@Override
public Num or(N value) {
return (Num) super.or(value);
}
@Override
public NumericExpression build() {
return (NumericExpression) super.build();
}
}
public static class Cmp> extends CoalesceBuilder {
Cmp(Expression expression) {
super(expression);
}
@Override
public Cmp or(Expression expr) {
return (Cmp) super.or(expr);
}
@Override
public Cmp or(T value) {
return (Cmp) super.or(value);
}
@Override
public ComparableExpression build() {
return (ComparableExpression) super.build();
}
}
private static class Expr extends AbstractExpression {
@Override
public Class getType() {
return ((ExpressionImplementor)expressions.get(0)).getType();
}
@Override
public int precedence() {
return 0;
}
private List> expressions;
public Expr(List> expressions) {
this.expressions = expressions;
}
@Override
public void accept(@NotNull AstVisitor visitor) {
for (Expression> expression : expressions) {
((Ast) expression).accept(visitor);
}
}
@Override
public void renderTo(@NotNull AbstractSqlBuilder> builder) {
if (expressions.size() == 1) {
renderChild((Ast) expressions.get(0), builder);
} else {
builder.sql("coalesce").enter(SqlBuilder.ScopeType.LIST);
for (Expression> expression : expressions) {
builder.separator();
renderChild((Ast) expression, builder);
}
builder.leave();
}
}
@Override
protected boolean determineHasVirtualPredicate() {
return hasVirtualPredicate(expressions);
}
@Override
protected Ast onResolveVirtualPredicate(AstContext ctx) {
this.expressions = ctx.resolveVirtualPredicates(expressions);
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Expr> expr = (Expr>) o;
return expressions.equals(expr.expressions);
}
@Override
public int hashCode() {
return Objects.hash(expressions);
}
}
private static class StrExpr extends Expr implements StringExpressionImplementor {
public StrExpr(List> expressions) {
super(expressions);
}
}
private static class NumExpr> extends Expr implements NumericExpressionImplementor {
public NumExpr(List> expressions) {
super(expressions);
}
}
private static class CmpExpr> extends Expr implements ComparableExpressionImplementor {
public CmpExpr(List> expressions) {
super(expressions);
}
}
}