diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java index 0216e39dad2..50f19a1c411 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java @@ -60,7 +60,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private String separator = ScriptUtils.DEFAULT_STATEMENT_SEPARATOR; - private String commentPrefix = ScriptUtils.DEFAULT_COMMENT_PREFIX; + private String[] commentPrefixes = ScriptUtils.DEFAULT_COMMENT_PREFIXES; private String blockCommentStartDelimiter = ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER; @@ -171,9 +171,22 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * Set the prefix that identifies single-line comments within the SQL scripts. *
Defaults to {@code "--"}. * @param commentPrefix the prefix for single-line comments + * @see #setCommentPrefixes(String...) */ public void setCommentPrefix(String commentPrefix) { - this.commentPrefix = commentPrefix; + Assert.hasText(commentPrefix, "CommentPrefix must not be null or empty"); + this.commentPrefixes = new String[] { commentPrefix }; + } + + /** + * Set the prefixes that identify single-line comments within the SQL scripts. + *
Defaults to {@code "--"}.
+ * @param commentPrefixes the prefixes for single-line comments
+ * @since 5.2
+ */
+ public void setCommentPrefixes(String... commentPrefixes) {
+ Assert.notNull(commentPrefixes, "CommentPrefixes must not be null");
+ this.commentPrefixes = commentPrefixes;
}
/**
@@ -236,7 +249,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
for (Resource script : this.scripts) {
EncodedResource encodedScript = new EncodedResource(script, this.sqlScriptEncoding);
ScriptUtils.executeSqlScript(connection, encodedScript, this.continueOnError, this.ignoreFailedDrops,
- this.commentPrefix, this.separator, this.blockCommentStartDelimiter, this.blockCommentEndDelimiter);
+ this.commentPrefixes, this.separator, this.blockCommentStartDelimiter, this.blockCommentEndDelimiter);
}
}
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
index 6f2d2128b0f..478ee0a3e0e 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
@@ -80,6 +80,12 @@ public abstract class ScriptUtils {
*/
public static final String DEFAULT_COMMENT_PREFIX = "--";
+ /**
+ * Default prefixes for single-line comments within SQL scripts: {@code ["--"]}.
+ * @since 5.2
+ */
+ public static final String[] DEFAULT_COMMENT_PREFIXES = { DEFAULT_COMMENT_PREFIX };
+
/**
* Default start delimiter for block comments within SQL scripts: {@code "/*"}.
*/
@@ -170,9 +176,46 @@ public abstract class ScriptUtils {
String separator, String commentPrefix, String blockCommentStartDelimiter,
String blockCommentEndDelimiter, List Within the script, the provided {@code commentPrefix} will be honored:
+ * any text beginning with the comment prefix and extending to the end of the
+ * line will be omitted from the output. Similarly, the provided
+ * {@code blockCommentStartDelimiter} and {@code blockCommentEndDelimiter}
+ * delimiters will be honored: any text enclosed in a block comment will be
+ * omitted from the output. In addition, multiple adjacent whitespace characters
+ * will be collapsed into a single space.
+ * @param resource the resource from which the script was read
+ * @param script the SQL script
+ * @param separator text separating each statement
+ * (typically a ';' or newline character)
+ * @param commentPrefixes the prefixes that identify SQL line comments
+ * (typically "--")
+ * @param blockCommentStartDelimiter the start block comment delimiter;
+ * never {@code null} or empty
+ * @param blockCommentEndDelimiter the end block comment delimiter;
+ * never {@code null} or empty
+ * @param statements the list that will contain the individual statements
+ * @throws ScriptException if an error occurred while splitting the SQL script
+ * @since 5.2
+ */
+ public static void splitSqlScript(@Nullable EncodedResource resource, String script,
+ String separator, String[] commentPrefixes, String blockCommentStartDelimiter,
+ String blockCommentEndDelimiter, List Lines beginning with the comment prefix are excluded from the
+ * results; however, line comments anywhere else — for example, within
+ * a statement — will be included in the results.
+ * @param lineNumberReader the {@code LineNumberReader} containing the script
+ * to be processed
+ * @param lineCommentPrefixes the prefixes that identify comments in the SQL script
+ * (typically "--")
+ * @param separator the statement separator in the SQL script (typically ";")
+ * @param blockCommentEndDelimiter the end block comment delimiter
+ * @return a {@code String} containing the script lines
+ * @throws IOException in case of I/O errors
+ * @since 5.2
+ */
+ public static String readScript(LineNumberReader lineNumberReader, @Nullable String[] lineCommentPrefixes,
+ @Nullable String separator, @Nullable String blockCommentEndDelimiter) throws IOException {
+
String currentStatement = lineNumberReader.readLine();
StringBuilder scriptBuilder = new StringBuilder();
while (currentStatement != null) {
if ((blockCommentEndDelimiter != null && currentStatement.contains(blockCommentEndDelimiter)) ||
- (lineCommentPrefix != null && !currentStatement.startsWith(lineCommentPrefix))) {
+ (lineCommentPrefixes != null && !startsWithAny(currentStatement, lineCommentPrefixes, 0))) {
if (scriptBuilder.length() > 0) {
scriptBuilder.append('\n');
}
@@ -340,6 +407,15 @@ public abstract class ScriptUtils {
}
}
+ private static boolean startsWithAny(String script, String[] prefixes, int toffset) {
+ for (String prefix : prefixes) {
+ if (script.startsWith(prefix, toffset)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Does the provided SQL script contain the specified delimiter?
* @param script the SQL script
@@ -454,6 +530,46 @@ public abstract class ScriptUtils {
boolean ignoreFailedDrops, String commentPrefix, @Nullable String separator,
String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws ScriptException {
+ executeSqlScript(connection, resource, continueOnError, ignoreFailedDrops,
+ new String[] { commentPrefix }, separator, blockCommentStartDelimiter,
+ blockCommentEndDelimiter);
+ }
+
+ /**
+ * Execute the given SQL script.
+ * Statement separators and comments will be removed before executing
+ * individual statements within the supplied script.
+ * Warning: this method does not release the
+ * provided {@link Connection}.
+ * @param connection the JDBC connection to use to execute the script; already
+ * configured and ready to use
+ * @param resource the resource (potentially associated with a specific encoding)
+ * to load the SQL script from
+ * @param continueOnError whether or not to continue without throwing an exception
+ * in the event of an error
+ * @param ignoreFailedDrops whether or not to continue in the event of specifically
+ * an error on a {@code DROP} statement
+ * @param commentPrefixes the prefixes that identify single-line comments in the
+ * SQL script (typically "--")
+ * @param separator the script statement separator; defaults to
+ * {@value #DEFAULT_STATEMENT_SEPARATOR} if not specified and falls back to
+ * {@value #FALLBACK_STATEMENT_SEPARATOR} as a last resort; may be set to
+ * {@value #EOF_STATEMENT_SEPARATOR} to signal that the script contains a
+ * single statement without a separator
+ * @param blockCommentStartDelimiter the start block comment delimiter
+ * @param blockCommentEndDelimiter the end block comment delimiter
+ * @throws ScriptException if an error occurred while executing the SQL script
+ * @since 5.2
+ * @see #DEFAULT_STATEMENT_SEPARATOR
+ * @see #FALLBACK_STATEMENT_SEPARATOR
+ * @see #EOF_STATEMENT_SEPARATOR
+ * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection
+ * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
+ */
+ public static void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError,
+ boolean ignoreFailedDrops, String[] commentPrefixes, @Nullable String separator,
+ String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws ScriptException {
+
try {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL script from " + resource);
@@ -462,7 +578,7 @@ public abstract class ScriptUtils {
String script;
try {
- script = readScript(resource, commentPrefix, separator, blockCommentEndDelimiter);
+ script = readScript(resource, commentPrefixes, separator, blockCommentEndDelimiter);
}
catch (IOException ex) {
throw new CannotReadScriptException(resource, ex);
@@ -476,7 +592,7 @@ public abstract class ScriptUtils {
}
List