SCT-79 Support sqlserver

resolves spring-cloud/spring-cloud-task#79
This commit is contained in:
Glenn Renfro
2016-02-18 19:07:39 -05:00
committed by Michael Minella
parent 27c8c6d76d
commit 91fa6be092
10 changed files with 117 additions and 28 deletions

View File

@@ -29,7 +29,21 @@ public class OraclePagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
int offset = pageable.getOffset()+1;
return SqlPagingQueryUtils.generateRowNumSqlQueryWithNesting(this, getSelectClause(), getSelectClause(), false, "TMP_ROW_NUM >= "
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
}
private String generateRowNumSqlQueryWithNesting(String selectClause,
boolean remainingPageQuery,
String rowNumClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
.append(", ").append("ROWNUM as TMP_ROW_NUM");
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ").append(this.getFromClause());
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
sql.append(")) WHERE ").append(rowNumClause);
return sql.toString();
}
}

View File

@@ -22,6 +22,7 @@ import static org.springframework.cloud.task.repository.support.DatabaseType.H2;
import static org.springframework.cloud.task.repository.support.DatabaseType.MYSQL;
import static org.springframework.cloud.task.repository.support.DatabaseType.ORACLE;
import static org.springframework.cloud.task.repository.support.DatabaseType.POSTGRES;
import static org.springframework.cloud.task.repository.support.DatabaseType.SQLSERVER;
import java.util.HashMap;
import java.util.Map;
@@ -66,6 +67,7 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
providers.put(MYSQL, new MySqlPagingQueryProvider());
providers.put(POSTGRES, new PostgresPagingQueryProvider());
providers.put(ORACLE, new OraclePagingQueryProvider());
providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
}
/**

View File

@@ -65,28 +65,14 @@ public class SqlPagingQueryUtils {
return sql.toString();
}
public static String generateRowNumSqlQueryWithNesting(AbstractSqlPagingQueryProvider provider,
String selectClause, boolean remainingPageQuery, String rowNumClause) {
return generateRowNumSqlQueryWithNesting(provider, selectClause, selectClause, remainingPageQuery, rowNumClause);
}
public static String generateRowNumSqlQueryWithNesting(AbstractSqlPagingQueryProvider provider,
String innerSelectClause, String outerSelectClause, boolean remainingPageQuery, String rowNumClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(outerSelectClause).append(" FROM (SELECT ").append(outerSelectClause)
.append(", ").append("ROWNUM as TMP_ROW_NUM");
sql.append(" FROM (SELECT ").append(innerSelectClause).append(" FROM ").append(provider.getFromClause());
buildWhereClause(provider, remainingPageQuery, sql);
sql.append(" ORDER BY ").append(buildSortClause(provider));
sql.append(")) WHERE ").append(rowNumClause);
return sql.toString();
}
private static void buildWhereClause(AbstractSqlPagingQueryProvider provider, boolean remainingPageQuery,
StringBuilder sql) {
/**
* Generates WHERE clause for queries that require sub selects.
*
* @param provider the paging query provider that will provide the base where clause
* @return a String for the where clause.
*/
public static void buildWhereClause( AbstractSqlPagingQueryProvider provider,
boolean remainingPageQuery, StringBuilder sql) {
if (remainingPageQuery) {
sql.append(" WHERE ");
if (provider.getWhereClause() != null) {
@@ -94,7 +80,6 @@ public class SqlPagingQueryUtils {
sql.append(provider.getWhereClause());
sql.append(") AND ");
}
}
else {
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
@@ -139,5 +124,4 @@ public class SqlPagingQueryUtils {
return builder.toString();
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.database.support;
import org.springframework.cloud.task.repository.database.PagingQueryProvider;
import org.springframework.data.domain.Pageable;
/**
* Sql Server implementation of a {@link PagingQueryProvider} using database specific features.
* @author Glenn Renfro
*/
public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider{
@Override
public String getPageQuery(Pageable pageable) {
int offset = pageable.getOffset()+1;
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
}
private String generateRowNumSqlQueryWithNesting(String selectClause,
boolean remainingPageQuery,
String rowNumClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
.append(", ").append("ROW_NUMBER() OVER (ORDER BY ")
.append(SqlPagingQueryUtils.buildSortClause(this))
.append(") AS TMP_ROW_NUM ")
.append(" FROM ").append(getFromClause());
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
sql.append(") TASK_EXECUTION_PAGE ");
sql.append(" WHERE ").append(rowNumClause);
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
return sql.toString();
}
}

View File

@@ -39,7 +39,8 @@ public enum DatabaseType {
H2("H2"),
ORACLE("Oracle"),
MYSQL("MySQL"),
POSTGRES("PostgreSQL");
POSTGRES("PostgreSQL"),
SQLSERVER("Microsoft SQL Server");
private static final Map<String, DatabaseType> dbNameMap;

View File

@@ -99,6 +99,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
if ("mysql".equals(platform)) {
platform = "mysql";
}
if ("sqlserver".equals(platform)){
platform = "sqlserver";
}
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
String schemaLocation = schema;
schemaLocation = schemaLocation.replace("@@platform@@", platform);

View File

@@ -0,0 +1,18 @@
CREATE TABLE TASK_EXECUTION (
TASK_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
START_TIME DATETIME DEFAULT NULL ,
END_TIME DATETIME DEFAULT NULL ,
TASK_NAME VARCHAR(100) ,
EXIT_CODE INTEGER ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME
);
CREATE TABLE TASK_EXECUTION_PARAMS (
TASK_EXECUTION_ID BIGINT NOT NULL ,
TASK_PARAM VARCHAR(250) ,
constraint TASK_EXEC_PARAMS_FK foreign key (TASK_EXECUTION_ID)
references TASK_EXECUTION(TASK_EXECUTION_ID)
) ;
CREATE TABLE TASK_SEQ (ID BIGINT IDENTITY);

View File

@@ -61,7 +61,15 @@ public class FindAllPagingQueryProviderTests {
{"MySQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
+ "%PREFIX%EXECUTION ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"}
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION) TASK_EXECUTION_PAGE "
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC"}
});
}

View File

@@ -66,7 +66,15 @@ public class WhereClausePagingQueryProviderTests {
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = '0000' "
+ "ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"}
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, LAST_UPDATED, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = "
+ "'0000') TASK_EXECUTION_PAGE WHERE TMP_ROW_NUM >= 1 "
+ "AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC"}
});
}

View File

@@ -34,6 +34,7 @@ utilize a supported database. Below is a list of the ones currently supported:
- MySql
- Oracle
- Postgres
- SqlServer
[[getting-started-developing-first-task]]
== Developing your first Spring Cloud Task application