diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/Db2PagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/Db2PagingQueryProvider.java index f29f86819..660eb430b 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/Db2PagingQueryProvider.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/Db2PagingQueryProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 the original author or authors. + * Copyright 2006-2024 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. @@ -27,7 +27,7 @@ import org.springframework.util.StringUtils; * @author Mahmoud Ben Hassine * @since 2.0 */ -public class Db2PagingQueryProvider extends SqlWindowingPagingQueryProvider { +public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider { @Override public String generateFirstPageQuery(int pageSize) { @@ -44,11 +44,6 @@ public class Db2PagingQueryProvider extends SqlWindowingPagingQueryProvider { } } - @Override - protected Object getSubQueryAlias() { - return "AS TMP_SUB "; - } - private String buildLimitClause(int pageSize) { return new StringBuilder().append("FETCH FIRST ").append(pageSize).append(" ROWS ONLY").toString(); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DerbyPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DerbyPagingQueryProvider.java index b2f4ab422..015454f90 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DerbyPagingQueryProvider.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DerbyPagingQueryProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 the original author or authors. + * Copyright 2006-2024 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. @@ -16,76 +16,37 @@ package org.springframework.batch.item.database.support; -import java.sql.DatabaseMetaData; -import javax.sql.DataSource; - import org.springframework.batch.item.database.PagingQueryProvider; -import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.util.StringUtils; /** - * Derby implementation of a {@link PagingQueryProvider} using standard SQL:2003 windowing - * functions. These features are supported starting with Apache Derby version 10.4.1.3. - *
- * As the OVER() function does not support the ORDER BY clause a sub query is instead used
- * to order the results before the ROW_NUM restriction is applied
+ * Derby implementation of a {@link PagingQueryProvider} using database specific features.
*
* @author Thomas Risberg
* @author David Thexton
* @author Michael Minella
+ * @author Henning Pöttker
* @since 2.0
*/
-public class DerbyPagingQueryProvider extends SqlWindowingPagingQueryProvider {
-
- private static final String MINIMAL_DERBY_VERSION = "10.4.1.3";
+public class DerbyPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
- public void init(DataSource dataSource) throws Exception {
- super.init(dataSource);
- String version = JdbcUtils.extractDatabaseMetaData(dataSource, DatabaseMetaData::getDatabaseProductVersion);
- if (!isDerbyVersionSupported(version)) {
- throw new InvalidDataAccessResourceUsageException(
- "Apache Derby version " + version + " is not supported by this class, Only version "
- + MINIMAL_DERBY_VERSION + " or later is supported");
+ public String generateFirstPageQuery(int pageSize) {
+ return SqlPagingQueryUtils.generateLimitSqlQuery(this, false, buildLimitClause(pageSize));
+ }
+
+ @Override
+ public String generateRemainingPagesQuery(int pageSize) {
+ if (StringUtils.hasText(getGroupClause())) {
+ return SqlPagingQueryUtils.generateLimitGroupedSqlQuery(this, buildLimitClause(pageSize));
+ }
+ else {
+ return SqlPagingQueryUtils.generateLimitSqlQuery(this, true, buildLimitClause(pageSize));
}
}
- // derby version numbering is M.m.f.p [ {alpha|beta} ] see
- // https://db.apache.org/derby/papers/versionupgrade.html#Basic+Numbering+Scheme
- private boolean isDerbyVersionSupported(String version) {
- String[] minimalVersionParts = MINIMAL_DERBY_VERSION.split("\\.");
- String[] versionParts = version.split("[\\. ]");
- for (int i = 0; i < minimalVersionParts.length; i++) {
- int minimalVersionPart = Integer.parseInt(minimalVersionParts[i]);
- int versionPart = Integer.parseInt(versionParts[i]);
- if (versionPart < minimalVersionPart) {
- return false;
- }
- else if (versionPart > minimalVersionPart) {
- return true;
- }
- }
- return true;
- }
-
- @Override
- protected String getOrderedQueryAlias() {
- return "TMP_ORDERED";
- }
-
- @Override
- protected String getOverClause() {
- return "";
- }
-
- @Override
- protected String getOverSubstituteClauseStart() {
- return " FROM (SELECT " + getSelectClause();
- }
-
- @Override
- protected String getOverSubstituteClauseEnd() {
- return " ) AS " + getOrderedQueryAlias();
+ private String buildLimitClause(int pageSize) {
+ return new StringBuilder("FETCH FIRST ").append(pageSize).append(" ROWS ONLY").toString();
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProvider.java
index 51b879ed2..b1c79763b 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProvider.java
@@ -28,7 +28,7 @@ import org.springframework.util.StringUtils;
* @author Mahmoud Ben Hassine
* @since 2.0
*/
-public class SqlServerPagingQueryProvider extends SqlWindowingPagingQueryProvider {
+public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String generateFirstPageQuery(int pageSize) {
@@ -45,11 +45,6 @@ public class SqlServerPagingQueryProvider extends SqlWindowingPagingQueryProvide
}
}
- @Override
- protected Object getSubQueryAlias() {
- return "AS TMP_SUB ";
- }
-
private String buildTopClause(int pageSize) {
return new StringBuilder().append("TOP ").append(pageSize).toString();
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java
index 1f75726aa..00e0d0471 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2023 the original author or authors.
+ * Copyright 2006-2024 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.
@@ -26,7 +26,9 @@ import org.springframework.util.StringUtils;
* @author Thomas Risberg
* @author Michael Minella
* @since 2.0
+ * @deprecated since 5.2.1 with no replacement. Scheduled for removal in 6.0.
*/
+@Deprecated(forRemoval = true)
public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SybasePagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SybasePagingQueryProvider.java
index af6916913..ade0af526 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SybasePagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SybasePagingQueryProvider.java
@@ -28,7 +28,7 @@ import org.springframework.util.StringUtils;
* @author Mahmoud Ben Hassine
* @since 2.0
*/
-public class SybasePagingQueryProvider extends SqlWindowingPagingQueryProvider {
+public class SybasePagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String generateFirstPageQuery(int pageSize) {
@@ -45,11 +45,6 @@ public class SybasePagingQueryProvider extends SqlWindowingPagingQueryProvider {
}
}
- @Override
- protected Object getSubQueryAlias() {
- return "";
- }
-
private String buildTopClause(int pageSize) {
return new StringBuilder().append("TOP ").append(pageSize).toString();
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderIntegrationTests.java
new file mode 100644
index 000000000..fb3820c61
--- /dev/null
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderIntegrationTests.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2024 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.batch.item.database.support;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.batch.item.database.Order;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author Henning Pöttker
+ */
+class DerbyPagingQueryProviderIntegrationTests {
+
+ private static EmbeddedDatabase embeddedDatabase;
+
+ private static JdbcTemplate jdbcTemplate;
+
+ @BeforeAll
+ static void setUp() {
+ embeddedDatabase = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.DERBY)
+ .addScript("/org/springframework/batch/item/database/support/query-provider-fixture.sql")
+ .generateUniqueName(true)
+ .build();
+ jdbcTemplate = new JdbcTemplate(embeddedDatabase);
+ }
+
+ @AfterAll
+ static void tearDown() {
+ if (embeddedDatabase != null) {
+ embeddedDatabase.shutdown();
+ }
+ }
+
+ @Test
+ void testWithoutGrouping() {
+ var queryProvider = new DerbyPagingQueryProvider();
+ queryProvider.setSelectClause("ID, STRING");
+ queryProvider.setFromClause("TEST_TABLE");
+ Map