BATCH-1797 - implementation of SQL 'wildcard' search in JobInstanceDao

This commit is contained in:
willschipp
2013-09-08 10:54:03 -04:00
committed by Chris Schaefer
parent 5599c5e469
commit aef4db98b8
7 changed files with 107 additions and 2 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.batch.item.ExecutionContext;
*
* @author Dave Syer
* @author Michael Minella
*
* @author Will Schipp
* @since 2.0
*/
public interface JobExplorer {
@@ -108,6 +108,17 @@ public interface JobExplorer {
* @return the set of job names that have been executed
*/
List<String> getJobNames();
/**
* Fetch {@link JobInstance} values in descending order of creation (and
* there for usually of first execution) with a 'like'/wildcard criteria.
*
* @param jobName
* @param start
* @param count
* @return
*/
List<JobInstance> getJobInstancesByJobName(String jobName, int start, int count);
/**
* Query the repository for the number of unique {@link JobInstance}s

View File

@@ -35,6 +35,7 @@ import org.springframework.batch.core.repository.dao.StepExecutionDao;
* @author Dave Syer
* @author Lucas Ward
* @author Michael Minella
* @author Will Schipp
*
* @see JobExplorer
* @see JobInstanceDao
@@ -195,7 +196,6 @@ public class SimpleJobExplorer implements JobExplorer {
* requires JobParameters) plus StepExecutions
*/
private void getJobExecutionDependencies(JobExecution jobExecution) {
JobInstance jobInstance = jobInstanceDao.getJobInstance(jobExecution);
stepExecutionDao.addStepExecutions(jobExecution);
jobExecution.setJobInstance(jobInstance);
@@ -208,4 +208,9 @@ public class SimpleJobExplorer implements JobExplorer {
stepExecution.setExecutionContext(ecDao.getExecutionContext(stepExecution));
}
}
@Override
public List<JobInstance> getJobInstancesByJobName(String jobName, int start, int count) {
return jobInstanceDao.findJobInstancesByName(jobName, start, count);
}
}

View File

@@ -50,10 +50,15 @@ import org.springframework.util.StringUtils;
* @author Dave Syer
* @author Robert Kasanicky
* @author Michael Minella
* @author Will Schipp
*/
public class JdbcJobInstanceDao extends AbstractJdbcBatchMetadataDao implements
JobInstanceDao, InitializingBean {
private static final String STAR_WILDCARD = "*";
private static final String SQL_WILDCARD = "%";
private static final String CREATE_JOB_INSTANCE = "INSERT into %PREFIX%JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION)"
+ " values (?, ?, ?, ?)";
@@ -74,6 +79,8 @@ JobInstanceDao, InitializingBean {
private static final String FIND_JOB_NAMES = "SELECT distinct JOB_NAME from %PREFIX%JOB_INSTANCE order by JOB_NAME";
private static final String FIND_LAST_JOBS_BY_NAME = "SELECT JOB_INSTANCE_ID, JOB_NAME from %PREFIX%JOB_INSTANCE where JOB_NAME = ? order by JOB_INSTANCE_ID desc";
private static final String FIND_LAST_JOBS_LIKE_NAME = "SELECT JOB_INSTANCE_ID, JOB_NAME from %PREFIX%JOB_INSTANCE where JOB_NAME like ? order by JOB_INSTANCE_ID desc";
private DataFieldMaxValueIncrementer jobIncrementer;
@@ -296,4 +303,42 @@ JobInstanceDao, InitializingBean {
return jobInstance;
}
}
@Override
public List<JobInstance> findJobInstancesByName(String jobName,final int start,
final int count) {
@SuppressWarnings("rawtypes")
ResultSetExtractor extractor = new ResultSetExtractor() {
private List<JobInstance> list = new ArrayList<JobInstance>();
@Override
public Object extractData(ResultSet rs) throws SQLException,
DataAccessException {
int rowNum = 0;
while (rowNum < start && rs.next()) {
rowNum++;
}
while (rowNum < start + count && rs.next()) {
ParameterizedRowMapper<JobInstance> rowMapper = new JobInstanceRowMapper();
list.add(rowMapper.mapRow(rs, rowNum));
rowNum++;
}
return list;
}
};
//check if the name contains a wildcard
if (jobName.contains(STAR_WILDCARD)) {
//swap for sql wildcard
jobName = jobName.replaceAll("\\" + STAR_WILDCARD, SQL_WILDCARD);
}//end if
@SuppressWarnings("unchecked")
List<JobInstance> result = (List<JobInstance>) getJdbcTemplate().query(getQuery(FIND_LAST_JOBS_LIKE_NAME),
new Object[] { jobName }, extractor);
return result;
}
}

View File

@@ -79,6 +79,9 @@ public interface JobInstanceDao {
* Fetch the last job instances with the provided name, sorted backwards by
* primary key.
*
* if using the JdbcJobInstance, you can provide the jobName with a wildcard
* (e.g. *Job) to return 'like' job names. (e.g. *Job will return 'someJob'
* and 'otherJob')
*
* @param jobName the job name
* @param start the start index of the instances to return
@@ -93,6 +96,17 @@ public interface JobInstanceDao {
* @return the names of all job instances
*/
List<String> getJobNames();
/**
* Fetch the last job instances with the provided name, sorted backwards by
* primary key, using a 'like' criteria
*
* @param jobName
* @param start
* @param count
* @return
*/
List<JobInstance> findJobInstancesByName(String jobName, int start, int count);
/**

View File

@@ -132,4 +132,9 @@ public class MapJobInstanceDao implements JobInstanceDao {
return count;
}
}
@Override
public List<JobInstance> findJobInstancesByName(String jobName, int start, int count) {
return getJobInstances(jobName,start,count);
}
}

View File

@@ -486,6 +486,11 @@ public class CommandLineJobRunnerTests {
throw new UnsupportedOperationException();
}
@Override
public List<JobInstance> getJobInstancesByJobName(String jobName, int start, int count) {
throw new UnsupportedOperationException();
}
@Override
public int getJobInstanceCount(String jobName)
throws NoSuchJobException {

View File

@@ -16,9 +16,11 @@
package org.springframework.batch.core.repository.dao;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.List;
import javax.sql.DataSource;
@@ -86,4 +88,22 @@ public class JdbcJobInstanceDaoTests extends AbstractJobInstanceDaoTests {
assertEquals("Wrong hash: " + value, 32, value.length());
assertEquals(value, output.toString());
}
@Test
public void testJobInstanceWildcard() {
//look up a job using a wildcard (* substituted to %)
// unrelated job instance that should be ignored by the query
dao.createJobInstance("anotherJob", new JobParameters());
// we need two instances of the same job to check ordering
dao.createJobInstance("someJob", new JobParameters());
//now look for them
List<JobInstance> jobInstances = dao.findJobInstancesByName("*Job", 0, 2);
assertEquals(2, jobInstances.size());
for (JobInstance instance : jobInstances) {
assertTrue(instance.getJobName().contains("Job"));
}//end for
//try with after wildcards
jobInstances = dao.getJobInstances("Job*", 0, 2);
assertTrue(jobInstances.isEmpty());
}
}