/** * */ package squill.functions; import static java.util.Arrays.asList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import squill.query.Declaration; import squill.query.Expression; import squill.query.select.SelectExpression; import squill.query.select.SimpleSelectExpression; import squill.query.where.WhereExpression; import squill.util.StringUtil; /** * Operators that can be used inside WHERE. */ public class OperationsHelper { public static final Object[] EMTPY_ARGS = {}; // TODO constant is an operand not an operator @SuppressWarnings("unchecked") public static <T> SelectExpression<T> constant(final T value) { final Class type = value != null ? value.getClass() : null; return new SimpleSelectExpression<T>(type) { public String getDefaultSql() { return "?"; } public List<Object> getSqlArguments() { return asList((Object) value); } }; } public static <T> SelectExpression<T> param(final String name,final Class<T> type) { return new SimpleSelectExpression<T>(type) { public String getDefaultSql() { return "?"; // todo formatter for spring named params ":"+name; } public List<Object> getSqlArguments() { return Collections.<Object>singletonList(new Declaration<T>(type,name)); } }; } public static <T> SelectExpression<T> literal(final T value) { final Class type = value != null ? value.getClass() : null; return new SimpleSelectExpression<T>(type) { public String getDefaultSql() { if (value instanceof String) return "'" + value + "'"; if (value instanceof Expression) return ((Expression) value).getDefaultSql(); return value.toString(); } public List<Object> getSqlArguments() { return Collections.emptyList(); } }; } public static WhereExpression multiBooleanOperator(final String operator, final WhereExpression... exps) { return new MultiOperatorBooleanExpression<Boolean>(operator,exps); } public static <T> WhereExpression unaryPrefixBooleanOperator(final Expression<T> exp, final String operator) { return new MultiOperatorBooleanExpression<T>(operator,exp) { @Override public String getDefaultSql() { StringBuilder sql = new StringBuilder(); sql.append(operator); sql.append(exp.getDefaultSql()); return sql.toString(); } }; } public static <T> WhereExpression unaryPostfixBooleanOperator(final Expression<T> exp, final String operator) { return new MultiOperatorBooleanExpression<T>(operator,exp) { @Override public String getDefaultSql() { StringBuilder sql = new StringBuilder(); sql.append(exp.getDefaultSql()); sql.append(operator); return sql.toString(); } }; } public static <T> WhereExpression binaryBooleanOperator(final T val1, final String operator, final T val2) { return new MultiOperatorBooleanExpression<T>(operator, expressionOrConstant(val1), expressionOrConstant(val2)); } public static <T> WhereExpression inOperation(final Collection<Expression<T>> expressions) { return new MultiOperatorBooleanExpression<T>("in", expressions) { @Override public String getDefaultSql() { final List<? extends Expression<?>> parts = getParts(); StringBuilder sb = new StringBuilder(parts.get(0).getDefaultSql()); sb.append(" "); sb.append(getOperator()); sb.append(" ("); final List<? extends Expression<?>> operands = parts.subList(1, parts.size()); sb.append(StringUtil.join(operands, Expression.GET_SQL_STRING, ",")); sb.append(") "); return sb.toString(); } }; } public static <A, B, RETURN_TYPE> SelectExpression<RETURN_TYPE> binaryOperator(Class<RETURN_TYPE> type, final String operator, final Expression<A> exp1, final Expression<B> exp2) { // using package access return new BinaryOperatorSelectExpression<RETURN_TYPE,A,B>(type, exp1, operator, exp2); } // TODO NVL is a function not an operator public static <T> SelectExpression<T> nvl(Class<T> type, final Expression<T> exp1, final Expression<T> exp2) { return new BinaryOperatorSelectExpression<T,T,T>(type,exp1,"nvl",exp2) { @Override public String getDefaultSql() { StringBuilder sql = new StringBuilder(); sql.append("nvl("); sql.append(exp1.getDefaultSql()); sql.append(","); sql.append(exp2.getDefaultSql()); sql.append(")"); return sql.toString(); } }; } /** * Concatenates two lists. * * @param list1 first list. * @param list2 second list. * @return new list containing items from both lists. */ protected static List<Object> concat(List<Object> list1, List<Object> list2) { List<Object> args = new ArrayList<Object>(list1.size() + list2.size()); args.addAll(list1); args.addAll(list2); return args; } @SuppressWarnings({"unchecked"}) public static <T> Expression<T> expressionOrConstant(T value) { if (value instanceof Expression) return (Expression<T>) value; else return constant(value); } public static <T> SelectExpression<T> unchecked(String alias, Class<T> type, final String sql, final Object... args) { return new UncheckedExpression<T>(alias, type, sql, args); } public static <T> SelectExpression<T> unchecked(Class<T> type, final String sql, final Object... args) { return unchecked(null,type,sql,args); } public static <T> SelectExpression<T> unchecked(Class<T> type, final String sql) { return unchecked(null,type,sql, EMTPY_ARGS); } }