update db2 'between' logic to be exclusive Signed-off-by: Ryan DCruz <rd@enfuse.io> use .acceptLicense() instead of the classpath file checkstyle add test to verify a result set that's smaller than requested page size cleanup
This commit is contained in:
committed by
Glenn Renfro
parent
62cccc2727
commit
fc89e23144
@@ -24,6 +24,7 @@ import org.springframework.data.domain.Pageable;
|
||||
* database specific features.
|
||||
*
|
||||
* @author Thomas Schuettel
|
||||
* @author Ryan DCruz
|
||||
*/
|
||||
public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
|
||||
@@ -31,8 +32,7 @@ public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
public String getPageQuery(Pageable pageable) {
|
||||
long offset = pageable.getOffset() + 1;
|
||||
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
|
||||
"TMP_ROW_NUM BETWEEN " + offset + " AND "
|
||||
+ (offset + pageable.getPageSize()));
|
||||
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < " + (offset + pageable.getPageSize()));
|
||||
}
|
||||
|
||||
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
||||
|
||||
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Glenn Renfro
|
||||
* @author Ryan DCruz
|
||||
*/
|
||||
public class FindAllPagingQueryProviderTests {
|
||||
|
||||
@@ -66,7 +67,16 @@ public class FindAllPagingQueryProviderTests {
|
||||
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
|
||||
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION) TASK_EXECUTION_PAGE "
|
||||
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, "
|
||||
+ "TASK_EXECUTION_ID DESC" } });
|
||||
+ "TASK_EXECUTION_ID DESC" },
|
||||
{ "DB2/Linux",
|
||||
"SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
|
||||
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
|
||||
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROW_NUMBER() "
|
||||
+ "OVER() as TMP_ROW_NUM FROM "
|
||||
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, "
|
||||
+ "EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM %PREFIX%EXECUTION ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC)) "
|
||||
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11"}});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<test.containers.version>1.16.3</test.containers.version>
|
||||
<test.rabbit.containers.version>1.16.3</test.rabbit.containers.version>
|
||||
<test.ducttape.version>1.0.8</test.ducttape.version>
|
||||
<db2-jdbc.version>11.5.7.0</db2-jdbc.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -28,6 +29,13 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers-bom</artifactId>
|
||||
<version>${test.containers.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -103,12 +111,29 @@
|
||||
<version>${test.containers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>rabbitmq</artifactId>
|
||||
<version>${test.rabbit.containers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>db2</artifactId>
|
||||
<version>${test.containers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.db2</groupId>
|
||||
<artifactId>jcc</artifactId>
|
||||
<version>${db2-jdbc.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.rnorth.duct-tape</groupId>
|
||||
<artifactId>duct-tape</artifactId>
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2015-2022 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
|
||||
*
|
||||
* https://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.cloud.task.database.support.db2;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.Db2Container;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.cloud.task.executionid.TaskStartApplication;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
import org.springframework.cloud.task.repository.dao.TaskExecutionDao;
|
||||
import org.springframework.cloud.task.repository.database.support.Db2PagingQueryProvider;
|
||||
import org.springframework.cloud.task.repository.support.SimpleTaskExplorer;
|
||||
import org.springframework.cloud.task.repository.support.TaskExecutionDaoFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.context.jdbc.SqlConfig.ErrorMode.CONTINUE_ON_ERROR;
|
||||
|
||||
/**
|
||||
* @author Tyler Carpenter-Rivers
|
||||
* @author Ryan DCruz
|
||||
* @see Db2PagingQueryProvider
|
||||
*/
|
||||
@SpringBootTest(
|
||||
classes = {TaskStartApplication.class, Db2PagingQueryProviderTest.TestConfig.class},
|
||||
properties = "spring.cloud.task.events.enabled=false"
|
||||
)
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
@DirtiesContext
|
||||
@Sql(
|
||||
scripts = "classpath:/org/springframework/cloud/task/schema-db2.sql",
|
||||
config = @SqlConfig(errorMode = CONTINUE_ON_ERROR)
|
||||
)
|
||||
@Sql(statements = {
|
||||
" DELETE FROM TASK_EXECUTION_PARAMS ",
|
||||
" DELETE FROM TASK_TASK_BATCH ",
|
||||
" DELETE FROM TASK_EXECUTION "
|
||||
})
|
||||
class Db2PagingQueryProviderTest {
|
||||
|
||||
@Container
|
||||
public static Db2Container db2Container =
|
||||
new Db2Container(DockerImageName.parse("ibmcom/db2:11.5.7.0"))
|
||||
.acceptLicense()
|
||||
.withDatabaseName("test")
|
||||
.withStartupTimeoutSeconds(30)
|
||||
.withExposedPorts(50000);
|
||||
|
||||
@DynamicPropertySource
|
||||
static void properties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.datasource.url", db2Container::getJdbcUrl);
|
||||
registry.add("spring.datasource.username", db2Container::getUsername);
|
||||
registry.add("spring.datasource.password", db2Container::getPassword);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SimpleTaskExplorer simpleTaskExplorer;
|
||||
|
||||
@Autowired
|
||||
private TaskExecutionDao taskExecutionDao;
|
||||
|
||||
@DisplayName("Scenario: The page request size is less than the total number of elements" +
|
||||
"Given the total number of elements is 3" +
|
||||
"And the page request size is 2" +
|
||||
"When the query is executed" +
|
||||
"Then the returned page has 2 elements")
|
||||
@Test
|
||||
void pageRequest() {
|
||||
// setup test data
|
||||
taskExecutionDao.createTaskExecution(
|
||||
UUID.randomUUID().toString(), new Date(), List.of(), UUID.randomUUID().toString());
|
||||
taskExecutionDao.createTaskExecution(
|
||||
UUID.randomUUID().toString(), new Date(), List.of(), UUID.randomUUID().toString());
|
||||
taskExecutionDao.createTaskExecution(
|
||||
UUID.randomUUID().toString(), new Date(), List.of(), UUID.randomUUID().toString());
|
||||
|
||||
PageRequest pageRequest = PageRequest.of(0, 2);
|
||||
|
||||
// run subject under test
|
||||
Page<TaskExecution> page = simpleTaskExplorer.findAll(pageRequest);
|
||||
|
||||
// assert and verify
|
||||
assertThat(page.getTotalElements())
|
||||
.as("Expected the total number of records in the table to be 3")
|
||||
.isEqualTo(3);
|
||||
|
||||
assertThat(pageRequest.getPageSize())
|
||||
.as("Expected the size of the returned page to be 2")
|
||||
.isEqualTo(2);
|
||||
}
|
||||
|
||||
@DisplayName("Scenario: the page request size is larger than the total number of elements" +
|
||||
"Given the total number of elements is 1" +
|
||||
"And the page request size is 2" +
|
||||
"When the query is executed" +
|
||||
"Then the returned page has 1 element")
|
||||
@Test
|
||||
void pageRequestSinglePageEntries() {
|
||||
// setup test data
|
||||
taskExecutionDao.createTaskExecution(
|
||||
UUID.randomUUID().toString(), new Date(), List.of(), UUID.randomUUID().toString());
|
||||
|
||||
PageRequest pageRequest = PageRequest.of(0, 2);
|
||||
|
||||
// run subject under test
|
||||
Page<TaskExecution> page = simpleTaskExplorer.findAll(pageRequest);
|
||||
|
||||
// assert and verify
|
||||
assertThat(page.getTotalElements())
|
||||
.as("Should only have one record in the table")
|
||||
.isEqualTo(1);
|
||||
|
||||
assertThat(page.getNumberOfElements())
|
||||
.as("Should have one record in the returned page")
|
||||
.isEqualTo(1);
|
||||
|
||||
assertThat(page.getTotalPages())
|
||||
.as("Should expect the total number of pages to be 1")
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
public static class TestConfig {
|
||||
@Bean
|
||||
@ConfigurationProperties("spring.datasource")
|
||||
public DataSource dataSource() {
|
||||
return new DriverManagerDataSource();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean(DataSource dataSource) {
|
||||
return new TaskExecutionDaoFactoryBean(dataSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskExecutionDao taskExecutionDao(TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean) throws Exception {
|
||||
return taskExecutionDaoFactoryBean.getObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user