All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jpattern.orm.query.OrmQuery Maven / Gradle / Ivy

package com.jpattern.orm.query;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.jpattern.orm.classtool.IOrmClassTool;
import com.jpattern.orm.classtool.IOrmClassToolMap;
import com.jpattern.orm.exception.OrmException;
import com.jpattern.orm.exception.OrmNotUniqueResultException;
import com.jpattern.orm.session.IResultSetReader;
import com.jpattern.orm.session.ISessionSqlPerformer;
import com.jpattern.orm.session.ISqlPerformer;

/**
 * 
 * @author Francesco Cina
 *
 * 20/giu/2011
 */
public class OrmQuery extends ABaseOrmQuery implements IOrmQuery, INameSolverConsumer {
	
	private INameSolver nameSolver = new NullNameSolver();
	private final IOrmClassToolMap ormClassToolMap;
	private final Class clazz;
	private final Class[] joinClasses;
	private boolean distinct;
	private final ISessionSqlPerformer session;
	private int queryTimeout = 0;
	private int maxRows = 0;
	private LockMode lockMode = LockMode.NO_LOCK;
	
	public OrmQuery(IOrmClassToolMap ormClassToolMap, ISessionSqlPerformer session, Class clazz, Class... joinClasses) {
		this.ormClassToolMap = ormClassToolMap;
		this.session = session;
		this.clazz = clazz;
		this.joinClasses = joinClasses;
		setJoin( new Join(ormClassToolMap) );
	}

	@Override
	public final int getMaxRows() throws OrmException {
		return maxRows;
	}

	@Override
	public final IOrmQuery setQueryTimeout(int queryTimeout) {
		this.queryTimeout = queryTimeout;
		return this;
	}

	@Override
	public final int getQueryTimeout() {
		return queryTimeout;
	}

	@Override
	public final IOrmQuery setMaxRows(int maxRows) throws OrmException {
		this.maxRows = maxRows;
		return this;
	}
	
	@Override
	public void setNameSolver(INameSolver nameSolver) {
		this.nameSolver = nameSolver;
		where().setNameSolver(nameSolver);
		orderBy().setNameSolver(nameSolver);
		join().setNameSolver(nameSolver);
	}

	@Override
	public List findList() {
		List values = new ArrayList();
		where().appendValues(values);
		final IOrmClassTool ormClassTool = ormClassToolMap.getOrmClassTool(clazz);
		
		IResultSetReader> resultSetReader = new IResultSetReader>() {

			@Override
			public List read(ResultSet resultSet) throws SQLException { 
				List resultList = new ArrayList();
				int rowCount = 0;
				while ( resultSet.next() ) {
					resultList.add( ormClassTool.getOrmPersistor().mapRow("", resultSet, rowCount++) );
				}
				return resultList;
			}
		};
		ISqlPerformer sqlExec = session.sqlPerformer();
		sqlExec.setMaxRows(getMaxRows());
		sqlExec.setQueryTimeout(getQueryTimeout());
		return sqlExec.query(renderSql(), resultSetReader, values.toArray());
	}
	
	@Override
	public void find(final IOrmRowMapper srr) throws OrmException {
		List values = new ArrayList();
		where().appendValues(values);
		final IOrmClassTool ormClassTool = ormClassToolMap.getOrmClassTool(clazz);
		
		IResultSetReader resultSetReader = new IResultSetReader() {
			@Override
			public Object read(ResultSet resultSet) throws SQLException { 
				int rowCount = 0;
				while ( resultSet.next() ) {
					srr.read( ormClassTool.getOrmPersistor().mapRow("", resultSet, rowCount) , rowCount );
					rowCount++;
				}
				return null;
			}
		};
		ISqlPerformer sqlExec = session.sqlPerformer();
		sqlExec.setMaxRows(getMaxRows());
		sqlExec.setQueryTimeout(getQueryTimeout());
		sqlExec.query(renderSql(), resultSetReader, values.toArray());
	}

	@Override
	public long findRowCount() {
		List values = new ArrayList();
		where().appendValues(values);
		ISqlPerformer sqlExec = session.sqlPerformer();
		sqlExec.setMaxRows(getMaxRows());
		sqlExec.setQueryTimeout(getQueryTimeout());
		return sqlExec.queryForLong(getGeneratedRowCountSql(), values.toArray());
	}

	@Override
	public T findUnique() throws OrmNotUniqueResultException {
		int oldMaxRow = getMaxRows();
		setMaxRows(2);
		List values = new ArrayList();
		where().appendValues(values);
		List result = findList();
		setMaxRows(oldMaxRow);
		if (result.size()==0) {
			return null;
		}
		if (result.size()>1) {
			throw new OrmNotUniqueResultException("The query execution returned a number of rows higher than 1");
		}
		return result.get(0);
	}

	@Override
	public String getGeneratedRowCountSql() {
		StringBuilder stringBuilder = new StringBuilder();
		renderSelectRowCount(stringBuilder);
		renderFrom(stringBuilder);
		renderWhere(stringBuilder);
		return stringBuilder.toString();
	}

	@Override
	public IOrmQuery setDistinct() {
		this.distinct = true;
		return this;
	}

	private void renderSelectRowCount(StringBuilder stringBuilder) {
		stringBuilder.append("SELECT COUNT(*) ");
	}
	
	@Override
	protected void renderSelect(StringBuilder stringBuilder) {
		String alias = nameSolver.alias(clazz); 
		stringBuilder.append("SELECT ");
		if (distinct) {
			stringBuilder.append("DISTINCT ");
		}
		stringBuilder.append(ormClassToolMap.getOrmClassTool(clazz).getOrmCRUDQuery().getBaseSelectClause(alias + ".") );
		stringBuilder.append(" ");
	}

	@Override
	protected void renderFrom(StringBuilder stringBuilder) {
		String alias = nameSolver.alias(clazz);
		stringBuilder.append("FROM ");
		stringBuilder.append(ormClassToolMap.getOrmClassTool(clazz).getClassMapper().getTableMap().getTableNameWithSchema() );
		stringBuilder.append( " " );
		stringBuilder.append(alias);
		stringBuilder.append(" ");
		join().renderSql(stringBuilder);
		if (joinClasses!=null && joinClasses.length>0) {
			for (Class joinClass : joinClasses) {
				stringBuilder.append( ", " );
				stringBuilder.append(ormClassToolMap.getOrmClassTool(joinClass).getClassMapper().getTableMap().getTableNameWithSchema() );
				stringBuilder.append( " " );
				stringBuilder.append(nameSolver.alias(joinClass));
			}
			stringBuilder.append(" ");
		}
	}
	
	@Override
	protected void renderWhere(StringBuilder stringBuilder) {
		where().renderSql(stringBuilder);
	}
	
	@Override
	protected void renderOrderBy(StringBuilder stringBuilder) {
		orderBy().renderSql(stringBuilder);
	}

	@Override
	protected void renderLockMode(StringBuilder stringBuilder) {
		stringBuilder.append(lockMode.getLockMode());
	}
	
	@Override
	public boolean isDistinct() throws OrmException {
		return distinct;
	}

	@Override
	public IOrmQuery setLockMode(LockMode lockMode) {
		this.lockMode = lockMode;
		return this;
	}

}