diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml
index d24a52774..71f8b4751 100644
--- a/spring-batch-core/pom.xml
+++ b/spring-batch-core/pom.xml
@@ -279,6 +279,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlite.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlite.sql
new file mode 100644
index 000000000..1b4e01390
--- /dev/null
+++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-drop-sqlite.sql
@@ -0,0 +1,12 @@
+-- Autogenerated: do not edit this file
+ DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_CONTEXT ;
+DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_CONTEXT ;
+DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_PARAMS ;
+DROP TABLE IF EXISTS BATCH_STEP_EXECUTION ;
+DROP TABLE IF EXISTS BATCH_JOB_EXECUTION ;
+DROP TABLE IF EXISTS BATCH_JOB_PARAMS ;
+DROP TABLE IF EXISTS BATCH_JOB_INSTANCE ;
+
+DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_SEQ ;
+DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_SEQ ;
+DROP TABLE IF EXISTS BATCH_JOB_SEQ ;
diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql
new file mode 100644
index 000000000..0ca50c5d3
--- /dev/null
+++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/schema-sqlite.sql
@@ -0,0 +1,86 @@
+-- Autogenerated: do not edit this file
+
+CREATE TABLE BATCH_JOB_INSTANCE (
+ JOB_INSTANCE_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ VERSION INTEGER ,
+ JOB_NAME VARCHAR(100) NOT NULL,
+ JOB_KEY VARCHAR(32) NOT NULL,
+ constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
+) ;
+
+CREATE TABLE BATCH_JOB_EXECUTION (
+ JOB_EXECUTION_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ VERSION INTEGER ,
+ JOB_INSTANCE_ID INTEGER NOT NULL,
+ CREATE_TIME TIMESTAMP NOT NULL,
+ START_TIME TIMESTAMP DEFAULT NULL ,
+ END_TIME TIMESTAMP DEFAULT NULL ,
+ STATUS VARCHAR(10) ,
+ EXIT_CODE VARCHAR(100) ,
+ EXIT_MESSAGE VARCHAR(2500) ,
+ LAST_UPDATED TIMESTAMP,
+ constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
+ references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
+) ;
+
+CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
+ JOB_EXECUTION_ID INTEGER NOT NULL ,
+ TYPE_CD VARCHAR(6) NOT NULL ,
+ KEY_NAME VARCHAR(100) NOT NULL ,
+ STRING_VAL VARCHAR(250) ,
+ DATE_VAL TIMESTAMP DEFAULT NULL ,
+ LONG_VAL INTEGER ,
+ DOUBLE_VAL DOUBLE PRECISION ,
+ IDENTIFYING CHAR(1) NOT NULL ,
+ constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
+ references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
+) ;
+
+CREATE TABLE BATCH_STEP_EXECUTION (
+ STEP_EXECUTION_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ VERSION INTEGER NOT NULL,
+ STEP_NAME VARCHAR(100) NOT NULL,
+ JOB_EXECUTION_ID INTEGER NOT NULL,
+ START_TIME TIMESTAMP NOT NULL ,
+ END_TIME TIMESTAMP DEFAULT NULL ,
+ STATUS VARCHAR(10) ,
+ COMMIT_COUNT INTEGER ,
+ READ_COUNT INTEGER ,
+ FILTER_COUNT INTEGER ,
+ WRITE_COUNT INTEGER ,
+ READ_SKIP_COUNT INTEGER ,
+ WRITE_SKIP_COUNT INTEGER ,
+ PROCESS_SKIP_COUNT INTEGER ,
+ ROLLBACK_COUNT INTEGER ,
+ EXIT_CODE VARCHAR(100) ,
+ EXIT_MESSAGE VARCHAR(2500) ,
+ LAST_UPDATED TIMESTAMP,
+ constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
+ references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
+) ;
+
+CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
+ STEP_EXECUTION_ID INTEGER NOT NULL PRIMARY KEY,
+ SHORT_CONTEXT VARCHAR(2500) NOT NULL,
+ SERIALIZED_CONTEXT CLOB ,
+ constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
+ references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
+) ;
+
+CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
+ JOB_EXECUTION_ID INTEGER NOT NULL PRIMARY KEY,
+ SHORT_CONTEXT VARCHAR(2500) NOT NULL,
+ SERIALIZED_CONTEXT CLOB ,
+ constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
+ references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
+) ;
+
+CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
+ ID INTEGER PRIMARY KEY AUTOINCREMENT
+);
+CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
+ ID INTEGER PRIMARY KEY AUTOINCREMENT
+);
+CREATE TABLE BATCH_JOB_SEQ (
+ ID INTEGER PRIMARY KEY AUTOINCREMENT
+);
diff --git a/spring-batch-core/src/main/sql/destroy.sql.vpp b/spring-batch-core/src/main/sql/destroy.sql.vpp
index 1c95ce2a8..8bc6d06a3 100644
--- a/spring-batch-core/src/main/sql/destroy.sql.vpp
+++ b/spring-batch-core/src/main/sql/destroy.sql.vpp
@@ -1,5 +1,6 @@
DROP TABLE $!{IFEXISTSBEFORE} BATCH_STEP_EXECUTION_CONTEXT $!{IFEXISTS};
DROP TABLE $!{IFEXISTSBEFORE} BATCH_JOB_EXECUTION_CONTEXT $!{IFEXISTS};
+DROP TABLE $!{IFEXISTSBEFORE} BATCH_JOB_EXECUTION_PARAMS $!{IFEXISTS};
DROP TABLE $!{IFEXISTSBEFORE} BATCH_STEP_EXECUTION $!{IFEXISTS};
DROP TABLE $!{IFEXISTSBEFORE} BATCH_JOB_EXECUTION $!{IFEXISTS};
DROP TABLE $!{IFEXISTSBEFORE} BATCH_JOB_PARAMS $!{IFEXISTS};
diff --git a/spring-batch-core/src/main/sql/sqlite.properties b/spring-batch-core/src/main/sql/sqlite.properties
new file mode 100644
index 000000000..807467dca
--- /dev/null
+++ b/spring-batch-core/src/main/sql/sqlite.properties
@@ -0,0 +1,14 @@
+platform=sqlite
+# SQL language oddities
+BIGINT = INTEGER
+IDENTITY =
+GENERATED = AUTOINCREMENT
+IFEXISTSBEFORE = IF EXISTS
+DOUBLE = DOUBLE PRECISION
+BLOB = BLOB
+CLOB = CLOB
+TIMESTAMP = TIMESTAMP
+CHAR = CHAR
+VARCHAR = VARCHAR
+# for generating drop statements...
+SEQUENCE = TABLE
\ No newline at end of file
diff --git a/spring-batch-core/src/main/sql/sqlite.vpp b/spring-batch-core/src/main/sql/sqlite.vpp
new file mode 100644
index 000000000..a3da1792e
--- /dev/null
+++ b/spring-batch-core/src/main/sql/sqlite.vpp
@@ -0,0 +1,5 @@
+#macro (sequence $name $value)CREATE TABLE ${name} (
+ ID INTEGER PRIMARY KEY AUTOINCREMENT
+);
+#end
+#macro (notnull $name $type)ALTER COLUMN ${name} ${type} NOT NULL#end
diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml
index 305d1e1b8..5716a1574 100644
--- a/spring-batch-infrastructure/pom.xml
+++ b/spring-batch-infrastructure/pom.xml
@@ -95,6 +95,11 @@
h2
test
+
+ org.xerial
+ sqlite-jdbc
+ test
+
org.apache.derby
derby
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java
index 83ff2f506..bf2d7d0bb 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactory.java
@@ -23,6 +23,7 @@ import static org.springframework.batch.support.DatabaseType.HSQL;
import static org.springframework.batch.support.DatabaseType.MYSQL;
import static org.springframework.batch.support.DatabaseType.ORACLE;
import static org.springframework.batch.support.DatabaseType.POSTGRES;
+import static org.springframework.batch.support.DatabaseType.SQLITE;
import static org.springframework.batch.support.DatabaseType.SQLSERVER;
import static org.springframework.batch.support.DatabaseType.SYBASE;
@@ -101,6 +102,9 @@ public class DefaultDataFieldMaxValueIncrementerFactory implements DataFieldMaxV
else if (databaseType == POSTGRES) {
return new PostgreSQLSequenceMaxValueIncrementer(dataSource, incrementerName);
}
+ else if (databaseType == SQLITE) {
+ return new SqliteMaxValueIncrementer(dataSource, incrementerName, incrementerColumnName);
+ }
else if (databaseType == SQLSERVER) {
return new SqlServerMaxValueIncrementer(dataSource, incrementerName, incrementerColumnName);
}
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 592e96114..4a1b06668 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
@@ -23,6 +23,7 @@ import static org.springframework.batch.support.DatabaseType.HSQL;
import static org.springframework.batch.support.DatabaseType.MYSQL;
import static org.springframework.batch.support.DatabaseType.ORACLE;
import static org.springframework.batch.support.DatabaseType.POSTGRES;
+import static org.springframework.batch.support.DatabaseType.SQLITE;
import static org.springframework.batch.support.DatabaseType.SQLSERVER;
import static org.springframework.batch.support.DatabaseType.SYBASE;
@@ -77,6 +78,7 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
providers.put(MYSQL,new MySqlPagingQueryProvider());
providers.put(ORACLE,new OraclePagingQueryProvider());
providers.put(POSTGRES,new PostgresPagingQueryProvider());
+ providers.put(SQLITE, new SqlitePagingQueryProvider());
providers.put(SQLSERVER,new SqlServerPagingQueryProvider());
providers.put(SYBASE,new SybasePagingQueryProvider());
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementer.java
new file mode 100644
index 000000000..b54110b81
--- /dev/null
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementer.java
@@ -0,0 +1,50 @@
+package org.springframework.batch.item.database.support;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.springframework.dao.DataAccessResourceFailureException;
+import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.jdbc.support.JdbcUtils;
+import org.springframework.jdbc.support.incrementer.AbstractColumnMaxValueIncrementer;
+
+/**
+ * Implemented as a package-private class since it is required for SQLite support, but
+ * should ideally be in Spring JDBC.
+ *
+ * @author Luke Taylor
+ */
+class SqliteMaxValueIncrementer extends AbstractColumnMaxValueIncrementer {
+
+ public SqliteMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) {
+ super(dataSource, incrementerName, columnName);
+ }
+
+ @Override
+ protected long getNextKey() {
+ Connection con = DataSourceUtils.getConnection(getDataSource());
+ Statement stmt = null;
+ try {
+ stmt = con.createStatement();
+ DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
+ stmt.executeUpdate("insert into " + getIncrementerName() + " values(null)");
+ ResultSet rs = stmt.executeQuery("select max(rowid) from " + getIncrementerName());
+ if (!rs.next()) {
+ throw new DataAccessResourceFailureException("rowid query failed after executing an update");
+ }
+ long nextKey = rs.getLong(1);
+ stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + nextKey);
+ return nextKey;
+ }
+ catch (SQLException ex) {
+ throw new DataAccessResourceFailureException("Could not obtain rowid", ex);
+ }
+ finally {
+ JdbcUtils.closeStatement(stmt);
+ DataSourceUtils.releaseConnection(con, getDataSource());
+ }
+ }
+}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlitePagingQueryProvider.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlitePagingQueryProvider.java
new file mode 100644
index 000000000..5562b0395
--- /dev/null
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/support/SqlitePagingQueryProvider.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006-2012 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.batch.item.database.support;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * SQLite implementation of a {@link org.springframework.batch.item.database.PagingQueryProvider} using database specific
+ * features.
+ *
+ * @author Luke Taylor
+ * @since 2.2.5
+ */
+public class SqlitePagingQueryProvider extends AbstractSqlPagingQueryProvider {
+ @Override
+ public String generateFirstPageQuery(int pageSize) {
+ return SqlPagingQueryUtils.generateLimitSqlQuery(this, false, buildLimitClause(pageSize));
+ }
+
+ @Override
+ public String generateRemainingPagesQuery(int pageSize) {
+ if(StringUtils.hasText(getGroupClause())) {
+ return SqlPagingQueryUtils.generateLimitGroupedSqlQuery(this, true, buildLimitClause(pageSize));
+ }
+ else {
+ return SqlPagingQueryUtils.generateLimitSqlQuery(this, true, buildLimitClause(pageSize));
+ }
+ }
+
+ @Override
+ public String generateJumpToItemQuery(int itemIndex, int pageSize) {
+ int page = itemIndex / pageSize;
+ int offset = (page * pageSize) - 1;
+ offset = offset<0 ? 0 : offset;
+
+ String limitClause = new StringBuilder().append("LIMIT ").append(offset).append(", 1").toString();
+ return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
+ }
+
+ private String buildLimitClause(int pageSize) {
+ return new StringBuilder().append("LIMIT ").append(pageSize).toString();
+ }
+}
+
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
index 756e56f5a..5fa56f98a 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/DatabaseType.java
@@ -29,24 +29,26 @@ import org.springframework.jdbc.support.MetaDataAccessException;
* Enum representing a database type, such as DB2 or oracle. The type also
* contains a product name, which is expected to be the same as the product name
* provided by the database driver's metadata.
- *
+ *
* @author Lucas Ward
* @since 2.0
*/
public enum DatabaseType {
- DERBY("Apache Derby"),
- DB2("DB2"),
- DB2ZOS("DB2ZOS"),
+ DERBY("Apache Derby"),
+ DB2("DB2"),
+ DB2ZOS("DB2ZOS"),
HSQL("HSQL Database Engine"),
SQLSERVER("Microsoft SQL Server"),
MYSQL("MySQL"),
ORACLE("Oracle"),
POSTGRES("PostgreSQL"),
- SYBASE("Sybase"), H2("H2");
-
+ SYBASE("Sybase"),
+ H2("H2"),
+ SQLITE("SQLite");
+
private static final Map nameMap;
-
+
static{
nameMap = new HashMap();
for(DatabaseType type: values()){
@@ -56,35 +58,35 @@ public enum DatabaseType {
//A description is necessary due to the nature of database descriptions
//in metadata.
private final String productName;
-
+
private DatabaseType(String productName) {
this.productName = productName;
}
-
+
public String getProductName() {
return productName;
}
-
+
/**
* Static method to obtain a DatabaseType from the provided product name.
- *
+ *
* @param productName
* @return DatabaseType for given product name.
* @throws IllegalArgumentException if none is found.
*/
public static DatabaseType fromProductName(String productName){
if(!nameMap.containsKey(productName)){
- throw new IllegalArgumentException("DatabaseType not found for product name: [" +
+ throw new IllegalArgumentException("DatabaseType not found for product name: [" +
productName + "]");
}
else{
return nameMap.get(productName);
}
}
-
+
/**
* Convenience method that pulls a database product name from the DataSource's metadata.
- *
+ *
* @param dataSource
* @return DatabaseType
* @throws MetaDataAccessException
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java
index 8ded8be59..60e687b27 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DefaultDataFieldMaxValueIncrementerFactoryTests.java
@@ -61,6 +61,7 @@ public class DefaultDataFieldMaxValueIncrementerFactoryTests extends TestCase {
assertTrue(factory.isSupportedIncrementerType("hsql"));
assertTrue(factory.isSupportedIncrementerType("sqlserver"));
assertTrue(factory.isSupportedIncrementerType("sybase"));
+ assertTrue(factory.isSupportedIncrementerType("sqlite"));
}
public void testUnsupportedDatabaseType(){
@@ -124,5 +125,8 @@ public class DefaultDataFieldMaxValueIncrementerFactoryTests extends TestCase {
assertTrue(factory.getIncrementer("sybase", "NAME") instanceof SybaseMaxValueIncrementer);
}
+ public void testSqlite(){
+ assertTrue(factory.getIncrementer("sqlite", "NAME") instanceof SqliteMaxValueIncrementer);
+ }
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementerTests.java
new file mode 100644
index 000000000..6086f1100
--- /dev/null
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqliteMaxValueIncrementerTests.java
@@ -0,0 +1,49 @@
+package org.springframework.batch.item.database.support;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.SimpleDriverDataSource;
+
+/**
+ * @author Luke Taylor
+ */
+public class SqliteMaxValueIncrementerTests {
+ static String dbFile;
+ static SimpleDriverDataSource dataSource;
+ static JdbcTemplate template;
+
+ @BeforeClass
+ public static void setUp() {
+ dbFile = System.getProperty("java.io.tmpdir") + File.separator + "batch_sqlite_inc.db";
+ dataSource = new SimpleDriverDataSource();
+ dataSource.setDriverClass(org.sqlite.JDBC.class);
+ dataSource.setUrl("jdbc:sqlite:" + dbFile);
+ template = new JdbcTemplate(dataSource);
+ template.execute("create table max_value (id integer primary key autoincrement)");
+ }
+
+ @AfterClass
+ public static void removeDbFile() {
+ File db = new File(dbFile);
+ if (db.exists()) {
+ db.delete();
+ }
+ dataSource = null;
+ template = null;
+ }
+
+ @Test
+ public void testNextKey() throws Exception {
+ SqliteMaxValueIncrementer mvi = new SqliteMaxValueIncrementer(dataSource, "max_value", "id");
+ assertEquals(1, mvi.getNextKey());
+ assertEquals(2, mvi.getNextKey());
+ assertEquals(3, mvi.getNextKey());
+ assertEquals(1, template.queryForInt("select count(*) from max_value"));
+ }
+}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlitePagingQueryProviderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlitePagingQueryProviderTests.java
new file mode 100644
index 000000000..72c73d76f
--- /dev/null
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/SqlitePagingQueryProviderTests.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2006-2012 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.batch.item.database.support;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * @author Thomas Risberg
+ * @author Michael Minella
+ * @author Luke Taylor
+ */
+public class SqlitePagingQueryProviderTests extends AbstractSqlPagingQueryProviderTests {
+
+ public SqlitePagingQueryProviderTests() {
+ pagingQueryProvider = new MySqlPagingQueryProvider();
+ }
+
+ @Test
+ @Override
+ public void testGenerateFirstPageQuery() {
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateRemainingPagesQuery() {
+ String sql = "SELECT id, name, age FROM foo WHERE bar = 1 AND ((id > ?)) ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQuery() {
+ String sql = "SELECT id FROM foo WHERE bar = 1 ORDER BY id ASC LIMIT 99, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Test @Override
+ public void testGenerateJumpToItemQueryForFirstPage() {
+ String sql = "SELECT id FROM foo WHERE bar = 1 ORDER BY id ASC LIMIT 0, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Override
+ @Test
+ 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);
+ assertEquals(sql, s);
+ }
+
+ @Override
+ @Test
+ public void testGenerateRemainingPagesQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT * FROM (SELECT id, name, age FROM foo WHERE bar = 1 GROUP BY dep) AS MAIN_QRY WHERE ((id > ?)) ORDER BY id ASC LIMIT 100";
+ String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Override
+ @Test
+ public void testGenerateJumpToItemQueryWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 99, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Override
+ @Test
+ public void testGenerateJumpToItemQueryForFirstPageWithGroupBy() {
+ pagingQueryProvider.setGroupClause("dep");
+ String sql = "SELECT id FROM foo WHERE bar = 1 GROUP BY dep ORDER BY id ASC LIMIT 0, 1";
+ String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
+ assertEquals(sql, s);
+ }
+
+ @Override
+ public String getFirstPageSqlWithMultipleSortKeys() {
+ return "SELECT id, name, age FROM foo WHERE bar = 1 ORDER BY name ASC, id DESC LIMIT 100";
+ }
+
+ @Override
+ public String getRemainingSqlWithMultipleSortKeys() {
+ return "SELECT id, name, age FROM foo WHERE bar = 1 AND ((name > ?) OR (name = ? AND id < ?)) ORDER BY name ASC, id DESC LIMIT 100";
+ }
+
+ @Override
+ public String getJumpToItemQueryWithMultipleSortKeys() {
+ return "SELECT name, id FROM foo WHERE bar = 1 ORDER BY name ASC, id DESC LIMIT 99, 1";
+ }
+
+ @Override
+ public String getJumpToItemQueryForFirstPageWithMultipleSortKeys() {
+ return "SELECT name, id FROM foo WHERE bar = 1 ORDER BY name ASC, id DESC LIMIT 0, 1";
+ }
+}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java
index e7e1ae5ed..cb88196b3 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/support/DatabaseTypeTests.java
@@ -8,6 +8,7 @@ import static org.springframework.batch.support.DatabaseType.HSQL;
import static org.springframework.batch.support.DatabaseType.MYSQL;
import static org.springframework.batch.support.DatabaseType.ORACLE;
import static org.springframework.batch.support.DatabaseType.POSTGRES;
+import static org.springframework.batch.support.DatabaseType.SQLITE;
import static org.springframework.batch.support.DatabaseType.SQLSERVER;
import static org.springframework.batch.support.DatabaseType.SYBASE;
import static org.springframework.batch.support.DatabaseType.fromProductName;
@@ -36,6 +37,7 @@ public class DatabaseTypeTests {
assertEquals(ORACLE, fromProductName("Oracle"));
assertEquals(POSTGRES, fromProductName("PostgreSQL"));
assertEquals(SYBASE, fromProductName("Sybase"));
+ assertEquals(SQLITE, fromProductName("SQLite"));
}
@Test(expected = IllegalArgumentException.class)
diff --git a/spring-batch-parent/pom.xml b/spring-batch-parent/pom.xml
index ea9ba7ad7..b66626d52 100644
--- a/spring-batch-parent/pom.xml
+++ b/spring-batch-parent/pom.xml
@@ -537,6 +537,12 @@
1.2.125
test
+
+ org.xerial
+ sqlite-jdbc
+ 3.7.2
+ test
+
org.apache.derby
derby