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); + } }