Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapSessionImpl.java (working copy) @@ -20,6 +20,7 @@ import com.ibatis.sqlmap.client.SqlMapSession; import com.ibatis.sqlmap.client.event.RowHandler; import com.ibatis.sqlmap.engine.execution.BatchException; +import com.ibatis.sqlmap.engine.execution.ISqlExecutor; import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement; import com.ibatis.sqlmap.engine.scope.SessionScope; @@ -253,7 +254,7 @@ * * @return - the executor */ - public SqlExecutor getSqlExecutor() { + public ISqlExecutor getSqlExecutor() { return delegate.getSqlExecutor(); } Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java (working copy) @@ -25,6 +25,7 @@ import com.ibatis.sqlmap.engine.cache.CacheModel; import com.ibatis.sqlmap.engine.exchange.DataExchangeFactory; import com.ibatis.sqlmap.engine.execution.BatchException; +import com.ibatis.sqlmap.engine.execution.ISqlExecutor; import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; import com.ibatis.sqlmap.engine.mapping.result.ResultMap; @@ -70,7 +71,7 @@ private HashMap resultMaps; private HashMap parameterMaps; - protected SqlExecutor sqlExecutor; + protected ISqlExecutor sqlExecutor; private TypeHandlerFactory typeHandlerFactory; private DataExchangeFactory dataExchangeFactory; @@ -91,7 +92,32 @@ dataExchangeFactory = new DataExchangeFactory(typeHandlerFactory); } + // Support for custom executors /** + * @param ExecutorClassName - ClassName of executor + */ + public void setCustomExecutor(String SqlExecutorClass) { + + // dont use default Executor + sqlExecutor = null; + + // Create an instance of custom executor and initialize it. + try { + Class factoryClass = Class.forName(SqlExecutorClass); + sqlExecutor = (ISqlExecutor) factoryClass.newInstance(); + } catch (ClassNotFoundException ex) { + // Throw Run time exception. + throw new RuntimeException("Custom SQLExecutor not found -" + SqlExecutorClass + ". Please check the class given in properties file. Cause: " + ex, ex); + } catch (InstantiationException ex) { + // Throw Run time exception. + throw new RuntimeException("Could not instantiate Custom SQLExecutor - " + SqlExecutorClass +". Cause: " + ex, ex); + } catch (IllegalAccessException ex) { + // Throw Run time exception. + throw new RuntimeException("Illegal access for Custom SQLExecutor - " + SqlExecutorClass + ". Cause: " + ex, ex); + } + } + + /** * DO NOT DEPEND ON THIS. Here to avoid breaking spring integration. * @deprecated */ @@ -814,8 +840,9 @@ * * @return the SqlExecutor */ - public SqlExecutor getSqlExecutor() { - return sqlExecutor; + public ISqlExecutor getSqlExecutor() { + return sqlExecutor; + } /** Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/ExtendedSqlMapClient.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/ExtendedSqlMapClient.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/ExtendedSqlMapClient.java (working copy) @@ -83,7 +83,7 @@ boolean isEnhancementEnabled(); - SqlExecutor getSqlExecutor(); + ISqlExecutor getSqlExecutor(); SqlMapExecutorDelegate getDelegate(); Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapClientImpl.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapClientImpl.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/impl/SqlMapClientImpl.java (working copy) @@ -21,6 +21,7 @@ import com.ibatis.sqlmap.client.*; import com.ibatis.sqlmap.client.event.RowHandler; import com.ibatis.sqlmap.engine.execution.BatchException; +import com.ibatis.sqlmap.engine.execution.ISqlExecutor; import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory; import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement; @@ -209,7 +210,7 @@ return delegate.isEnhancementEnabled(); } - public SqlExecutor getSqlExecutor() { + public ISqlExecutor getSqlExecutor() { return delegate.getSqlExecutor(); } Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/ISqlExecutor.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/ISqlExecutor.java (revision 0) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/ISqlExecutor.java (revision 0) @@ -0,0 +1,108 @@ +package com.ibatis.sqlmap.engine.execution; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; + +import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback; +import com.ibatis.sqlmap.engine.scope.SessionScope; +import com.ibatis.sqlmap.engine.scope.StatementScope; + +/** + * Classes responsible for executing the SQL implement this interface + * Support for custom SQL Executors. + */ +public interface ISqlExecutor { + + /** + * Execute an update + * + * @param statementScope - the request scope + * @param conn - the database connection + * @param sql - the sql statement to execute + * @param parameters - the parameters for the sql statement + * @return - the number of records changed + * @throws SQLException - if the update fails + */ + public int executeUpdate(StatementScope statementScope, Connection conn, String sql, Object[] parameters) throws SQLException; + + /** + * Adds a statement to a batch + * + * @param statementScope - the request scope + * @param conn - the database connection + * @param sql - the sql statement + * @param parameters - the parameters for the statement + * @throws SQLException - if the statement fails + */ + public void addBatch(StatementScope statementScope, Connection conn, String sql, Object[] parameters) throws SQLException; + + /** + * Execute a batch of statements + * + * @param sessionScope - the session scope + * @return - the number of rows impacted by the batch + * @throws SQLException - if a statement fails + */ + public int executeBatch(SessionScope sessionScope) throws SQLException; + + /** + * Execute a batch of statements + * + * @param sessionScope - the session scope + * @return - a List of BatchResult objects (may be null if no batch + * has been initiated). There will be one BatchResult object in the + * list for each sub-batch executed + * @throws SQLException if a database access error occurs, or the drive + * does not support batch statements + * @throws BatchException if the driver throws BatchUpdateException + */ + public List executeBatchDetailed(SessionScope sessionScope) throws SQLException, BatchException; + + /** + * Long form of the method to execute a query + * + * @param statementScope - the request scope + * @param conn - the database connection + * @param sql - the SQL statement to execute + * @param parameters - the parameters for the statement + * @param skipResults - the number of results to skip + * @param maxResults - the maximum number of results to return + * @param callback - the row handler for the query + * @throws SQLException - if the query fails + */ + public void executeQuery(StatementScope statementScope, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException; + + /** + * Execute a stored procedure that updates data + * + * @param statementScope - the request scope + * @param conn - the database connection + * @param sql - the SQL to call the procedure + * @param parameters - the parameters for the procedure + * @return - the rows impacted by the procedure + * @throws SQLException - if the procedure fails + */ + public int executeUpdateProcedure(StatementScope statementScope, Connection conn, String sql, Object[] parameters) throws SQLException; + + /** + * Execute a stored procedure + * + * @param statementScope - the request scope + * @param conn - the database connection + * @param sql - the sql to call the procedure + * @param parameters - the parameters for the procedure + * @param skipResults - the number of results to skip + * @param maxResults - the maximum number of results to return + * @param callback - a row handler for processing the results + * @throws SQLException - if the procedure fails + */ + public void executeQueryProcedure(StatementScope statementScope, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException; + + /** + * Clean up any batches on the session + * + * @param sessionScope - the session to clean up + */ + public void cleanup(SessionScope sessionScope); +} Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java (working copy) @@ -35,7 +35,7 @@ /** * Class responsible for executing the SQL */ -public class SqlExecutor { +public class SqlExecutor implements ISqlExecutor { // // Constants Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/builder/xml/XmlParserState.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/builder/xml/XmlParserState.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/builder/xml/XmlParserState.java (working copy) @@ -2,6 +2,7 @@ import com.ibatis.common.resources.*; import com.ibatis.sqlmap.engine.config.*; +import com.ibatis.sqlmap.engine.execution.ISqlExecutor; import javax.sql.DataSource; import java.util.*; @@ -129,6 +130,21 @@ props.putAll(globalProps); globalProps = props; } + + // Check for custom executors + String customizedSQLExecutor = globalProps.getProperty("ibatis.sqlExecutor_class"); + config.getErrorContext().setActivity("Loading SQLExecutor."); + if (customizedSQLExecutor != null) { + + try { + config.getClient().getDelegate().setCustomExecutor(customizedSQLExecutor); + }catch (RuntimeException e) { + config.getErrorContext().setCause(e); + config.getErrorContext().setMoreInfo("Loading of customizedSQLExecutor failed. Please check Properties file."); + } + + } + } catch (Exception e) { throw new RuntimeException("Error loading properties. Cause: " + e, e); } Index: /ibatisSVN/src/com/ibatis/sqlmap/engine/mapping/statement/MappedStatement.java =================================================================== --- /ibatisSVN/src/com/ibatis/sqlmap/engine/mapping/statement/MappedStatement.java (revision 742332) +++ /ibatisSVN/src/com/ibatis/sqlmap/engine/mapping/statement/MappedStatement.java (working copy) @@ -20,6 +20,7 @@ import com.ibatis.sqlmap.client.event.RowHandler; import com.ibatis.sqlmap.client.*; +import com.ibatis.sqlmap.engine.execution.ISqlExecutor; import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; import com.ibatis.sqlmap.engine.mapping.result.ResultMap; @@ -347,7 +348,7 @@ } } - public SqlExecutor getSqlExecutor() { + public ISqlExecutor getSqlExecutor() { return sqlMapClient.getSqlExecutor(); }