diff --git a/.project b/.project
new file mode 100644
index 0000000000..8300bf6f1c
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ spring-batch
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Nature
+
+
diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000000..86f52791da
--- /dev/null
+++ b/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,8 @@
+#Mon Feb 07 12:03:26 CET 2011
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/archetypes/.project b/archetypes/.project
new file mode 100644
index 0000000000..4ab6f5c621
--- /dev/null
+++ b/archetypes/.project
@@ -0,0 +1,17 @@
+
+
+ spring-batch-archetype
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Nature
+
+
diff --git a/archetypes/.settings/org.maven.ide.eclipse.prefs b/archetypes/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000000..86f52791da
--- /dev/null
+++ b/archetypes/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,8 @@
+#Mon Feb 07 12:03:26 CET 2011
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
index e20d4a3c00..7a58e6d857 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcPagingItemReader.java
@@ -37,35 +37,30 @@
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
/**
*
- * {@link org.springframework.batch.item.ItemReader} for reading database
- * records using JDBC in a paging fashion.
+ * {@link org.springframework.batch.item.ItemReader} for reading database records using JDBC in a paging fashion.
*
*
*
- * It executes the SQL built by the {@link PagingQueryProvider} to retrieve
- * requested data. The query is executed using paged requests of a size
- * specified in {@link #setPageSize(int)}. Additional pages are requested when
- * needed as {@link #read()} method is called, returning an object corresponding
- * to current position. On restart it uses the last sort key value to locate the
- * first page to read (so it doesn't matter if the successfully processed itmes
- * have been removed or modified).
+ * It executes the SQL built by the {@link PagingQueryProvider} to retrieve requested data. The query is executed using
+ * paged requests of a size specified in {@link #setPageSize(int)}. Additional pages are requested when needed as
+ * {@link #read()} method is called, returning an object corresponding to current position. On restart it uses the last
+ * sort key value to locate the first page to read (so it doesn't matter if the successfully processed itmes have been
+ * removed or modified).
*
*
*
- * The performance of the paging depends on the database specific features
- * available to limit the number of returned rows. Setting a fairly large page
- * size and using a commit interval that matches the page size should provide
- * better performance.
+ * The performance of the paging depends on the database specific features available to limit the number of returned
+ * rows. Setting a fairly large page size and using a commit interval that matches the page size should provide better
+ * performance.
*
*
*
- * The implementation is thread-safe in between calls to
- * {@link #open(ExecutionContext)}, but remember to use
- * saveState=false
if used in a multi-threaded client (no restart
- * available).
+ * The implementation is thread-safe in between calls to {@link #open(ExecutionContext)}, but remember to use
+ * saveState=false
if used in a multi-threaded client (no restart available).
*
*
* @author Thomas Risberg
@@ -108,12 +103,12 @@ public void setDataSource(DataSource dataSource) {
}
/**
- * Gives the JDBC driver a hint as to the number of rows that should be
- * fetched from the database when more rows are needed for this
- * ResultSet
object. If the fetch size specified is zero, the
- * JDBC driver ignores the value.
+ * Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are
+ * needed for this ResultSet
object. If the fetch size specified is zero, the JDBC driver ignores the
+ * value.
*
- * @param fetchSize the number of rows to fetch
+ * @param fetchSize
+ * the number of rows to fetch
* @see ResultSet#setFetchSize(int)
*/
public void setFetchSize(int fetchSize) {
@@ -121,37 +116,34 @@ public void setFetchSize(int fetchSize) {
}
/**
- * A {@link PagingQueryProvider}. Supplies all the platform dependent query
- * generation capabilities needed by the reader.
+ * A {@link PagingQueryProvider}. Supplies all the platform dependent query generation capabilities needed by the
+ * reader.
*
- * @param queryProvider the {@link PagingQueryProvider} to use
+ * @param queryProvider
+ * the {@link PagingQueryProvider} to use
*/
public void setQueryProvider(PagingQueryProvider queryProvider) {
this.queryProvider = queryProvider;
}
/**
- * The row mapper implementation to be used by this reader. The row mapper
- * is used to convert result set rows into objects, which are then returned
- * by the reader.
+ * The row mapper implementation to be used by this reader. The row mapper is used to convert result set rows into
+ * objects, which are then returned by the reader.
*
- * @param rowMapper a
- * {@link org.springframework.jdbc.core.simple.ParameterizedRowMapper}
- * implementation
+ * @param rowMapper
+ * a {@link org.springframework.jdbc.core.simple.ParameterizedRowMapper} implementation
*/
public void setRowMapper(RowMapper rowMapper) {
this.rowMapper = rowMapper;
}
/**
- * The parameter values to be used for the query execution. If you use named
- * parameters then the key should be the name used in the query clause. If
- * you use "?" placeholders then the key should be the relative index that
- * the parameter appears in the query string built using the select, from
- * and where clauses specified.
+ * The parameter values to be used for the query execution. If you use named parameters then the key should be the
+ * name used in the query clause. If you use "?" placeholders then the key should be the relative index that the
+ * parameter appears in the query string built using the select, from and where clauses specified.
*
- * @param parameterValues the values keyed by the parameter named/index used
- * in the query string.
+ * @param parameterValues
+ * the values keyed by the parameter named/index used in the query string.
*/
public void setParameterValues(Map parameterValues) {
this.parameterValues = parameterValues;
@@ -159,6 +151,7 @@ public void setParameterValues(Map parameterValues) {
/**
* Check mandatory properties.
+ *
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
@@ -181,8 +174,7 @@ protected void doReadPage() {
if (results == null) {
results = new CopyOnWriteArrayList();
- }
- else {
+ } else {
results.clear();
}
@@ -198,31 +190,27 @@ protected void doReadPage() {
if (this.queryProvider.isUsingNamedParameters()) {
query = simpleJdbcTemplate.getNamedParameterJdbcOperations().query(firstPageSql,
getParameterMap(parameterValues, null), rowCallback);
- }
- else {
+ } else {
query = simpleJdbcTemplate.getJdbcOperations().query(firstPageSql,
getParameterList(parameterValues, null).toArray(), rowCallback);
}
- }
- else {
+ } else {
query = simpleJdbcTemplate.getJdbcOperations().query(firstPageSql, rowCallback);
}
- }
- else {
+ } else {
if (logger.isDebugEnabled()) {
logger.debug("SQL used for reading remaining pages: [" + remainingPagesSql + "]");
}
if (this.queryProvider.isUsingNamedParameters()) {
query = simpleJdbcTemplate.getNamedParameterJdbcOperations().query(remainingPagesSql,
getParameterMap(parameterValues, startAfterValue), rowCallback);
- }
- else {
+ } else {
query = simpleJdbcTemplate.getJdbcOperations().query(remainingPagesSql,
getParameterList(parameterValues, startAfterValue).toArray(), rowCallback);
}
}
-
+
@SuppressWarnings("unchecked")
Collection result = (Collection) query;
results.addAll(result);
@@ -248,8 +236,7 @@ public void open(ExecutionContext executionContext) {
@Override
protected void doJumpToPage(int itemIndex) {
/*
- * Normally this would be false (the startAfterValue is enough
- * information to restart from.
+ * Normally this would be false (the startAfterValue is enough information to restart from.
*/
if (startAfterValue == null && getPage() > 0) {
@@ -268,8 +255,7 @@ public Object mapRow(ResultSet rs, int i) throws SQLException {
if (this.queryProvider.isUsingNamedParameters()) {
startAfterValue = simpleJdbcTemplate.getNamedParameterJdbcOperations().queryForObject(jumpToItemSql,
getParameterMap(parameterValues, startAfterValue), startMapper);
- }
- else {
+ } else {
startAfterValue = simpleJdbcTemplate.getJdbcOperations().queryForObject(jumpToItemSql,
getParameterList(parameterValues, startAfterValue).toArray(), startMapper);
}
@@ -309,7 +295,11 @@ private List getParameterList(Map values, Object sortKey
private class PagingRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
- startAfterValue = rs.getObject(queryProvider.getSortKey());
+ if (StringUtils.hasText(queryProvider.getSortKeyAlias())) {
+ startAfterValue = rs.getObject(queryProvider.getSortKeyAlias());
+ } else {
+ startAfterValue = rs.getObject(queryProvider.getSortKey());
+ }
return rowMapper.mapRow(rs, rowNum);
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/PagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/PagingQueryProvider.java
index 3a831ddea8..7e4dbc71b5 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/PagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/PagingQueryProvider.java
@@ -81,5 +81,7 @@ public interface PagingQueryProvider {
* @return the sort key used to order the query
*/
String getSortKey();
+
+ String getSortKeyAlias();
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
index 72615799cf..07f9ae5ead 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProvider.java
@@ -52,8 +52,12 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
private String fromClause;
private String whereClause;
+
+ private String groupClause;
private String sortKey;
+
+ private String sortKeyAlias;
private boolean ascending = true;
@@ -178,6 +182,9 @@ public void init(DataSource dataSource) throws Exception {
if (whereClause != null) {
sql.append(" WHERE ").append(whereClause);
}
+ if (groupClause != null) {
+ sql.append(" GROUP BY ").append(groupClause);
+ }
List namedParameters = new ArrayList();
parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);
if (namedParameters.size() > 0) {
@@ -228,4 +235,21 @@ private String removeKeyWord(String keyWord, String clause) {
}
}
+ public void setGroupClause(String groupClause) {
+ this.groupClause = groupClause;
+ }
+
+ public String getGroupClause() {
+ return groupClause;
+ }
+
+ public void setSortKeyAlias(String sortKeyAlias) {
+ this.sortKeyAlias = sortKeyAlias;
+ }
+
+ public String getSortKeyAlias() {
+ return sortKeyAlias;
+ }
+
+
}
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 c078e602b8..53264946dd 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
@@ -54,11 +54,16 @@ protected String getOverClause() {
@Override
protected String getAfterWhereClause() {
+ StringBuilder sql = new StringBuilder();
+ if (getGroupClause() != null) {
+ sql.append(" GROUP BY ").append(getGroupClause());
+ }
if (version!=null && "10.6.1".compareTo(version) > 0) {
// Old behaviour retained, even though it is broken
- return "";
+ return sql.toString();
}
- return " " + super.getOverClause();
+ sql.append(" ").append(super.getOverClause());
+ return sql.toString();
}
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
index 42ae64509f..eea1ea88c9 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryProviderFactoryBean.java
@@ -39,9 +39,8 @@
import org.springframework.util.StringUtils;
/**
- * Factory bean for {@link PagingQueryProvider} interface. The database type
- * will be determined from the data source if not provided explicitly. Valid
- * types are given by the {@link DatabaseType} enum.
+ * Factory bean for {@link PagingQueryProvider} interface. The database type will be determined from the data source if
+ * not provided explicitly. Valid types are given by the {@link DatabaseType} enum.
*
* @author Dave Syer
*/
@@ -57,63 +56,72 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
private String selectClause;
+ private String groupClause;
+
private String sortKey;
+
+ private String sortKeyAlias;
private boolean ascending = true;
private Map providers = new HashMap();
-
{
providers.put(DB2, new Db2PagingQueryProvider());
providers.put(DB2ZOS, new Db2PagingQueryProvider());
- providers.put(DERBY,new DerbyPagingQueryProvider());
- providers.put(HSQL,new HsqlPagingQueryProvider());
- providers.put(H2,new H2PagingQueryProvider());
- providers.put(MYSQL,new MySqlPagingQueryProvider());
- providers.put(ORACLE,new OraclePagingQueryProvider());
- providers.put(POSTGRES,new PostgresPagingQueryProvider());
- providers.put(SQLSERVER,new SqlServerPagingQueryProvider());
- providers.put(SYBASE,new SybasePagingQueryProvider());
+ providers.put(DERBY, new DerbyPagingQueryProvider());
+ providers.put(HSQL, new HsqlPagingQueryProvider());
+ providers.put(H2, new H2PagingQueryProvider());
+ providers.put(MYSQL, new MySqlPagingQueryProvider());
+ providers.put(ORACLE, new OraclePagingQueryProvider());
+ providers.put(POSTGRES, new PostgresPagingQueryProvider());
+ providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
+ providers.put(SYBASE, new SybasePagingQueryProvider());
}
/**
- * @param databaseType the databaseType to set
+ * @param databaseType
+ * the databaseType to set
*/
public void setDatabaseType(String databaseType) {
this.databaseType = databaseType;
}
/**
- * @param dataSource the dataSource to set
+ * @param dataSource
+ * the dataSource to set
*/
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
- * @param fromClause the fromClause to set
+ * @param fromClause
+ * the fromClause to set
*/
public void setFromClause(String fromClause) {
this.fromClause = fromClause;
}
/**
- * @param whereClause the whereClause to set
+ * @param whereClause
+ * the whereClause to set
*/
public void setWhereClause(String whereClause) {
this.whereClause = whereClause;
}
/**
- * @param selectClause the selectClause to set
+ * @param selectClause
+ * the selectClause to set
*/
public void setSelectClause(String selectClause) {
this.selectClause = selectClause;
}
/**
- * @param sortKey the sortKey to set
+ * @param sortKey
+ * the sortKey to set
*/
public void setSortKey(String sortKey) {
this.sortKey = sortKey;
@@ -123,12 +131,12 @@ public void setSortKey(String sortKey) {
* @param ascending
*/
public void setAscending(boolean ascending) {
- this.ascending = ascending;
+ this.ascending = ascending;
}
/**
- * Get a {@link PagingQueryProvider} instance using the provided properties
- * and appropriate for the given database type.
+ * Get a {@link PagingQueryProvider} instance using the provided properties and appropriate for the given database
+ * type.
*
* @see FactoryBean#getObject()
*/
@@ -138,19 +146,24 @@ public Object getObject() throws Exception {
try {
type = databaseType != null ? DatabaseType.valueOf(databaseType.toUpperCase()) : DatabaseType
.fromMetaData(dataSource);
- }
- catch (MetaDataAccessException e) {
+ } catch (MetaDataAccessException e) {
throw new IllegalArgumentException(
"Could not inspect meta data for database type. You have to supply it explicitly.", e);
}
AbstractSqlPagingQueryProvider provider = providers.get(type);
- Assert.state(provider!=null, "Should not happen: missing PagingQueryProvider for DatabaseType="+type);
+ Assert.state(provider != null, "Should not happen: missing PagingQueryProvider for DatabaseType=" + type);
provider.setFromClause(fromClause);
provider.setWhereClause(whereClause);
provider.setSortKey(sortKey);
provider.setAscending(ascending);
+ if (StringUtils.hasText(groupClause)) {
+ provider.setGroupClause(groupClause);
+ }
+ if (StringUtils.hasText(sortKeyAlias)) {
+ provider.setSortKeyAlias(sortKeyAlias);
+ }
if (StringUtils.hasText(selectClause)) {
provider.setSelectClause(selectClause);
}
@@ -172,10 +185,27 @@ public Class getObjectType() {
/**
* Always returns true.
+ *
* @see FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
+ public void setGroupClause(String groupClause) {
+ this.groupClause = groupClause;
+ }
+
+ public String getGroupClause() {
+ return groupClause;
+ }
+
+ public void setSortKeyAlias(String sortKeyAlias) {
+ this.sortKeyAlias = sortKeyAlias;
+ }
+
+ public String getSortKeyAlias() {
+ return sortKeyAlias;
+ }
+
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java
index b154cdf036..6b1a9964b2 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlPagingQueryUtils.java
@@ -16,6 +16,7 @@
package org.springframework.batch.item.database.support;
+
/**
* Utility class that generates the actual SQL statements used by query
* providers.
@@ -42,6 +43,7 @@ public static String generateLimitSqlQuery(AbstractSqlPagingQueryProvider provid
sql.append("SELECT ").append(provider.getSelectClause());
sql.append(" FROM ").append(provider.getFromClause());
buildWhereClause(provider, remainingPageQuery, sql);
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
sql.append(" " + limitClause);
@@ -65,6 +67,7 @@ public static String generateTopSqlQuery(AbstractSqlPagingQueryProvider provider
sql.append("SELECT ").append(topClause).append(" ").append(provider.getSelectClause());
sql.append(" FROM ").append(provider.getFromClause());
buildWhereClause(provider, remainingPageQuery, sql);
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
@@ -104,6 +107,7 @@ public static String generateRowNumSqlQuery(AbstractSqlPagingQueryProvider provi
sql.append("SELECT * FROM (SELECT ").append(selectClause).append(", ROWNUM as TMP_ROW_NUM");
sql.append(" FROM ").append(provider.getFromClause());
buildWhereClause(provider, remainingPageQuery, sql);
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
sql.append(") WHERE ").append(rowNumClause);
@@ -125,6 +129,7 @@ public static String generateRowNumSqlQueryWithNesting(AbstractSqlPagingQueryPro
.append(", ROWNUM as TMP_ROW_NUM");
sql.append(" FROM (SELECT ").append(innerSelectClause).append(" FROM ").append(provider.getFromClause());
buildWhereClause(provider, remainingPageQuery, sql);
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
sql.append(")) WHERE ").append(rowNumClause);
@@ -146,6 +151,7 @@ public static String generateLimitJumpToQuery(AbstractSqlPagingQueryProvider pro
sql.append("SELECT ").append(provider.getSortKey()).append(" AS SORT_KEY");
sql.append(" FROM ").append(provider.getFromClause());
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
sql.append(" " + limitClause);
@@ -166,6 +172,7 @@ public static String generateTopJumpToQuery(AbstractSqlPagingQueryProvider provi
sql.append("SELECT ").append(topClause).append(" ").append(provider.getSortKey()).append(" AS SORT_KEY");
sql.append(" FROM ").append(provider.getFromClause());
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
+ sql.append(provider.getGroupClause() == null ? "" : " GROUP BY " + provider.getGroupClause());
sql.append(" ORDER BY ").append(provider.getSortKey());
buildAscendingClause(provider, sql);
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 e62d8ad007..824a45a1d1 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
@@ -19,9 +19,8 @@
import org.springframework.util.StringUtils;
/**
- * Generic Paging Query Provider using standard SQL:2003 windowing functions.
- * These features are supported by DB2, Oracle, SQL Server 2005, Sybase and
- * Apache Derby version 10.4.1.3
+ * Generic Paging Query Provider using standard SQL:2003 windowing functions. These features are supported by DB2,
+ * Oracle, SQL Server 2005, Sybase and Apache Derby version 10.4.1.3
*
* @author Thomas Risberg
* @since 2.0
@@ -35,8 +34,8 @@ public String generateFirstPageQuery(int pageSize) {
sql.append("SELECT ").append(getSelectClause()).append(", ");
sql.append("ROW_NUMBER() OVER (").append(getOverClause());
sql.append(") AS ROW_NUMBER");
- sql.append(" FROM ").append(getFromClause()).append(
- getWhereClause() == null ? "" : " WHERE " + getWhereClause());
+ sql.append(" FROM ").append(getFromClause())
+ .append(getWhereClause() == null ? "" : " WHERE " + getWhereClause());
sql.append(getAfterWhereClause());
String alias = extractTableAlias();
sql.append(") ").append(getSubQueryAlias()).append("WHERE " + alias + "ROW_NUMBER <= ").append(pageSize);
@@ -72,8 +71,7 @@ public String generateRemainingPagesQuery(int pageSize) {
sql.append(getSortKey());
if (isAscending()) {
sql.append(" > ");
- }
- else {
+ } else {
sql.append(" < ");
}
sql.append(getSortKeyPlaceHolder());
@@ -85,7 +83,11 @@ public String generateRemainingPagesQuery(int pageSize) {
}
protected String getAfterWhereClause() {
- return "";
+ if (getGroupClause() != null) {
+ return " GROUP BY " + getGroupClause();
+ } else {
+ return "";
+ }
}
@Override
@@ -101,8 +103,8 @@ public String generateJumpToItemQuery(int itemIndex, int pageSize) {
sql.append("SELECT ").append(getSortKey()).append(" AS SORT_KEY, ");
sql.append("ROW_NUMBER() OVER (").append(getOverClause());
sql.append(") AS ROW_NUMBER");
- sql.append(" FROM ").append(getFromClause()).append(
- getWhereClause() == null ? "" : " WHERE " + getWhereClause());
+ sql.append(" FROM ").append(getFromClause())
+ .append(getWhereClause() == null ? "" : " WHERE " + getWhereClause());
sql.append(getAfterWhereClause());
String alias = extractTableAlias();
sql.append(") ").append(getSubQueryAlias()).append("WHERE " + alias + "ROW_NUMBER = ").append(lastRowNum);
@@ -117,8 +119,7 @@ protected String getOverClause() {
private String getAscendingClause() {
if (isAscending()) {
return "ASC";
- }
- else {
+ } else {
return "DESC";
}
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProviderTests.java
index 0ffc0e4bb5..d3535e9b2b 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/AbstractSqlPagingQueryProviderTests.java
@@ -66,5 +66,17 @@ public void testQueryContainsSortKeyDesc(){
@Test
public abstract void testGenerateJumpToItemQueryForFirstPage();
+
+ @Test
+ public abstract void testGenerateFirstPageQueryWithGroupBy();
+
+ @Test
+ public abstract void testGenerateRemainingPagesQueryWithGroupBy();
+
+ @Test
+ public abstract void testGenerateJumpToItemQueryWithGroupBy();
+
+ @Test
+ public abstract void testGenerateJumpToItemQueryForFirstPageWithGroupBy();
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/Db2PagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/Db2PagingQueryProviderTests.java
index a406f1166e..dd3f91d94b 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/Db2PagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/Db2PagingQueryProviderTests.java
@@ -40,5 +40,38 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC FETCH FIRST 100 ROWS ONLY";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC FETCH FIRST 100 ROWS ONLY";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java
index 92af442848..8c0ad62dca 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderTests.java
@@ -132,5 +132,38 @@ public void testQueryContainsSortKeyDesc() {
String s = pagingQueryProvider.generateFirstPageQuery(pageSize).toLowerCase();
assertTrue("Wrong query: " + s, s.contains("id desc"));
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER <= 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/H2PagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/H2PagingQueryProviderTests.java
index 6cd942ef3a..0f0a06f995 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/H2PagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/H2PagingQueryProviderTests.java
@@ -56,4 +56,37 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT LIMIT 99 1 id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT LIMIT 0 1 id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HsqlPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HsqlPagingQueryProviderTests.java
index 196cee342e..4c7f5ca4b3 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HsqlPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/HsqlPagingQueryProviderTests.java
@@ -55,4 +55,37 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT LIMIT 99 1 id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT LIMIT 0 1 id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java
index af51b95527..8fdda1cca3 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/MySqlPagingQueryProviderTests.java
@@ -55,4 +55,37 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 99, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 0, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/OraclePagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/OraclePagingQueryProviderTests.java
index fe2fff029c..33fed144f4 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/OraclePagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/OraclePagingQueryProviderTests.java
@@ -44,4 +44,41 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals(sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM (SELECT id, name, age, ROWNUM as TMP_ROW_NUM FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC) WHERE ROWNUM <= 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ pagingQueryProvider.setWhereClause("");
+ String sql2 = "SELECT * FROM (SELECT id, name, age, ROWNUM as TMP_ROW_NUM FROM foo GROUP BY dep ORDER BY id ASC) WHERE ROWNUM <= 100";
+ String s2 = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql2, s2);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM (SELECT id, name, age, ROWNUM as TMP_ROW_NUM FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC) WHERE ROWNUM <= 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM (SELECT SORT_KEY, ROWNUM as TMP_ROW_NUM FROM (SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC)) WHERE TMP_ROW_NUM = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals(sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM (SELECT SORT_KEY, ROWNUM as TMP_ROW_NUM FROM (SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC)) WHERE TMP_ROW_NUM = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals(sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/PostgresPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/PostgresPagingQueryProviderTests.java
index 9b4d266c7d..ce73cfc3ce 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/PostgresPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/PostgresPagingQueryProviderTests.java
@@ -40,5 +40,38 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("Wrong SQL for first page", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 1 OFFSET 99";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("Wrong SQL for jump to", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id AS SORT_KEY FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 1 OFFSET 0";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("Wrong SQL for first page", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProviderTests.java
index e71229b1d9..c60bc20b8e 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlServerPagingQueryProviderTests.java
@@ -41,4 +41,37 @@ public void testGenerateJumpToItemQueryForFirstPage() {
Assert.assertEquals("", sql, s);
}
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) AS TMP_SUB WHERE TMP_SUB.ROW_NUMBER = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java
index ffffa3d6f8..4f007d2cd4 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlWindowingPagingQueryProviderTests.java
@@ -56,5 +56,38 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) WHERE ROW_NUMBER <= 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 AND id > ? GROUP BY dep) WHERE ROW_NUMBER <= 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) WHERE ROW_NUMBER = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) WHERE ROW_NUMBER = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SybasePagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SybasePagingQueryProviderTests.java
index 1503798be7..df64b7f77a 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SybasePagingQueryProviderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SybasePagingQueryProviderTests.java
@@ -40,4 +40,37 @@ public void testGenerateJumpToItemQueryForFirstPage() {
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
Assert.assertEquals("", sql, s);
}
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT TOP 100 id, name, age FROM foo WHERE bar = 1 AND id > ? GROUP BY dep ORDER BY id ASC";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) WHERE ROW_NUMBER = 100";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 GROUP BY dep) WHERE ROW_NUMBER = 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ Assert.assertEquals("", sql, s);
+ }
}