diff --git a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java index d11e808e0..84dfdb78f 100644 --- a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java +++ b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java @@ -30,6 +30,7 @@ import org.springframework.batch.restart.GenericRestartData; import org.springframework.batch.restart.RestartData; import org.springframework.batch.support.PropertiesConverter; import org.springframework.beans.factory.InitializingBean; +import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; @@ -77,7 +78,7 @@ public class SqlStepDao implements StepDao, InitializingBean { private static final String FIND_STEP_EXECUTIONS = "SELECT ID, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT," + " TASK_COUNT, TASK_STATISTICS, EXIT_CODE from %PREFIX%STEP_EXECUTION where STEP_ID = ?"; - private JdbcTemplate jdbcTemplate; + private JdbcOperations jdbcTemplate; private DataFieldMaxValueIncrementer stepIncrementer; @@ -316,7 +317,7 @@ public class SqlStepDao implements StepDao, InitializingBean { } - public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + public void setJdbcTemplate(JdbcOperations jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/MockJdbcTemplate.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/MockJdbcTemplate.java new file mode 100644 index 000000000..b923b3340 --- /dev/null +++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/MockJdbcTemplate.java @@ -0,0 +1,383 @@ +package org.springframework.batch.execution.repository.dao; + +import java.util.List; +import java.util.Map; + +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.CallableStatementCallback; +import org.springframework.jdbc.core.CallableStatementCreator; +import org.springframework.jdbc.core.ConnectionCallback; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.PreparedStatementCallback; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.PreparedStatementSetter; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.RowCallbackHandler; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.StatementCallback; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.jdbc.support.rowset.SqlRowSet; + +public class MockJdbcTemplate implements JdbcOperations { + + private String sqlStatement = ""; + + public String getSqlStatement() { + return sqlStatement; + } + + public int[] batchUpdate(String[] sql) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) + throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Map call(CallableStatementCreator csc, List declaredParameters) + throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object execute(ConnectionCallback action) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object execute(StatementCallback action) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public void execute(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + } + + public Object execute(PreparedStatementCreator psc, + PreparedStatementCallback action) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object execute(String sql, PreparedStatementCallback action) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object execute(CallableStatementCreator csc, + CallableStatementCallback action) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object execute(String callString, CallableStatementCallback action) + throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object query(String sql, ResultSetExtractor rse) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public void query(String sql, RowCallbackHandler rch) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + } + + public List query(String sql, RowMapper rowMapper) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object query(PreparedStatementCreator psc, ResultSetExtractor rse) + throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public void query(PreparedStatementCreator psc, RowCallbackHandler rch) + throws DataAccessException { + // TODO Auto-generated method stub + } + + public List query(PreparedStatementCreator psc, RowMapper rowMapper) + throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public Object query(String sql, PreparedStatementSetter pss, + ResultSetExtractor rse) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object query(String sql, Object[] args, ResultSetExtractor rse) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public void query(String sql, PreparedStatementSetter pss, + RowCallbackHandler rch) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + } + + public void query(String sql, Object[] args, RowCallbackHandler rch) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + } + + public List query(String sql, PreparedStatementSetter pss, + RowMapper rowMapper) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List query(String sql, Object[] args, RowMapper rowMapper) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object query(String sql, Object[] args, int[] argTypes, + ResultSetExtractor rse) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public void query(String sql, Object[] args, int[] argTypes, + RowCallbackHandler rch) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + } + + public List query(String sql, Object[] args, int[] argTypes, + RowMapper rowMapper) throws DataAccessException { + // TODO Auto-generated method stub + return null; + } + + public int queryForInt(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public int queryForInt(String sql, Object[] args) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public int queryForInt(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public List queryForList(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List queryForList(String sql, Class elementType) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List queryForList(String sql, Object[] args) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List queryForList(String sql, Object[] args, Class elementType) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List queryForList(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public List queryForList(String sql, Object[] args, int[] argTypes, + Class elementType) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public long queryForLong(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public long queryForLong(String sql, Object[] args) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public long queryForLong(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public Map queryForMap(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Map queryForMap(String sql, Object[] args) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Map queryForMap(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, RowMapper rowMapper) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, Class requiredType) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, Object[] args, RowMapper rowMapper) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, Object[] args, Class requiredType) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, Object[] args, int[] argTypes, + RowMapper rowMapper) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public Object queryForObject(String sql, Object[] args, int[] argTypes, + Class requiredType) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public SqlRowSet queryForRowSet(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public SqlRowSet queryForRowSet(String sql, Object[] args) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return null; + } + + public int update(String sql) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public int update(PreparedStatementCreator psc) throws DataAccessException { + // TODO Auto-generated method stub + return 0; + } + + public int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) + throws DataAccessException { + // TODO Auto-generated method stub + return 0; + } + + public int update(String sql, PreparedStatementSetter pss) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public int update(String sql, Object[] args) throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + + public int update(String sql, Object[] args, int[] argTypes) + throws DataAccessException { + // TODO Auto-generated method stub + sqlStatement = sql; + return 0; + } + +} diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/SqlStepDaoPrefixTests.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/SqlStepDaoPrefixTests.java new file mode 100644 index 000000000..9eb6d2e18 --- /dev/null +++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/SqlStepDaoPrefixTests.java @@ -0,0 +1,159 @@ +package org.springframework.batch.execution.repository.dao; + +import java.util.ArrayList; +import java.util.List; + +import org.easymock.MockControl; +import org.springframework.batch.core.domain.BatchStatus; +import org.springframework.batch.core.domain.JobInstance; +import org.springframework.batch.core.domain.StepExecution; +import org.springframework.batch.core.domain.StepInstance; +import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; + +import junit.framework.TestCase; + +/** + * Unit Test of SqlStepDao that only tests prefix matching. A + * separate test is needed because all other tests hit hsql, + * while this test needs to mock JdbcTemplate to analyze the + * Sql passed in. + * + * @author Lucas Ward + * + */ +public class SqlStepDaoPrefixTests extends TestCase { + + private SqlStepDao stepDao; + + MockJdbcTemplate jdbcTemplate = new MockJdbcTemplate(); + + StepExecution stepExecution = new StepExecution(new Long(1), new Long(2)); + StepInstance step = new StepInstance(new Long(1)); + JobInstance job = new JobInstance(new Long(1)); + + MockControl stepExecutionIncrementerControl = MockControl.createControl(DataFieldMaxValueIncrementer.class); + DataFieldMaxValueIncrementer stepExecutionIncrementer; + MockControl stepIncrementerControl = MockControl.createControl(DataFieldMaxValueIncrementer.class); + DataFieldMaxValueIncrementer stepIncrementer; + + protected void setUp() throws Exception { + super.setUp(); + + stepDao = new SqlStepDao(); + stepExecutionIncrementer = (DataFieldMaxValueIncrementer)stepExecutionIncrementerControl.getMock(); + stepIncrementer = (DataFieldMaxValueIncrementer)stepIncrementerControl.getMock(); + + stepDao.setJdbcTemplate(jdbcTemplate); + stepDao.setStepExecutionIncrementer(stepExecutionIncrementer); + stepDao.setStepIncrementer(stepIncrementer); + stepExecution.setId(new Long(1)); + step.setStatus(BatchStatus.STARTED); + + job.addStep(step); + + } + + public void testModifiedUpdateStepExecution(){ + stepDao.setTablePrefix("FOO_"); + stepDao.update(stepExecution); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1); + } + + public void testModifiedSaveStepExecution(){ + stepDao.setTablePrefix("FOO_"); + stepExecutionIncrementer.nextLongValue(); + stepExecutionIncrementerControl.setReturnValue(1); + stepExecutionIncrementerControl.replay(); + stepDao.save(stepExecution); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1); + } + + public void testModifiedFindStepExecutions(){ + stepDao.setTablePrefix("FOO_"); + stepDao.findStepExecutions(step); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1); + } + + public void testModifiedUpdateStep(){ + stepDao.setTablePrefix("FOO_"); + stepDao.update(step); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1); + } + + public void testModifiedCreateStep(){ + stepDao.setTablePrefix("FOO_"); + stepIncrementer.nextLongValue(); + stepIncrementerControl.setReturnValue(1); + stepIncrementerControl.replay(); + stepDao.createStep(job, "test"); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1); + } + + public void testModifiedFindSteps(){ + stepDao.setTablePrefix("FOO_"); + stepDao.findSteps(new Long(1)); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1); + } + + public void testModifiedFindStep(){ + stepDao.setTablePrefix("FOO_"); + try{ + stepDao.findStep(job, "test"); + } + catch(NullPointerException ex){ + //It's going to throw a NullPointerException because the MockJdbcTemplate + //isn't returning anything, but that's okay because I'm only concerned + //with the sql that was passed in. + } + assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1); + } + + public void testDefaultFindStep(){ + try{ + stepDao.findStep(job, "test"); + } + catch(NullPointerException ex){ + //It's going to throw a NullPointerException because the MockJdbcTemplate + //isn't returning anything, but that's okay because I'm only concerned + //with the sql that was passed in. + } + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1); + + } + + public void testDefaultFindSteps(){ + stepDao.findSteps(new Long(1)); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1); + } + + public void testDefaultCreateStep(){ + stepIncrementer.nextLongValue(); + stepIncrementerControl.setReturnValue(1); + stepIncrementerControl.replay(); + stepDao.createStep(job, "test"); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1); + } + + public void testDefaultUpdateStep(){ + stepDao.update(step); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1); + } + + public void testDefaultFindStepExecutions(){ + stepDao.findStepExecutions(step); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1); + } + + public void testDefaultSaveStepExecution(){ + stepExecutionIncrementer.nextLongValue(); + stepExecutionIncrementerControl.setReturnValue(1); + stepExecutionIncrementerControl.replay(); + stepDao.save(stepExecution); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1); + } + + public void testDefaultUpdateStepExecution(){ + stepDao.update(stepExecution); + assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1); + } +}