/******************************************************************************* * Copyright (c) 2014 BestSolution.at and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * tom <FIRSTNAME.LASTNAME@bestsolution.at> - initial API and implementation *******************************************************************************/ package at.bestsolution.persistence.java.query; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import at.bestsolution.persistence.DynamicSelectQuery; import at.bestsolution.persistence.expr.Expression; import at.bestsolution.persistence.expr.GroupExpression; import at.bestsolution.persistence.expr.PropertyExpression; import at.bestsolution.persistence.java.DatabaseSupport; import at.bestsolution.persistence.java.JavaObjectMapper; import at.bestsolution.persistence.java.Util; import at.bestsolution.persistence.order.OrderColumn; public abstract class DynamicSelectQueryImpl<T,O> extends DynamicBaseQuery<T, O> implements DynamicSelectQuery<T,O>, InternalSelectQueryCriteria { private final DynamicListDelegate<T,O> listDelegate; private Expression<O> expression; private final JavaObjectMapper<?> rootMapper; private final String rootPrefix; private List<OrderColumn<O>> orderColumns; private int maxRows = -1; public DynamicSelectQueryImpl(DatabaseSupport db,JavaObjectMapper<?> rootMapper, String rootPrefix, DynamicListDelegate<T,O> listDelegate) { super(db); this.rootMapper = rootMapper; this.rootPrefix = rootPrefix; this.listDelegate = listDelegate; } @Override public List<T> list() { List<T> l = listDelegate.list(this); if( maxRows != -1 ) { if( l.size() > maxRows ) { Util.trimToSize(l, maxRows); } } return l; } @Override public DynamicSelectQuery<T,O> maxRows(int maxRows) { this.maxRows = maxRows; return this; } public abstract String processSQL(String sql); /** * @return the maxRows */ public int getMaxRows() { return maxRows; } @Override public T unique() { List<T> l = list(); if( l.size() == 1 ) { return l.get(0); } else if( l.size() > 1 ) { throw new IllegalStateException("More than one result"); } return null; } @Override public DynamicSelectQuery<T,O> where(Expression<O> expression) { this.expression = expression; return this; } protected boolean isJoinQuery() { if( expression != null ) { return isJoinExpression(expression); } return false; } private boolean isJoinExpression(final Expression<O> expression) { switch (expression.type) { case AND: case OR: { for (Expression<O> e : ((GroupExpression<O>) expression).expressions) { if( isJoinExpression(e) ) { return true; } } return false; } default: { PropertyExpression<O> p = (PropertyExpression<O>) expression; return p.property.contains("."); } } } public String getCriteriaJoin() { StringBuilder b = new StringBuilder(); if (expression != null) { LinkedHashSet<Join> joins = new LinkedHashSet<Join>(); appendJoinCriteria(joins, rootMapper, rootPrefix == null ? "" : rootPrefix, expression); for( Join j : joins ) { // Remark do NOT escape aliases because they are most likely not escaped themselves b.append("INNER JOIN " + quoteColumnName(j.joinTable) + " " + j.joinAlias + " ON " + j.joinAlias + "." + quoteColumnName(j.joinColumn) + " = " + ( j.otherAlias != null ? j.otherAlias + "." : "") + quoteColumnName(j.otherColumn) + " \n"); } } return b.toString(); } public String getCriteria() { StringBuilder b = new StringBuilder(); if (expression != null) { appendCriteria(b, rootMapper, rootPrefix == null ? quoteColumnName(rootMapper.getTableName()) + "." : rootPrefix + ".", expression); } return b.toString(); } public String getOrderBy() { StringBuilder b = new StringBuilder(); if( orderColumns != null && ! orderColumns.isEmpty() ) { for( OrderColumn<?> c : orderColumns ) { if( b.length() > 0 ) { b.append(", "); } b.append(rootMapper.getColumnName(c.column) + (c.asc ? " ASC" : " DESC")); } } return b.toString(); } public TypedValue[] getParameters() { List<TypedValue> rv = new ArrayList<TypedValue>(); if( expression != null) { appendValue(rv, rootMapper, expression); } return rv.toArray(new TypedValue[0]); } @Override public DynamicSelectQuery<T,O> orderBy(OrderColumn<O>... columns) { orderColumns = Arrays.asList(columns); return this; } }