package squill.builder; import static java.util.Arrays.asList; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import squill.callback.ResultCallback; import squill.db.Database; import squill.format.SqlFormat; import squill.query.*; import squill.query.orderby.OrderByElement; import squill.query.select.SelectExpression; import squill.query.select.SimpleSelectExpression; import squill.tree.QueryPartHandler; import squill.tuple.Tuple; import squill.tuple.Tuple1; public class BaseOrderByBuilder extends BaseBuilder { protected final SelectPart selectPart; protected final OrderByPart orderByPart; protected static final Log log = LogFactory.getLog(BaseOrderByBuilder.class); public BaseOrderByBuilder(QueryContext ctx, Database dataSource) { super(ctx, dataSource); selectPart = new SelectPart(ctx); orderByPart = new OrderByPart(ctx); } protected void addSelects(SelectExpression<?>... selects) { selectPart.addSelects(selects); addArgs(selects); } private void addArgs(final Expression<?>... expressions) { for (Expression expression : expressions) { addArgs(expression.getSqlArguments()); } } protected void setOrderbyList(OrderByElement<?>[] orderbyArray) { orderByPart.setOrderByList(asList(orderbyArray)); } public <FT> SelectExpression<FT> subSelect(final SelectExpression<FT> select) { addSelects(select); SelectExpression<FT> exp = new SimpleSelectExpression<FT>(select.getTableType()) { @Override public String getDefaultSql() { return "(" + getSql() + ")"; } @Override public List<Object> getSqlArguments() { return select.getSqlArguments(); } @Override public void setQueryContext(QueryContext ctx) { super.setQueryContext(ctx); BaseOrderByBuilder.this.setQueryContext(ctx); } }; return exp; } @Override protected void setQueryContext(QueryContext ctx) { super.setQueryContext(ctx); selectPart.setQueryContext(ctx); orderByPart.setQueryContext(ctx); } Tuple queryTuple(Class<? extends Tuple> tupleType, SelectExpression<?>... selects) { addSelects(selects); return database.queryTuple(getSql(), getArgs(), selectPart.getSelectList(), tupleType); } List queryTuples(Class<? extends Tuple> tupleType, SelectExpression<?>... selects) { addSelects(selects); return database.queryList(getSql(), getArgs(), selectPart.getSelectList(), tupleType); } @SuppressWarnings( { "unchecked" }) <P extends Tuple, R> List<R> queryCallback(Class<P> tupleType, ResultCallback<P, R> callback, SelectExpression<?>... selects) { addSelects(selects); return database.queryCallback(getSql(), getArgs(), selectPart.getSelectList(), tupleType, (ResultCallback<Tuple, R>) callback); } @Override // Select full, tbl objects (each object selects all its known fields) public String getSql() { // orderByPart.checkOrderByOccurrence(fromPart, selectPart); StringBuilder sql = new StringBuilder(); sql.append(selectPart.getDefaultSql()); sql.append(fromPart.getDefaultSql()); sql.append(wherePart.getDefaultSql()); sql.append(orderByPart.getDefaultSql()); return sql.toString(); } public String getSql(final SqlFormat format) { final StringBuilder sql = new StringBuilder(); handle(new QueryPartHandler<StringBuilder>() { public void handle(final QueryPart queryPart, final StringBuilder sql) { if (queryPart == null) { return; } sql.append(format.format(queryPart)); } }, sql); return sql.toString(); } public String getCountSql() { StringBuilder sql = new StringBuilder("SELECT count(*) "); sql.append(fromPart.getDefaultSql()); sql.append(wherePart.getDefaultSql()); return sql.toString(); } public long count() { return database.count(getCountSql(), getArgs()); } public <T> T traverse(QueryPartHandler<T> handler, T collectingParameter) { selectPart.traverse(handler, collectingParameter); fromPart.traverse(handler, collectingParameter); wherePart.traverse(handler, collectingParameter); orderByPart.traverse(handler, collectingParameter); return collectingParameter; } public <T> T handle(QueryPartHandler<T> handler, T collectingParameter) { handler.handle(selectPart, collectingParameter); handler.handle(fromPart, collectingParameter); handler.handle(wherePart, collectingParameter); handler.handle(orderByPart, collectingParameter); return collectingParameter; } /** * Select 1 value(s) as single object (not a list) */ public <F1> F1 select(SelectExpression<F1> select1) { Tuple1<F1> tuple1 = (Tuple1<F1>) queryTuple(Tuple1.class, select1); return tuple1 == null ? null : tuple1.v1; } /** * Select 1 value(s) as a list */ public <F1> List<F1> selectList(SelectExpression<F1> select1) { List<F1> result = new ArrayList<F1>(); List<Tuple1<F1>> tupled = queryTuples(Tuple1.class, select1); for (Tuple1<F1> tuple1 : tupled) { result.add(tuple1.v1); } return result; } public <F1, R> List<R> selectCallback(SelectExpression<F1> select1, final ResultCallback<F1, R> callback) { final ResultCallback<Tuple1<F1>, R> tupleCallback = new ResultCallback<Tuple1<F1>, R>() { public R handle(final Tuple1<F1> tuple, final Status status) { return callback.handle(tuple.v1, status); } }; return queryCallback(Tuple1.class, (ResultCallback<Tuple1, R>) (Object) tupleCallback, select1); } public <F1> ResultBuilder<Tuple1<F1>> selectAs(SelectExpression<F1> select1) { addSelects(select1); return new ResultBuilder<Tuple1<F1>>(this, Tuple1.class); } }