package jp.sf.amateras.mirage;

import java.util.List;

import jp.sf.amateras.mirage.dialect.Dialect;
import jp.sf.amateras.mirage.naming.NameConverter;
import jp.sf.amateras.mirage.provider.ConnectionProvider;
import jp.sf.amateras.mirage.type.ValueType;

public interface SqlManager {

	public void setNameConverter(NameConverter converter);

	public void setConnectionProvider(ConnectionProvider connectionProvider);

	public void setDialect(Dialect dialect);

	public void addValueType(ValueType valueType);

	public <T> int getCount(String sqlPath);

	public <T> int getCount(String sqlPath, Object param);

	public <T> List<T> getResultList(Class<T> clazz, String sqlPath);

	public <T> List<T> getResultList(Class<T> clazz, String sqlPath, Object param);

	public <T, R> R iterate(Class<T> clazz, IterationCallback<T, R> callback, String sqlPath);

	public <T, R> R iterate(Class<T> clazz, IterationCallback<T, R> callback, String sqlPath, Object param);

	public <T> T getSingleResult(Class<T> clazz, String sqlPath);

	public <T> T getSingleResult(Class<T> clazz, String sqlPath, Object param);

	public int executeUpdate(String sqlPath);

	public int executeUpdate(String sqlPath, Object param);

	/**
	 * Inserts the given entity.
	 *
	 * @param entity the entity to insert
	 * @return the number of updated rows
	 */
	public int insertEntity(Object entity);

	/**
	 * Updates the given entity.
	 *
	 * @param entity the entity to update
	 * @return the number of updated rows
	 */
	public int updateEntity(Object entity);

	/**
	 * Deletes the given entity.
	 *
	 * @param entity the entity to delete
	 * @return the number of updated rows
	 */
	public int deleteEntity(Object entity);

	/**
	 * Finds the entity by the given primary key.
	 *
	 * @param <T> the type of entity
	 * @param clazz the type of entity
	 * @param id the primary key
	 * @return the entity. If the entity which corresponds to the given primary key
	 *   is not found, this method returns <code>null</code>.
	 */
	public <T> T findEntity(Class<T> clazz, Object... id);

	public void call(String procedureName);

	public void call(String procedureName, Object parameter);

	public <T> T call(Class<T> resultClass, String functionName);

	public <T> T call(Class<T> resultClass, String functionName, Object param);

	public <T> List<T> callForList(Class<T> resultClass, String functionName);

	public <T> List<T> callForList(Class<T> resultClass, String functionName, Object param);

	public <T> List<T> getResultListBySql(Class<T> clazz, String sql);

	public <T> List<T> getResultListBySql(Class<T> clazz, String sql, Object... params);

	public <T> T getSingleResultBySql(Class<T> clazz, String sql);

	public <T> T getSingleResultBySql(Class<T> clazz, String sql, Object... params);

	public <T, R> R iterateBySql(Class<T> clazz, IterationCallback<T, R> callback, String sql);

	public <T, R> R iterateBySql(Class<T> clazz, IterationCallback<T, R> callback, String sql, Object... params);

	/**
	 * Executes the given SQL.
	 * <pre>
	 * int rows = sqlManager.executeUpdateBySql("DELETE FROM EMPLOYEE");
	 * </pre>
	 *
	 * @param sql the SQL to execute
	 * @return the number of updated rows
	 */
	public int executeUpdateBySql(String sql);

	/**
	 * Executes the given SQL with parameters.
	 * <pre>
	 * int rows = sqlManager.executeUpdateBySql("DELETE FROM EMPLOYEE WHERE ID=?", id);
	 * </pre>
	 *
	 * @param sql the SQL to execute which contains placeholder (This is not a 2waySQL)
	 * @param params the parameters which are set to the placeholder
	 * @return the number of updated rows
	 */
	public int executeUpdateBySql(String sql, Object... params);

}
