Add tablePrefix feature to SqlStepDao.

REOPENED - issue BATCH-93: Need to be able to configure table names! 
http://opensource.atlassian.com/projects/spring/browse/BATCH-93
This commit is contained in:
dsyer
2007-08-28 20:35:02 +00:00
parent 97e6d74dd5
commit b03caffc42
4 changed files with 245 additions and 20 deletions

View File

@@ -53,7 +53,7 @@ public class SqlJobDao implements JobDao, InitializingBean {
*/
public static final String DEFAULT_TABLE_PREFIX = "BATCH_";
private static String tablePrefix = DEFAULT_TABLE_PREFIX;
private String tablePrefix = DEFAULT_TABLE_PREFIX;
// Job SQL statements
private static final String CREATE_JOB = "INSERT into %PREFIX%JOB(ID, JOB_NAME, JOB_STREAM, SCHEDULE_DATE, JOB_RUN)"
@@ -94,7 +94,7 @@ public class SqlJobDao implements JobDao, InitializingBean {
* the tablePrefix to set
*/
public void setTablePrefix(String tablePrefix) {
SqlJobDao.tablePrefix = tablePrefix;
this.tablePrefix = tablePrefix;
}
/**

View File

@@ -34,6 +34,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Sql implementation of StepDao. Uses Sequences (via Spring's
@@ -54,27 +55,27 @@ import org.springframework.util.Assert;
public class SqlStepDao implements StepDao, InitializingBean {
// Step SQL statements
private static final String FIND_STEPS = "SELECT ID, STEP_NAME, STATUS, RESTART_DATA from BATCH_STEP where JOB_ID = ?";
private static final String FIND_STEPS = "SELECT ID, STEP_NAME, STATUS, RESTART_DATA from %PREFIX%STEP where JOB_ID = ?";
private static final String FIND_STEP = "SELECT ID, STATUS, RESTART_DATA from BATCH_STEP where JOB_ID = ? "
private static final String FIND_STEP = "SELECT ID, STATUS, RESTART_DATA from %PREFIX%STEP where JOB_ID = ? "
+ "and STEP_NAME = ?";
private static final String CREATE_STEP = "INSERT into BATCH_STEP(ID, JOB_ID, STEP_NAME) values (?, ?, ?)";
private static final String CREATE_STEP = "INSERT into %PREFIX%STEP(ID, JOB_ID, STEP_NAME) values (?, ?, ?)";
private static final String UPDATE_STEP = "UPDATE BATCH_STEP set STATUS = ?, RESTART_DATA = ? where ID = ?";
private static final String UPDATE_STEP = "UPDATE %PREFIX%STEP set STATUS = ?, RESTART_DATA = ? where ID = ?";
// StepExecution statements
private static final String SAVE_STEP_EXECUTION = "INSERT into BATCH_STEP_EXECUTION(ID, VERSION, STEP_ID, JOB_EXECUTION_ID, START_TIME, "
private static final String SAVE_STEP_EXECUTION = "INSERT into %PREFIX%STEP_EXECUTION(ID, VERSION, STEP_ID, JOB_EXECUTION_ID, START_TIME, "
+ "END_TIME, STATUS, COMMIT_COUNT, TASK_COUNT, TASK_STATISTICS, EXIT_CODE) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String UPDATE_STEP_EXECUTION = "UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, "
private static final String UPDATE_STEP_EXECUTION = "UPDATE %PREFIX%STEP_EXECUTION set START_TIME = ?, END_TIME = ?, "
+ "STATUS = ?, COMMIT_COUNT = ?, TASK_COUNT = ?, TASK_STATISTICS = ?, EXIT_CODE = ? where ID = ?";
private static final String GET_STEP_EXECUTION_COUNT = "SELECT count(ID) from BATCH_STEP_EXECUTION where "
private static final String GET_STEP_EXECUTION_COUNT = "SELECT count(ID) from %PREFIX%STEP_EXECUTION where "
+ "STEP_ID = ?";
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 BATCH_STEP_EXECUTION where STEP_ID = ?";
+ " TASK_COUNT, TASK_STATISTICS, EXIT_CODE from %PREFIX%STEP_EXECUTION where STEP_ID = ?";
private JdbcTemplate jdbcTemplate;
@@ -82,6 +83,20 @@ public class SqlStepDao implements StepDao, InitializingBean {
private DataFieldMaxValueIncrementer stepExecutionIncrementer;
private String tablePrefix = SqlJobDao.DEFAULT_TABLE_PREFIX;
/**
* Public setter for the table prefix property. This will be prefixed to all
* the table names before queries are executed. Defaults to
* {@value #DEFAULT_TABLE_PREFIX}.
*
* @param tablePrefix
* the tablePrefix to set
*/
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
/**
* Find one step for given job and stepName. A RowMapper is used to map each
* row returned to a step object. If none are found, the list will be empty
@@ -113,7 +128,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
};
List steps = jdbcTemplate.query(FIND_STEP, parameters, rowMapper);
List steps = jdbcTemplate.query(getQuery(FIND_STEP), parameters, rowMapper);
if (steps.size() == 0) {
// No step found
@@ -138,7 +153,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
* @see StepDao#findSteps(Long)
*
* Sql implementation which uses a RowMapper to populate a list of all rows
* in the BATCH_STEP table with the same JOB_ID.
* in the step table with the same JOB_ID.
*
* @throws IllegalArgumentException if jobId is null.
*/
@@ -162,7 +177,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
}
};
return jdbcTemplate.query(FIND_STEPS, parameters, rowMapper);
return jdbcTemplate.query(getQuery(FIND_STEPS), parameters, rowMapper);
}
/**
@@ -180,7 +195,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
Long stepId = new Long(stepIncrementer.nextLongValue());
Object[] parameters = new Object[] { stepId, job.getId(), stepName };
jdbcTemplate.update(CREATE_STEP, parameters);
jdbcTemplate.update(getQuery(CREATE_STEP), parameters);
StepInstance step = new StepInstance(stepId);
step.setJob(job);
@@ -209,7 +224,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
step.getId()
};
jdbcTemplate.update(UPDATE_STEP, parameters);
jdbcTemplate.update(getQuery(UPDATE_STEP), parameters);
}
/**
@@ -228,7 +243,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
stepExecution.getStartTime(), stepExecution.getEndTime(), stepExecution.getStatus().toString(),
stepExecution.getCommitCount(), stepExecution.getTaskCount(),
PropertiesConverter.propertiesToString(stepExecution.getStatistics()), stepExecution.getExitCode() };
jdbcTemplate.update(SAVE_STEP_EXECUTION, parameters);
jdbcTemplate.update(getQuery(SAVE_STEP_EXECUTION), parameters);
}
@@ -254,7 +269,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
stepExecution.getTaskCount(), PropertiesConverter.propertiesToString(stepExecution.getStatistics()),
stepExecution.getExitCode(),
stepExecution.getId() };
jdbcTemplate.update(UPDATE_STEP_EXECUTION, parameters);
jdbcTemplate.update(getQuery(UPDATE_STEP_EXECUTION), parameters);
}
@@ -262,7 +277,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
Object[] parameters = new Object[] { stepId };
return jdbcTemplate.queryForInt(GET_STEP_EXECUTION_COUNT, parameters);
return jdbcTemplate.queryForInt(getQuery(GET_STEP_EXECUTION_COUNT), parameters);
}
/**
@@ -297,7 +312,7 @@ public class SqlStepDao implements StepDao, InitializingBean {
}
};
return jdbcTemplate.query(FIND_STEP_EXECUTIONS, new Object[] { stepId }, rowMapper);
return jdbcTemplate.query(getQuery(FIND_STEP_EXECUTIONS), new Object[] { stepId }, rowMapper);
}
@@ -319,6 +334,10 @@ public class SqlStepDao implements StepDao, InitializingBean {
Assert.notNull(stepExecutionIncrementer, "StepExecutionIncrementer canot be null.");
}
private String getQuery(String base) {
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
}
/*
* Validate StepExecution. At a minimum, JobId, StartTime, and
* Status cannot be null. EndTime can be null for an unfinished job.

View File

@@ -0,0 +1,206 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.execution.repository.dao;
import java.sql.Timestamp;
import java.util.List;
import java.util.Properties;
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.batch.core.runtime.JobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.util.ClassUtils;
/**
* Test for StepDao. Because it is very reasonable to assume that there is a
* foreign key constraint on the JobId of a step, the JobDao is used to create
* jobs, to have an id for creating steps.
*
* @author Lucas Ward
*/
public class BaseStepDaoTests extends AbstractTransactionalDataSourceSpringContextTests {
protected JobDao jobDao;
protected StepDao stepDao;
protected JobInstance job;
protected StepInstance step1;
protected StepInstance step2;
protected StepExecution stepExecution;
public void setJobDao(JobDao jobDao) {
this.jobDao = jobDao;
}
public void setStepDao(StepDao stepDao) {
this.stepDao = stepDao;
}
/*
* (non-Javadoc)
* @see org.springframework.test.AbstractSingleSpringContextTests#getConfigLocations()
*/
protected String[] getConfigLocations() {
return new String[] { ClassUtils.addResourcePathToPackagePath(getClass(), "sql-dao-test.xml") };
}
/*
* (non-Javadoc)
* @see org.springframework.test.AbstractTransactionalSpringContextTests#onSetUpInTransaction()
*/
protected void onSetUpInTransaction() throws Exception {
JobIdentifier jobIdentifier = new ScheduledJobIdentifier("TestJob");
job = jobDao.createJob(jobIdentifier);
step1 = stepDao.createStep(job, "TestStep1");
step2 = stepDao.createStep(job, "TestStep2");
stepExecution = new StepExecution(step1.getId(), new Long(23));
stepExecution.setStatus(BatchStatus.STARTED);
stepExecution.setStartTime(new Timestamp(System.currentTimeMillis()));
stepDao.save(stepExecution);
}
public void testVersionIsNotNullForStep() throws Exception {
int version = jdbcTemplate.queryForInt("select version from BATCH_STEP where ID="+step1.getId());
assertEquals(0, version);
}
public void testVersionIsNotNullForStepExecution() throws Exception {
int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_EXECUTION where ID="+stepExecution.getId());
assertEquals(0, version);
}
public void testFindStepNull(){
StepInstance step = stepDao.findStep(job, "UnSavedStep");
assertNull(step);
}
public void testFindStep(){
StepInstance tempStep = stepDao.findStep(job, "TestStep1");
assertEquals(tempStep, step1);
}
public void testFindSteps(){
List steps = stepDao.findSteps(job.getId());
assertEquals(steps.size(), 2);
assertTrue(steps.contains(step1));
assertTrue(steps.contains(step2));
}
public void testFindStepsNotSaved(){
//no steps are saved for given id, empty list should be returned
List steps = stepDao.findSteps(new Long(38922));
assertEquals(steps.size(), 0);
}
public void testCreateStep(){
StepInstance step3 = stepDao.createStep(job, "TestStep3");
StepInstance tempStep = stepDao.findStep(job, "TestStep3");
assertEquals(step3, tempStep);
}
public void testUpdateStepWithoutRestartData(){
step1.setStatus(BatchStatus.COMPLETED);
stepDao.update(step1);
StepInstance tempStep = stepDao.findStep(job, step1.getName());
assertEquals(tempStep, step1);
}
public void testUpdateStepWithRestartData(){
step1.setStatus(BatchStatus.COMPLETED);
Properties data = new Properties();
data.setProperty("restart.key1", "restartData");
RestartData restartData = new GenericRestartData(data);
step1.setRestartData(restartData);
stepDao.update(step1);
StepInstance tempStep = stepDao.findStep(job, step1.getName());
assertEquals(tempStep, step1);
assertEquals(tempStep.getRestartData().getProperties().toString(),
restartData.getProperties().toString());
}
public void testSaveStepExecution(){
StepExecution execution = new StepExecution(step2.getId(), new Long(10));
execution.setStatus(BatchStatus.STARTED);
execution.setStartTime(new Timestamp(System.currentTimeMillis()));
Properties statistics = new Properties();
statistics.setProperty("statistic.key1", "0");
statistics.setProperty("statistic.key2", "5");
execution.setStatistics(statistics);
stepDao.save(execution);
List executions = stepDao.findStepExecutions(step2);
assertEquals(1, executions.size());
StepExecution tempExecution = (StepExecution)executions.get(0);
assertEquals(execution, tempExecution);
assertEquals(execution.getStatistics(), tempExecution.getStatistics());
}
public void testUpdateStepExecution(){
stepExecution.setStatus(BatchStatus.COMPLETED);
stepExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
stepExecution.setCommitCount(5);
stepExecution.setTaskCount(5);
stepExecution.setStatistics(new Properties());
stepDao.update(stepExecution);
List executions = stepDao.findStepExecutions(step1);
assertEquals(1, executions.size());
assertEquals(stepExecution, (StepExecution)executions.get(0));
}
public void testUpdateStepExecutionWithNullId(){
StepExecution stepExecution = new StepExecution(null, null);
try{
stepDao.update(stepExecution);
fail();
}catch(IllegalArgumentException ex){
//expected
}
}
public void testGetStepExecutionCountForNoExecutions(){
int executionCount = stepDao.getStepExecutionCount(step2.getId());
assertEquals(executionCount, 0);
}
public void testIncrementStepExecutionCount(){
assertEquals(1, stepDao.getStepExecutionCount(step1.getId()));
StepExecution execution = new StepExecution(step1.getId(), new Long(9));
stepDao.save(execution);
assertEquals(2, stepDao.getStepExecutionCount(step1.getId()));
}
}

View File

@@ -24,7 +24,7 @@ import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.util.ClassUtils;
public class HibernateStepDaoTests extends SqlStepDaoTests {
public class HibernateStepDaoTests extends BaseStepDaoTests {
private SessionFactory sessionFactory;