Refactor SQL script support
This commit continues the work in the previous commit as follows: - Introduced an exception hierarchy for exceptions related to SQL scripts, with ScriptException as the base. - CannotReadScriptException and ScriptStatementFailedException now extend ScriptException. - Introduced ScriptParseException, used by ScriptUtils.splitSqlScript(). - DatabasePopulatorUtils.execute() now explicitly throws a DataAccessException. - Polished Javadoc in ResourceDatabasePopulator. - Overhauled Javadoc in ScriptUtils and documented all constants. - Added missing @author tags for original authors in ScriptUtils and ScriptUtilsTests. - ScriptUtils.splitSqlScript() now asserts preconditions. - Deleted superfluous methods in ScriptUtils and changed method visibility to private or package private as appropriate. - Deleted the ScriptStatementExecutor introduced in the previous commit; ScriptUtils.executeSqlScript() now accepts a JDBC Connection; JdbcTestUtils, AbstractTransactionalJUnit4SpringContextTests, and AbstractTransactionalTestNGSpringContextTests now use DatabasePopulatorUtils to execute a ResourceDatabasePopulator instead of executing a script directly via ScriptUtils. - Introduced JdbcTestUtilsIntegrationTests. Issue: SPR-9531
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -21,9 +21,10 @@ import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
||||
@@ -171,22 +172,24 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst
|
||||
/**
|
||||
* Execute the given SQL script.
|
||||
* <p>Use with caution outside of a transaction!
|
||||
* <p>The script will normally be loaded by classpath. There should be one
|
||||
* statement per line. Any semicolons will be removed. <b>Do not use this
|
||||
* method to execute DDL if you expect rollback.</b>
|
||||
* <p>The script will normally be loaded by classpath.
|
||||
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
|
||||
* @param sqlResourcePath the Spring resource path for the SQL script
|
||||
* @param continueOnError whether or not to continue without throwing an
|
||||
* exception in the event of an error
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and continueOnError was {@code false}
|
||||
* @see JdbcTestUtils#executeSqlScript(JdbcTemplate, EncodedResource, boolean)
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see DatabasePopulatorUtils
|
||||
* @see #setSqlScriptEncoding
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||
JdbcTestUtils.executeSqlScript(this.jdbcTemplate, new EncodedResource(resource, this.sqlScriptEncoding),
|
||||
continueOnError);
|
||||
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
|
||||
databasePopulator.setContinueOnError(continueOnError);
|
||||
databasePopulator.addScript(resource);
|
||||
databasePopulator.setSqlScriptEncoding(this.sqlScriptEncoding);
|
||||
|
||||
DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -21,9 +21,10 @@ import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
@@ -162,22 +163,24 @@ public abstract class AbstractTransactionalTestNGSpringContextTests extends Abst
|
||||
/**
|
||||
* Execute the given SQL script.
|
||||
* <p>Use with caution outside of a transaction!
|
||||
* <p>The script will normally be loaded by classpath. There should be one
|
||||
* statement per line. Any semicolons will be removed. <b>Do not use this
|
||||
* method to execute DDL if you expect rollback.</b>
|
||||
* <p>The script will normally be loaded by classpath.
|
||||
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
|
||||
* @param sqlResourcePath the Spring resource path for the SQL script
|
||||
* @param continueOnError whether or not to continue without throwing an
|
||||
* exception in the event of an error
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and continueOnError was {@code false}
|
||||
* @see JdbcTestUtils#executeSqlScript(JdbcTemplate, EncodedResource, boolean)
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see DatabasePopulatorUtils
|
||||
* @see #setSqlScriptEncoding
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||
JdbcTestUtils.executeSqlScript(this.jdbcTemplate, new EncodedResource(resource, this.sqlScriptEncoding),
|
||||
continueOnError);
|
||||
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
|
||||
databasePopulator.setContinueOnError(continueOnError);
|
||||
databasePopulator.addScript(resource);
|
||||
databasePopulator.setSqlScriptEncoding(this.sqlScriptEncoding);
|
||||
|
||||
DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,15 +22,16 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.SqlParameterValue;
|
||||
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||
import org.springframework.jdbc.datasource.init.ScriptUtils.ScriptStatementExecutor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,7 @@ public class JdbcTestUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JdbcTestUtils.class);
|
||||
|
||||
|
||||
/**
|
||||
* Count the rows in the given table.
|
||||
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
|
||||
@@ -117,14 +119,13 @@ public class JdbcTestUtils {
|
||||
* optionally the scale.
|
||||
* @return the number of rows deleted from the table
|
||||
*/
|
||||
public static int deleteFromTableWhere(JdbcTemplate jdbcTemplate, String tableName,
|
||||
String whereClause, Object... args) {
|
||||
public static int deleteFromTableWhere(JdbcTemplate jdbcTemplate, String tableName, String whereClause,
|
||||
Object... args) {
|
||||
String sql = "DELETE FROM " + tableName;
|
||||
if (StringUtils.hasText(whereClause)) {
|
||||
sql += " WHERE " + whereClause;
|
||||
}
|
||||
int rowCount = (args != null && args.length > 0 ? jdbcTemplate.update(sql, args)
|
||||
: jdbcTemplate.update(sql));
|
||||
int rowCount = (args != null && args.length > 0 ? jdbcTemplate.update(sql, args) : jdbcTemplate.update(sql));
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Deleted " + rowCount + " rows from table " + tableName);
|
||||
}
|
||||
@@ -158,9 +159,11 @@ public class JdbcTestUtils {
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and {@code continueOnError} is {@code false}
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see DatabasePopulatorUtils
|
||||
* @see #executeSqlScript(JdbcTemplate, Resource, boolean)
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript(ScriptStatementExecutor, EncodedResource, boolean, boolean, String, String, String, String)}
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript}
|
||||
* or {@link org.springframework.jdbc.datasource.init.ResourceDatabasePopulator}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void executeSqlScript(JdbcTemplate jdbcTemplate, ResourceLoader resourceLoader,
|
||||
@@ -184,9 +187,11 @@ public class JdbcTestUtils {
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and {@code continueOnError} is {@code false}
|
||||
* @see ResourceDatabasePopulator
|
||||
* @see DatabasePopulatorUtils
|
||||
* @see #executeSqlScript(JdbcTemplate, EncodedResource, boolean)
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript(ScriptStatementExecutor, EncodedResource, boolean, boolean, String, String, String, String)}
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript}
|
||||
* or {@link org.springframework.jdbc.datasource.init.ResourceDatabasePopulator}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void executeSqlScript(JdbcTemplate jdbcTemplate, Resource resource, boolean continueOnError)
|
||||
@@ -207,36 +212,22 @@ public class JdbcTestUtils {
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and {@code continueOnError} is {@code false}
|
||||
* @see ResourceDatabasePopulator
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript(ScriptStatementExecutor, EncodedResource, boolean, boolean, String, String, String, String)}
|
||||
* @see DatabasePopulatorUtils
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#executeSqlScript}
|
||||
* or {@link org.springframework.jdbc.datasource.init.ResourceDatabasePopulator}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void executeSqlScript(JdbcTemplate jdbcTemplate, EncodedResource resource, boolean continueOnError)
|
||||
throws DataAccessException {
|
||||
ScriptUtils.executeSqlScript(new JdbcTemplateScriptStatementExecutor(jdbcTemplate), resource,
|
||||
continueOnError, continueOnError, ScriptUtils.DEFAULT_COMMENT_PREFIX,
|
||||
ScriptUtils.DEFAULT_STATEMENT_SEPARATOR, ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||
ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
|
||||
databasePopulator.setContinueOnError(continueOnError);
|
||||
databasePopulator.addScript(resource.getResource());
|
||||
databasePopulator.setSqlScriptEncoding(resource.getEncoding());
|
||||
|
||||
DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource());
|
||||
}
|
||||
|
||||
private static class JdbcTemplateScriptStatementExecutor implements ScriptStatementExecutor {
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
public JdbcTemplateScriptStatementExecutor(JdbcTemplate jdbcTemplate) {
|
||||
super();
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.jdbc.support.JdbcUtils.ScriptStatementExecutor#executeScriptStatement(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public int executeScriptStatement(String statement) throws DataAccessException {
|
||||
return jdbcTemplate.update(statement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a script from the provided {@code LineNumberReader}, using
|
||||
* "{@code --}" as the comment prefix, and build a {@code String} containing
|
||||
@@ -245,14 +236,14 @@ public class JdbcTestUtils {
|
||||
* to be processed
|
||||
* @return a {@code String} containing the script lines
|
||||
* @see #readScript(LineNumberReader, String)
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#readScript(LineNumberReader)}
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#readScript(LineNumberReader, String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String readScript(LineNumberReader lineNumberReader) throws IOException {
|
||||
return ScriptUtils.readScript(lineNumberReader);
|
||||
return readScript(lineNumberReader, ScriptUtils.DEFAULT_COMMENT_PREFIX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a script from the provided {@code LineNumberReader}, using the supplied
|
||||
* comment prefix, and build a {@code String} containing the lines.
|
||||
@@ -263,7 +254,7 @@ public class JdbcTestUtils {
|
||||
* to be processed
|
||||
* @param commentPrefix the prefix that identifies comments in the SQL script — typically "--"
|
||||
* @return a {@code String} containing the script lines
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#readScript(LineNumberReader, String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -276,14 +267,14 @@ public class JdbcTestUtils {
|
||||
* @param script the SQL script
|
||||
* @param delim character delimiting each statement — typically a ';' character
|
||||
* @return {@code true} if the script contains the delimiter; {@code false} otherwise
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#containsSqlScriptDelimiters(String, char)}
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#containsSqlScriptDelimiters}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean containsSqlScriptDelimiters(String script, char delim) {
|
||||
return ScriptUtils.containsSqlScriptDelimiters(script, delim);
|
||||
return ScriptUtils.containsSqlScriptDelimiters(script, String.valueOf(delim));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Split an SQL script into separate statements delimited by the provided
|
||||
* delimiter character. Each individual statement will be added to the
|
||||
@@ -295,7 +286,7 @@ public class JdbcTestUtils {
|
||||
* @param script the SQL script
|
||||
* @param delim character delimiting each statement — typically a ';' character
|
||||
* @param statements the list that will contain the individual statements
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* @deprecated as of Spring 4.0.3, in favor of using
|
||||
* {@link org.springframework.jdbc.datasource.init.ScriptUtils#splitSqlScript(String, char, List)}
|
||||
*/
|
||||
@Deprecated
|
||||
|
||||
Reference in New Issue
Block a user