Polish ScriptUtils internals in spring-r2dbc
See gh-26947
This commit is contained in:
parent
101ed17b6f
commit
fab7b1cebe
|
|
@ -106,8 +106,8 @@ public abstract class ScriptUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split an SQL script into separate statements delimited by the provided
|
* Split an SQL script into separate statements delimited by the provided
|
||||||
* separator string. Each individual statement will be added to the provided
|
* separator string and return a {@code List} containing each individual
|
||||||
* {@code List}.
|
* statement.
|
||||||
* <p>Within the script, the provided {@code commentPrefixes} will be honored:
|
* <p>Within the script, the provided {@code commentPrefixes} will be honored:
|
||||||
* any text beginning with one of the comment prefixes and extending to the
|
* any text beginning with one of the comment prefixes and extending to the
|
||||||
* end of the line will be omitted from the output. Similarly, the provided
|
* end of the line will be omitted from the output. Similarly, the provided
|
||||||
|
|
@ -125,12 +125,12 @@ public abstract class ScriptUtils {
|
||||||
* never {@code null} or empty
|
* never {@code null} or empty
|
||||||
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter;
|
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter;
|
||||||
* never {@code null} or empty
|
* never {@code null} or empty
|
||||||
* @param statements the list that will contain the individual statements
|
* @return a list of statements
|
||||||
* @throws ScriptException if an error occurred while splitting the SQL script
|
* @throws ScriptException if an error occurred while splitting the SQL script
|
||||||
*/
|
*/
|
||||||
static void splitSqlScript(@Nullable EncodedResource resource, String script,
|
static List<String> splitSqlScript(EncodedResource resource, String script,
|
||||||
String separator, String[] commentPrefixes, String blockCommentStartDelimiter,
|
String separator, String[] commentPrefixes, String blockCommentStartDelimiter,
|
||||||
String blockCommentEndDelimiter, List<String> statements) throws ScriptException {
|
String blockCommentEndDelimiter) throws ScriptException {
|
||||||
|
|
||||||
Assert.hasText(script, "'script' must not be null or empty");
|
Assert.hasText(script, "'script' must not be null or empty");
|
||||||
Assert.notNull(separator, "'separator' must not be null");
|
Assert.notNull(separator, "'separator' must not be null");
|
||||||
|
|
@ -141,6 +141,7 @@ public abstract class ScriptUtils {
|
||||||
Assert.hasText(blockCommentStartDelimiter, "'blockCommentStartDelimiter' must not be null or empty");
|
Assert.hasText(blockCommentStartDelimiter, "'blockCommentStartDelimiter' must not be null or empty");
|
||||||
Assert.hasText(blockCommentEndDelimiter, "'blockCommentEndDelimiter' must not be null or empty");
|
Assert.hasText(blockCommentEndDelimiter, "'blockCommentEndDelimiter' must not be null or empty");
|
||||||
|
|
||||||
|
List<String> statements = new ArrayList<>();
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
boolean inSingleQuote = false;
|
boolean inSingleQuote = false;
|
||||||
boolean inDoubleQuote = false;
|
boolean inDoubleQuote = false;
|
||||||
|
|
@ -215,26 +216,22 @@ public abstract class ScriptUtils {
|
||||||
if (StringUtils.hasText(sb)) {
|
if (StringUtils.hasText(sb)) {
|
||||||
statements.add(sb.toString());
|
statements.add(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a script from the provided resource, using the supplied comment prefixes
|
* Read a script from the provided resource, using the supplied statement
|
||||||
* and statement separator, and build a {@code String} containing the lines.
|
* separator, and build a {@code String} containing the lines.
|
||||||
* <p>Lines <em>beginning</em> with one of the comment prefixes are excluded
|
* @param resource the {@code EncodedResource} containing the script to be
|
||||||
* from the results; however, line comments anywhere else — for example,
|
* processed
|
||||||
* within a statement — will be included in the results.
|
|
||||||
* @param resource the {@code EncodedResource} containing the script
|
|
||||||
* to be processed
|
|
||||||
* @param dataBufferFactory the factory to create data buffers with
|
* @param dataBufferFactory the factory to create data buffers with
|
||||||
* @param separator the statement separator in the SQL script (typically ";")
|
* @param separator the statement separator in the SQL script (typically ";")
|
||||||
* @param commentPrefixes the prefixes that identify comments in the SQL script
|
|
||||||
* (typically "--")
|
|
||||||
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter
|
|
||||||
* @return a {@link Mono} of {@link String} containing the script lines that
|
* @return a {@link Mono} of {@link String} containing the script lines that
|
||||||
* completes once the resource was loaded
|
* completes once the resource has been loaded
|
||||||
*/
|
*/
|
||||||
static Mono<String> readScript(EncodedResource resource, DataBufferFactory dataBufferFactory,
|
static Mono<String> readScript(EncodedResource resource, DataBufferFactory dataBufferFactory,
|
||||||
@Nullable String separator, @Nullable String[] commentPrefixes, @Nullable String blockCommentEndDelimiter) {
|
@Nullable String separator) {
|
||||||
|
|
||||||
return DataBufferUtils.join(DataBufferUtils.read(resource.getResource(), dataBufferFactory, 8192))
|
return DataBufferUtils.join(DataBufferUtils.read(resource.getResource(), dataBufferFactory, 8192))
|
||||||
.handle((it, sink) -> {
|
.handle((it, sink) -> {
|
||||||
|
|
@ -322,7 +319,7 @@ public abstract class ScriptUtils {
|
||||||
* (typically <code>"*/"</code>)
|
* (typically <code>"*/"</code>)
|
||||||
* @since 5.3.8
|
* @since 5.3.8
|
||||||
*/
|
*/
|
||||||
static boolean containsStatementSeparator(@Nullable EncodedResource resource, String script,
|
static boolean containsStatementSeparator(EncodedResource resource, String script,
|
||||||
String separator, String[] commentPrefixes, String blockCommentStartDelimiter,
|
String separator, String[] commentPrefixes, String blockCommentStartDelimiter,
|
||||||
String blockCommentEndDelimiter) throws ScriptException {
|
String blockCommentEndDelimiter) throws ScriptException {
|
||||||
|
|
||||||
|
|
@ -514,13 +511,12 @@ public abstract class ScriptUtils {
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
Mono<String> inputScript = readScript(resource, dataBufferFactory, separator, commentPrefixes, blockCommentEndDelimiter)
|
Mono<String> inputScript = readScript(resource, dataBufferFactory, separator)
|
||||||
.onErrorMap(IOException.class, ex -> new CannotReadScriptException(resource, ex));
|
.onErrorMap(IOException.class, ex -> new CannotReadScriptException(resource, ex));
|
||||||
|
|
||||||
AtomicInteger statementNumber = new AtomicInteger();
|
AtomicInteger statementNumber = new AtomicInteger();
|
||||||
|
|
||||||
Flux<Void> executeScript = inputScript.flatMapIterable(script -> {
|
Flux<Void> executeScript = inputScript.flatMapIterable(script -> {
|
||||||
List<String> statements = new ArrayList<>();
|
|
||||||
String separatorToUse = separator;
|
String separatorToUse = separator;
|
||||||
if (separatorToUse == null) {
|
if (separatorToUse == null) {
|
||||||
separatorToUse = DEFAULT_STATEMENT_SEPARATOR;
|
separatorToUse = DEFAULT_STATEMENT_SEPARATOR;
|
||||||
|
|
@ -530,9 +526,8 @@ public abstract class ScriptUtils {
|
||||||
blockCommentStartDelimiter, blockCommentEndDelimiter)) {
|
blockCommentStartDelimiter, blockCommentEndDelimiter)) {
|
||||||
separatorToUse = FALLBACK_STATEMENT_SEPARATOR;
|
separatorToUse = FALLBACK_STATEMENT_SEPARATOR;
|
||||||
}
|
}
|
||||||
splitSqlScript(resource, script, separatorToUse, commentPrefixes, blockCommentStartDelimiter,
|
return splitSqlScript(resource, script, separatorToUse, commentPrefixes,
|
||||||
blockCommentEndDelimiter, statements);
|
blockCommentStartDelimiter, blockCommentEndDelimiter);
|
||||||
return statements;
|
|
||||||
}).concatMap(statement -> {
|
}).concatMap(statement -> {
|
||||||
statementNumber.incrementAndGet();
|
statementNumber.incrementAndGet();
|
||||||
return runStatement(statement, connection, resource, continueOnError, ignoreFailedDrops, statementNumber);
|
return runStatement(statement, connection, resource, continueOnError, ignoreFailedDrops, statementNumber);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.r2dbc.connection.init;
|
package org.springframework.r2dbc.connection.init;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.assertj.core.util.Strings;
|
import org.assertj.core.util.Strings;
|
||||||
|
|
@ -60,8 +59,7 @@ public class ScriptUtilsUnitTests {
|
||||||
String delimiter = ";";
|
String delimiter = ";";
|
||||||
String script = Strings.join(rawStatement1, rawStatement2, rawStatement3).with(delimiter);
|
String script = Strings.join(rawStatement1, rawStatement2, rawStatement3).with(delimiter);
|
||||||
|
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, delimiter);
|
||||||
splitSqlScript(script, delimiter, statements);
|
|
||||||
|
|
||||||
assertThat(statements).containsExactly(cleanedStatement1, cleanedStatement2, cleanedStatement3);
|
assertThat(statements).containsExactly(cleanedStatement1, cleanedStatement2, cleanedStatement3);
|
||||||
}
|
}
|
||||||
|
|
@ -75,8 +73,7 @@ public class ScriptUtilsUnitTests {
|
||||||
String delimiter = "\n";
|
String delimiter = "\n";
|
||||||
String script = Strings.join(statement1, statement2, statement3).with(delimiter);
|
String script = Strings.join(statement1, statement2, statement3).with(delimiter);
|
||||||
|
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, delimiter);
|
||||||
splitSqlScript(script, delimiter, statements);
|
|
||||||
|
|
||||||
assertThat(statements).containsExactly(statement1, statement2, statement3);
|
assertThat(statements).containsExactly(statement1, statement2, statement3);
|
||||||
}
|
}
|
||||||
|
|
@ -88,9 +85,7 @@ public class ScriptUtilsUnitTests {
|
||||||
|
|
||||||
String script = Strings.join(statement1, statement2).with("\n");
|
String script = Strings.join(statement1, statement2).with("\n");
|
||||||
|
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, DEFAULT_STATEMENT_SEPARATOR);
|
||||||
|
|
||||||
splitSqlScript(script, DEFAULT_STATEMENT_SEPARATOR, statements);
|
|
||||||
|
|
||||||
assertThat(statements).as("stripped but not split statements").containsExactly(script.replace('\n', ' '));
|
assertThat(statements).as("stripped but not split statements").containsExactly(script.replace('\n', ' '));
|
||||||
}
|
}
|
||||||
|
|
@ -103,8 +98,7 @@ public class ScriptUtilsUnitTests {
|
||||||
String delimiter = ";";
|
String delimiter = ";";
|
||||||
String script = Strings.join(statement1, statement2).with(delimiter);
|
String script = Strings.join(statement1, statement2).with(delimiter);
|
||||||
|
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, delimiter);
|
||||||
splitSqlScript(script, delimiter, statements);
|
|
||||||
|
|
||||||
assertThat(statements).containsExactly(statement1, statement2);
|
assertThat(statements).containsExactly(statement1, statement2);
|
||||||
}
|
}
|
||||||
|
|
@ -112,8 +106,7 @@ public class ScriptUtilsUnitTests {
|
||||||
@Test // SPR-11560
|
@Test // SPR-11560
|
||||||
public void readAndSplitScriptWithMultipleNewlinesAsSeparator() throws Exception {
|
public void readAndSplitScriptWithMultipleNewlinesAsSeparator() throws Exception {
|
||||||
String script = readScript("db-test-data-multi-newline.sql");
|
String script = readScript("db-test-data-multi-newline.sql");
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, "\n\n");
|
||||||
splitSqlScript(script, "\n\n", statements);
|
|
||||||
|
|
||||||
String statement1 = "insert into T_TEST (NAME) values ('Keith')";
|
String statement1 = "insert into T_TEST (NAME) values ('Keith')";
|
||||||
String statement2 = "insert into T_TEST (NAME) values ('Dave')";
|
String statement2 = "insert into T_TEST (NAME) values ('Dave')";
|
||||||
|
|
@ -140,9 +133,8 @@ public class ScriptUtilsUnitTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void splitScriptContainingComments(String script, String... commentPrefixes) {
|
private void splitScriptContainingComments(String script, String... commentPrefixes) {
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = ScriptUtils.splitSqlScript(null, script, ";", commentPrefixes, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||||
ScriptUtils.splitSqlScript(null, script, ";", commentPrefixes, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||||
DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements);
|
|
||||||
|
|
||||||
String statement1 = "insert into customer (id, name) values (1, 'Rod; Johnson'), (2, 'Adrian Collier')";
|
String statement1 = "insert into customer (id, name) values (1, 'Rod; Johnson'), (2, 'Adrian Collier')";
|
||||||
String statement2 = "insert into orders(id, order_date, customer_id) values (1, '2008-01-02', 2)";
|
String statement2 = "insert into orders(id, order_date, customer_id) values (1, '2008-01-02', 2)";
|
||||||
|
|
@ -156,8 +148,7 @@ public class ScriptUtilsUnitTests {
|
||||||
@Test // SPR-10330
|
@Test // SPR-10330
|
||||||
public void readAndSplitScriptContainingCommentsWithLeadingTabs() throws Exception {
|
public void readAndSplitScriptContainingCommentsWithLeadingTabs() throws Exception {
|
||||||
String script = readScript("test-data-with-comments-and-leading-tabs.sql");
|
String script = readScript("test-data-with-comments-and-leading-tabs.sql");
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, ";");
|
||||||
splitSqlScript(script, ";", statements);
|
|
||||||
|
|
||||||
String statement1 = "insert into customer (id, name) values (1, 'Sam Brannen')";
|
String statement1 = "insert into customer (id, name) values (1, 'Sam Brannen')";
|
||||||
String statement2 = "insert into orders(id, order_date, customer_id) values (1, '2013-06-08', 1)";
|
String statement2 = "insert into orders(id, order_date, customer_id) values (1, '2013-06-08', 1)";
|
||||||
|
|
@ -169,8 +160,7 @@ public class ScriptUtilsUnitTests {
|
||||||
@Test // SPR-9531
|
@Test // SPR-9531
|
||||||
public void readAndSplitScriptContainingMultiLineComments() throws Exception {
|
public void readAndSplitScriptContainingMultiLineComments() throws Exception {
|
||||||
String script = readScript("test-data-with-multi-line-comments.sql");
|
String script = readScript("test-data-with-multi-line-comments.sql");
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, ";");
|
||||||
splitSqlScript(script, ";", statements);
|
|
||||||
|
|
||||||
String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')";
|
String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')";
|
||||||
String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )";
|
String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )";
|
||||||
|
|
@ -181,8 +171,7 @@ public class ScriptUtilsUnitTests {
|
||||||
@Test
|
@Test
|
||||||
public void readAndSplitScriptContainingMultiLineNestedComments() throws Exception {
|
public void readAndSplitScriptContainingMultiLineNestedComments() throws Exception {
|
||||||
String script = readScript("test-data-with-multi-line-nested-comments.sql");
|
String script = readScript("test-data-with-multi-line-nested-comments.sql");
|
||||||
List<String> statements = new ArrayList<>();
|
List<String> statements = splitSqlScript(script, ";");
|
||||||
splitSqlScript(script, ";", statements);
|
|
||||||
|
|
||||||
String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')";
|
String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')";
|
||||||
String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )";
|
String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )";
|
||||||
|
|
@ -231,13 +220,12 @@ public class ScriptUtilsUnitTests {
|
||||||
|
|
||||||
private String readScript(String path) throws Exception {
|
private String readScript(String path) throws Exception {
|
||||||
EncodedResource resource = new EncodedResource(new ClassPathResource(path, getClass()));
|
EncodedResource resource = new EncodedResource(new ClassPathResource(path, getClass()));
|
||||||
return ScriptUtils.readScript(resource, DefaultDataBufferFactory.sharedInstance, DEFAULT_STATEMENT_SEPARATOR,
|
return ScriptUtils.readScript(resource, DefaultDataBufferFactory.sharedInstance, DEFAULT_STATEMENT_SEPARATOR).block();
|
||||||
DEFAULT_COMMENT_PREFIXES, DEFAULT_BLOCK_COMMENT_END_DELIMITER).block();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void splitSqlScript(String script, String separator, List<String> statements) throws ScriptException {
|
private static List<String> splitSqlScript(String script, String separator) throws ScriptException {
|
||||||
ScriptUtils.splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIXES, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
return ScriptUtils.splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIXES, DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||||
DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements);
|
DEFAULT_BLOCK_COMMENT_END_DELIMITER);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue