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 f43a42304d..68918f5150 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 @@ -26,6 +26,7 @@ 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.support.EncodedResource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -53,6 +54,13 @@ public abstract class ScriptUtils { */ public static final String DEFAULT_STATEMENT_SEPARATOR = ";"; + /** + * Fallback statement separator within SQL scripts. + *

Used if neither a custom defined separator nor the + * {@link #DEFAULT_STATEMENT_SEPARATOR} is present in a given script. + */ + public static final String FALLBACK_STATEMENT_SEPARATOR = "\n"; + /** * Default prefix for line comments within SQL scripts. */ @@ -78,7 +86,7 @@ public abstract class ScriptUtils { /** * Split an SQL script into separate statements delimited by the provided - * delimiter character. Each individual statement will be added to the + * separator character. Each individual statement will be added to the * provided {@code List}. *

Within the script, {@value #DEFAULT_COMMENT_PREFIX} will be used as the * comment prefix; any text beginning with the comment prefix and extending to @@ -89,18 +97,41 @@ public abstract class ScriptUtils { * in a block comment will be omitted from the output. In addition, multiple * adjacent whitespace characters will be collapsed into a single space. * @param script the SQL script - * @param delimiter character delimiting each statement — typically a ';' character + * @param separator character separating each statement — typically a ';' * @param statements the list that will contain the individual statements + * @see #splitSqlScript(String, String, List) * @see #splitSqlScript(EncodedResource, String, String, String, String, String, List) */ - public static void splitSqlScript(String script, char delimiter, List statements) throws ScriptException { - splitSqlScript(null, script, String.valueOf(delimiter), DEFAULT_COMMENT_PREFIX, - DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements); + public static void splitSqlScript(String script, char separator, List statements) throws ScriptException { + splitSqlScript(script, String.valueOf(separator), statements); } /** * Split an SQL script into separate statements delimited by the provided - * delimiter string. Each individual statement will be added to the provided + * separator string. Each individual statement will be added to the + * provided {@code List}. + *

Within the script, {@value #DEFAULT_COMMENT_PREFIX} will be used as the + * comment prefix; any text beginning with the comment prefix and extending to + * the end of the line will be omitted from the output. Similarly, + * {@value #DEFAULT_BLOCK_COMMENT_START_DELIMITER} and + * {@value #DEFAULT_BLOCK_COMMENT_END_DELIMITER} will be used as the + * start and end block comment delimiters: 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 script the SQL script + * @param separator text separating each statement — typically a ';' or newline character + * @param statements the list that will contain the individual statements + * @see #splitSqlScript(String, char, List) + * @see #splitSqlScript(EncodedResource, String, String, String, String, String, List) + */ + public static void splitSqlScript(String script, String separator, List statements) throws ScriptException { + splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIX, DEFAULT_BLOCK_COMMENT_START_DELIMITER, + DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements); + } + + /** + * Split an SQL script into separate statements delimited by the provided + * separator string. Each individual statement will be added to the provided * {@code 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 @@ -111,8 +142,8 @@ public abstract class ScriptUtils { * will be collapsed into a single space. * @param resource the resource from which the script was read * @param script the SQL script; never {@code null} or empty - * @param delimiter text delimiting each statement — typically a ';' - * character; never {@code null} + * @param separator text separating each statement — typically a ';' or + * newline character; never {@code null} * @param commentPrefix the prefix that identifies SQL line comments — * typically "--"; never {@code null} or empty * @param blockCommentStartDelimiter the start block comment delimiter; @@ -121,12 +152,12 @@ public abstract class ScriptUtils { * never {@code null} or empty * @param statements the list that will contain the individual statements */ - public static void splitSqlScript(EncodedResource resource, String script, String delimiter, String commentPrefix, + public static void splitSqlScript(EncodedResource resource, String script, String separator, String commentPrefix, String blockCommentStartDelimiter, String blockCommentEndDelimiter, List statements) throws ScriptException { Assert.hasText(script, "script must not be null or empty"); - Assert.notNull(delimiter, "delimiter must not be null"); + Assert.notNull(separator, "separator must not be null"); Assert.hasText(commentPrefix, "commentPrefix 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"); @@ -152,13 +183,13 @@ public abstract class ScriptUtils { inLiteral = !inLiteral; } if (!inLiteral) { - if (script.startsWith(delimiter, i)) { + if (script.startsWith(separator, i)) { // we've reached the end of the current statement if (sb.length() > 0) { statements.add(sb.toString()); sb = new StringBuilder(); } - i += delimiter.length() - 1; + i += separator.length() - 1; continue; } else if (script.startsWith(commentPrefix, i)) { @@ -215,9 +246,8 @@ public abstract class ScriptUtils { } /** - * Read a script from the provided resource, using the supplied - * comment prefix and statement separator, and build a {@code String} containing - * the lines. + * Read a script from the provided resource, using the supplied comment prefix + * and statement separator, and build a {@code String} containing the lines. *

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. @@ -258,8 +288,7 @@ public abstract class ScriptUtils { String currentStatement = lineNumberReader.readLine(); StringBuilder scriptBuilder = new StringBuilder(); while (currentStatement != null) { - if (StringUtils.hasText(currentStatement) - && (commentPrefix != null && !currentStatement.startsWith(commentPrefix))) { + if (commentPrefix != null && !currentStatement.startsWith(commentPrefix)) { if (scriptBuilder.length() > 0) { scriptBuilder.append('\n'); } @@ -267,11 +296,11 @@ public abstract class ScriptUtils { } currentStatement = lineNumberReader.readLine(); } - maybeAddSeparatorToScript(scriptBuilder, separator); + appendSeparatorToScriptIfNecessary(scriptBuilder, separator); return scriptBuilder.toString(); } - private static void maybeAddSeparatorToScript(StringBuilder scriptBuilder, String separator) { + private static void appendSeparatorToScriptIfNecessary(StringBuilder scriptBuilder, String separator) { if (separator == null) { return; } @@ -305,6 +334,48 @@ public abstract class ScriptUtils { return false; } + /** + * Execute the given SQL script using default settings for separator separators, + * comment delimiters, and exception handling flags. + *

Statement separators and comments will be removed before executing + * individual statements within the supplied script. + *

Do not use this method to execute DDL if you expect rollback. + * @param connection the JDBC connection to use to execute the script; already + * configured and ready to use + * @param resource the resource to load the SQL script from; encoded with the + * current platform's default encoding + * @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String) + * @see #DEFAULT_COMMENT_PREFIX + * @see #DEFAULT_STATEMENT_SEPARATOR + * @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER + * @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER + */ + public static void executeSqlScript(Connection connection, Resource resource) throws SQLException, ScriptException { + executeSqlScript(connection, new EncodedResource(resource)); + } + + /** + * Execute the given SQL script using default settings for separator separators, + * comment delimiters, and exception handling flags. + *

Statement separators and comments will be removed before executing + * individual statements within the supplied script. + *

Do not use this method to execute DDL if you expect rollback. + * @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 + * @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String) + * @see #DEFAULT_COMMENT_PREFIX + * @see #DEFAULT_STATEMENT_SEPARATOR + * @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER + * @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER + */ + public static void executeSqlScript(Connection connection, EncodedResource resource) throws SQLException, + ScriptException { + executeSqlScript(connection, resource, false, false, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR, + DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER); + } + /** * Execute the given SQL script. *

Statement separators and comments will be removed before executing @@ -321,7 +392,8 @@ public abstract class ScriptUtils { * @param commentPrefix the prefix that identifies comments in the SQL script — * typically "--" * @param separator the script statement separator; defaults to - * {@value #DEFAULT_STATEMENT_SEPARATOR} if not specified + * {@value #DEFAULT_STATEMENT_SEPARATOR} if not specified and falls back to + * {@value #FALLBACK_STATEMENT_SEPARATOR} as a last resort * @param blockCommentStartDelimiter the start block comment delimiter; never * {@code null} or empty * @param blockCommentEndDelimiter the end block comment delimiter; never @@ -346,9 +418,9 @@ public abstract class ScriptUtils { if (separator == null) { separator = DEFAULT_STATEMENT_SEPARATOR; - if (!containsSqlScriptDelimiters(script, separator)) { - separator = "\n"; - } + } + if (!containsSqlScriptDelimiters(script, separator)) { + separator = FALLBACK_STATEMENT_SEPARATOR; } splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter, diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java new file mode 100644 index 0000000000..7d85f92cb2 --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java @@ -0,0 +1,64 @@ +/* + * 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. + * 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.jdbc.datasource.init; + +import org.junit.After; +import org.junit.Before; +import org.springframework.core.io.ClassRelativeResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +/** + * Abstract base class for integration tests involving database initialization. + * + * @author Sam Brannen + * @since 4.0.3 + */ +public abstract class AbstractDatabaseInitializationTests { + + private final ClassRelativeResourceLoader resourceLoader = new ClassRelativeResourceLoader(getClass()); + + protected EmbeddedDatabase db; + protected JdbcTemplate jdbcTemplate; + + + @Before + public void setUp() { + db = new EmbeddedDatabaseBuilder().setType(getEmbeddedDatabaseType()).build(); + jdbcTemplate = new JdbcTemplate(db); + } + + @After + public void shutDown() { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.clear(); + TransactionSynchronizationManager.unbindResource(db); + } + db.shutdown(); + } + + protected abstract EmbeddedDatabaseType getEmbeddedDatabaseType(); + + protected Resource resource(String path) { + return resourceLoader.getResource(path); + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java similarity index 89% rename from spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java rename to spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java index 571b744384..f26116b54a 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java @@ -19,14 +19,9 @@ package org.springframework.jdbc.datasource.init; import java.sql.Connection; import java.sql.SQLException; -import org.junit.After; import org.junit.Test; -import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.core.io.Resource; -import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.transaction.support.TransactionSynchronizationManager; import static org.hamcrest.Matchers.*; @@ -34,57 +29,16 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; /** + * Abstract base class for integration tests for {@link ResourceDatabasePopulator}. + * * @author Dave Syer * @author Sam Brannen * @author Oliver Gierke */ -public class DatabasePopulatorTests { - - private final EmbeddedDatabase db = new EmbeddedDatabaseBuilder().build(); +public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseInitializationTests { private final ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - private final ClassRelativeResourceLoader resourceLoader = new ClassRelativeResourceLoader(getClass()); - - private final JdbcTemplate jdbcTemplate = new JdbcTemplate(db); - - - private void assertTestDatabaseCreated() { - assertTestDatabaseCreated("Keith"); - } - - private void assertTestDatabaseCreated(String name) { - assertEquals(name, jdbcTemplate.queryForObject("select NAME from T_TEST", String.class)); - } - - private void assertUsersDatabaseCreated(String... lastNames) { - for (String lastName : lastNames) { - assertThat("Did not find user with last name [" + lastName + "].", - jdbcTemplate.queryForObject("select count(0) from users where last_name = ?", Integer.class, lastName), - equalTo(1)); - } - } - - private Resource resource(String path) { - return resourceLoader.getResource(path); - } - - private Resource defaultSchema() { - return resource("db-schema.sql"); - } - - private Resource usersSchema() { - return resource("users-schema.sql"); - } - - @After - public void shutDown() { - if (TransactionSynchronizationManager.isSynchronizationActive()) { - TransactionSynchronizationManager.clear(); - TransactionSynchronizationManager.unbindResource(db); - } - db.shutdown(); - } @Test public void buildWithCommentsAndFailedDrop() throws Exception { @@ -226,4 +180,28 @@ public class DatabasePopulatorTests { DatabasePopulatorUtils.execute(databasePopulator, db); } + private void assertTestDatabaseCreated() { + assertTestDatabaseCreated("Keith"); + } + + private void assertTestDatabaseCreated(String name) { + assertEquals(name, jdbcTemplate.queryForObject("select NAME from T_TEST", String.class)); + } + + private void assertUsersDatabaseCreated(String... lastNames) { + for (String lastName : lastNames) { + assertThat("Did not find user with last name [" + lastName + "].", + jdbcTemplate.queryForObject("select count(0) from users where last_name = ?", Integer.class, lastName), + equalTo(1)); + } + } + + private Resource defaultSchema() { + return resource("db-schema.sql"); + } + + private Resource usersSchema() { + return resource("users-schema.sql"); + } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java new file mode 100644 index 0000000000..699ea75b1a --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/H2DatabasePopulatorTests.java @@ -0,0 +1,31 @@ +/* + * 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. + * 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.jdbc.datasource.init; + +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +/** + * @author Sam Brannen + * @since 4.0.3 + */ +public class H2DatabasePopulatorTests extends AbstractDatabasePopulatorTests { + + protected EmbeddedDatabaseType getEmbeddedDatabaseType() { + return EmbeddedDatabaseType.H2; + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java new file mode 100644 index 0000000000..9ab79b6054 --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/HsqlDatabasePopulatorTests.java @@ -0,0 +1,31 @@ +/* + * 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. + * 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.jdbc.datasource.init; + +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +/** + * @author Sam Brannen + * @since 4.0.3 + */ +public class HsqlDatabasePopulatorTests extends AbstractDatabasePopulatorTests { + + protected EmbeddedDatabaseType getEmbeddedDatabaseType() { + return EmbeddedDatabaseType.HSQL; + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java new file mode 100644 index 0000000000..f7d8f18092 --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java @@ -0,0 +1,58 @@ +/* + * 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. + * 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.jdbc.datasource.init; + +import java.sql.SQLException; + +import org.junit.Test; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +/** + * Integration tests for {@link ScriptUtils}. + * + * @author Sam Brannen + * @see ScriptUtilsUnitTests + * @since 4.0.3 + */ +public class ScriptUtilsIntegrationTests extends AbstractDatabaseInitializationTests { + + protected EmbeddedDatabaseType getEmbeddedDatabaseType() { + return EmbeddedDatabaseType.HSQL; + } + + @Test + public void executeSqlScript() throws SQLException { + ScriptUtils.executeSqlScript(db.getConnection(), resource("users-schema.sql")); + ScriptUtils.executeSqlScript(db.getConnection(), resource("test-data-with-multi-line-comments.sql")); + + assertUsersDatabaseCreated("Hoeller", "Brannen"); + } + + private void assertUsersDatabaseCreated(String... lastNames) { + final JdbcTemplate jdbcTemplate = new JdbcTemplate(db); + for (String lastName : lastNames) { + assertThat("Did not find user with last name [" + lastName + "].", + jdbcTemplate.queryForObject("select count(0) from users where last_name = ?", Integer.class, lastName), + equalTo(1)); + } + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java similarity index 61% rename from spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsTests.java rename to spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java index dff78a50b9..6df2eb1793 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java @@ -16,44 +16,27 @@ package org.springframework.jdbc.datasource.init; -import java.sql.Connection; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import org.junit.After; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.EncodedResource; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.springframework.jdbc.datasource.init.ScriptUtils.*; /** - * Unit and integration tests for {@link ScriptUtils}. + * Unit tests for {@link ScriptUtils}. * * @author Thomas Risberg * @author Sam Brannen * @author Phillip Webb * @author Chris Baldwin + * @see ScriptUtilsIntegrationTests + * @since 4.0.3 */ -public class ScriptUtilsTests { - - private final EmbeddedDatabase db = new EmbeddedDatabaseBuilder().build(); - - - @After - public void shutDown() { - if (TransactionSynchronizationManager.isSynchronizationActive()) { - TransactionSynchronizationManager.clear(); - TransactionSynchronizationManager.unbindResource(db); - } - db.shutdown(); - } +public class ScriptUtilsUnitTests { @Test public void splitSqlScriptDelimitedWithSemicolon() { @@ -66,7 +49,7 @@ public class ScriptUtilsTests { char delim = ';'; String script = rawStatement1 + delim + rawStatement2 + delim + rawStatement3 + delim; List statements = new ArrayList(); - ScriptUtils.splitSqlScript(script, delim, statements); + splitSqlScript(script, delim, statements); assertEquals("wrong number of statements", 3, statements.size()); assertEquals("statement 1 not split correctly", cleanedStatement1, statements.get(0)); assertEquals("statement 2 not split correctly", cleanedStatement2, statements.get(1)); @@ -81,7 +64,7 @@ public class ScriptUtilsTests { char delim = '\n'; String script = statement1 + delim + statement2 + delim + statement3 + delim; List statements = new ArrayList(); - ScriptUtils.splitSqlScript(script, delim, statements); + splitSqlScript(script, delim, statements); assertEquals("wrong number of statements", 3, statements.size()); assertEquals("statement 1 not split correctly", statement1, statements.get(0)); assertEquals("statement 2 not split correctly", statement2, statements.get(1)); @@ -89,14 +72,40 @@ public class ScriptUtilsTests { } @Test - public void readAndSplitScriptContainingComments() throws Exception { - EncodedResource resource = new EncodedResource(new ClassPathResource("test-data-with-comments.sql", getClass())); - - String script = ScriptUtils.readScript(resource); - - char delim = ';'; + public void splitSqlScriptDelimitedWithNewLineButDefaultDelimiterSpecified() { + String statement1 = "do something"; + String statement2 = "do something else"; + char delim = '\n'; + String script = statement1 + delim + statement2 + delim; List statements = new ArrayList(); - ScriptUtils.splitSqlScript(script, delim, statements); + splitSqlScript(script, DEFAULT_STATEMENT_SEPARATOR, statements); + assertEquals("wrong number of statements", 1, statements.size()); + assertEquals("script should have been 'stripped' but not actually 'split'", script.replace('\n', ' '), + statements.get(0)); + } + + /** + * See SPR-11560 + */ + @Test + public void readAndSplitScriptWithMultipleNewlinesAsSeparator() throws Exception { + String script = readScript("db-test-data-multi-newline.sql"); + List statements = new ArrayList(); + splitSqlScript(script, "\n\n", statements); + + String statement1 = "insert into T_TEST (NAME) values ('Keith')"; + String statement2 = "insert into T_TEST (NAME) values ('Dave')"; + + assertEquals("wrong number of statements", 2, statements.size()); + assertEquals("statement 1 not split correctly", statement1, statements.get(0)); + assertEquals("statement 2 not split correctly", statement2, statements.get(1)); + } + + @Test + public void readAndSplitScriptContainingComments() throws Exception { + String script = readScript("test-data-with-comments.sql"); + List statements = new ArrayList(); + splitSqlScript(script, ';', statements); 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)"; @@ -112,18 +121,13 @@ public class ScriptUtilsTests { } /** - * See SPR-10330 + * See SPR-10330 */ @Test public void readAndSplitScriptContainingCommentsWithLeadingTabs() throws Exception { - EncodedResource resource = new EncodedResource(new ClassPathResource( - "test-data-with-comments-and-leading-tabs.sql", getClass())); - - String script = ScriptUtils.readScript(resource); - - char delim = ';'; + String script = readScript("test-data-with-comments-and-leading-tabs.sql"); List statements = new ArrayList(); - ScriptUtils.splitSqlScript(script, delim, statements); + splitSqlScript(script, ';', statements); 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)"; @@ -136,18 +140,13 @@ public class ScriptUtilsTests { } /** - * See SPR-9531 + * See SPR-9531 */ @Test public void readAndSplitScriptContainingMuliLineComments() throws Exception { - EncodedResource resource = new EncodedResource(new ClassPathResource("test-data-with-multi-line-comments.sql", - getClass())); - - String script = ScriptUtils.readScript(resource); - - char delim = ';'; + String script = readScript("test-data-with-multi-line-comments.sql"); List statements = new ArrayList(); - ScriptUtils.splitSqlScript(script, delim, statements); + splitSqlScript(script, ';', statements); String statement1 = "INSERT INTO users(first_name, last_name) VALUES('Juergen', 'Hoeller')"; String statement2 = "INSERT INTO users(first_name, last_name) VALUES( 'Sam' , 'Brannen' )"; @@ -159,38 +158,15 @@ public class ScriptUtilsTests { @Test public void containsDelimiters() { - assertTrue("test with ';' is wrong", !ScriptUtils.containsSqlScriptDelimiters("select 1\n select ';'", ";")); - assertTrue("test with delimiter ; is wrong", ScriptUtils.containsSqlScriptDelimiters("select 1; select 2", ";")); - assertTrue("test with '\\n' is wrong", - !ScriptUtils.containsSqlScriptDelimiters("select 1; select '\\n\n';", "\n")); - assertTrue("test with delimiter \\n is wrong", - ScriptUtils.containsSqlScriptDelimiters("select 1\n select 2", "\n")); + assertTrue("test with ';' is wrong", !containsSqlScriptDelimiters("select 1\n select ';'", ";")); + assertTrue("test with delimiter ; is wrong", containsSqlScriptDelimiters("select 1; select 2", ";")); + assertTrue("test with '\\n' is wrong", !containsSqlScriptDelimiters("select 1; select '\\n\n';", "\n")); + assertTrue("test with delimiter \\n is wrong", containsSqlScriptDelimiters("select 1\n select 2", "\n")); } - @Test - public void executeSqlScript() throws SQLException { - EncodedResource schemaResource = new EncodedResource(new ClassPathResource("users-schema.sql", getClass())); - EncodedResource commentResource = new EncodedResource(new ClassPathResource( - "test-data-with-multi-line-comments.sql", getClass())); - Connection connection = db.getConnection(); - - ScriptUtils.executeSqlScript(connection, schemaResource, false, false, ScriptUtils.DEFAULT_COMMENT_PREFIX, - ScriptUtils.DEFAULT_STATEMENT_SEPARATOR, ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER, - ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER); - ScriptUtils.executeSqlScript(connection, commentResource, false, false, ScriptUtils.DEFAULT_COMMENT_PREFIX, - ScriptUtils.DEFAULT_STATEMENT_SEPARATOR, ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER, - ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER); - - assertUsersDatabaseCreated("Hoeller", "Brannen"); - } - - private void assertUsersDatabaseCreated(String... lastNames) { - final JdbcTemplate jdbcTemplate = new JdbcTemplate(db); - for (String lastName : lastNames) { - assertThat("Did not find user with last name [" + lastName + "].", - jdbcTemplate.queryForObject("select count(0) from users where last_name = ?", Integer.class, lastName), - equalTo(1)); - } + private String readScript(String path) throws Exception { + EncodedResource resource = new EncodedResource(new ClassPathResource(path, getClass())); + return ScriptUtils.readScript(resource); } }