From 14edc9fc031dbd5b8af7824e3e3f7c9d17712cda Mon Sep 17 00:00:00 2001 From: David Syer Date: Thu, 2 Jun 2011 16:22:26 +0000 Subject: [PATCH] SPR-7364: added separator property to database populator to deal with things like PL/SQL --- org.springframework.jdbc/.classpath | 22 ++---- org.springframework.jdbc/.project | 6 ++ .../.settings/org.eclipse.jdt.core.prefs | 5 +- ...nitializeDatabaseBeanDefinitionParser.java | 45 +++++++---- .../metadata/OracleCallMetaDataProvider.java | 1 - .../namedparam/SqlParameterSourceUtils.java | 2 - .../init/CompositeDatabasePopulator.java | 57 ++++++++++++++ .../init/ResourceDatabasePopulator.java | 75 +++++++++++------- .../jdbc/config/spring-jdbc-3.1.xsd | 7 ++ .../config/JdbcNamespaceIntegrationTest.java | 25 +++++- .../jdbc/core/AbstractRowMapperTests.java | 2 - .../jdbc/core/JdbcTemplateTests.java | 1 - .../init/DatabasePopulatorTests.java | 78 +++++++++++++++++++ .../jdbc/object/SqlUpdateTests.java | 1 - .../jdbc/config/db-test-data-endings.sql | 2 + .../config/jdbc-initialize-endings-config.xml | 15 ++++ .../datasource/init/db-test-data-endings.sql | 2 + .../init/db-test-data-multi-newline.sql | 5 ++ .../datasource/init/db-test-data-multiple.sql | 2 + .../datasource/init/db-test-data-newline.sql | 2 + .../init/db-test-data-whitespace.sql | 5 ++ 21 files changed, 288 insertions(+), 72 deletions(-) create mode 100644 org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-test-data-endings.sql create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-endings-config.xml create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-endings.sql create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multi-newline.sql create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multiple.sql create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-newline.sql create mode 100644 org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-whitespace.sql diff --git a/org.springframework.jdbc/.classpath b/org.springframework.jdbc/.classpath index a8aa9a87195..7c3d14f89b7 100644 --- a/org.springframework.jdbc/.classpath +++ b/org.springframework.jdbc/.classpath @@ -1,22 +1,10 @@ - - + + - - - - - - - - - - - - - - - + + + diff --git a/org.springframework.jdbc/.project b/org.springframework.jdbc/.project index f1bebbe7efe..5b378ac2e92 100644 --- a/org.springframework.jdbc/.project +++ b/org.springframework.jdbc/.project @@ -10,8 +10,14 @@ + + org.maven.ide.eclipse.maven2Builder + + + + org.maven.ide.eclipse.maven2Nature org.eclipse.jdt.core.javanature diff --git a/org.springframework.jdbc/.settings/org.eclipse.jdt.core.prefs b/org.springframework.jdbc/.settings/org.eclipse.jdt.core.prefs index 51fbd353764..f6a35953218 100644 --- a/org.springframework.jdbc/.settings/org.eclipse.jdt.core.prefs +++ b/org.springframework.jdbc/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ -#Wed Jul 15 00:01:31 PDT 2009 +#Thu Jun 02 17:16:32 BST 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate @@ -9,6 +9,7 @@ org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.5 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java index 766b2d08636..ce28adbcd5b 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java @@ -16,16 +16,20 @@ package org.springframework.jdbc.config; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.jdbc.datasource.init.CompositeDatabasePopulator; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -60,21 +64,36 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti } private BeanDefinition createDatabasePopulator(Element element, List scripts, ParserContext context) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); - builder.addPropertyValue("ignoreFailedDrops", element.getAttribute("ignore-failures").equals("DROPS")); - builder.addPropertyValue("continueOnError", element.getAttribute("ignore-failures").equals("ALL")); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CompositeDatabasePopulator.class); + + boolean ignoreFailedDrops = element.getAttribute("ignore-failures").equals("DROPS"); + boolean continueOnError = element.getAttribute("ignore-failures").equals("ALL"); + + ManagedList delegates = new ManagedList(); - List locations = new ArrayList(); for (Element scriptElement : scripts) { - String location = scriptElement.getAttribute("location"); - locations.add(location); - } - // Use a factory bean for the resources so they can be given an order if a pattern is used - BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder - .genericBeanDefinition(SortedResourcesFactoryBean.class); - resourcesFactory.addConstructorArgValue(locations); - builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); + BeanDefinitionBuilder delegate = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); + delegate.addPropertyValue("ignoreFailedDrops", ignoreFailedDrops); + delegate.addPropertyValue("continueOnError", continueOnError); + + List locations = Arrays.asList(scriptElement.getAttribute("location")); + // Use a factory bean for the resources so they can be given an order if a pattern is used + BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder + .genericBeanDefinition(SortedResourcesFactoryBean.class); + resourcesFactory.addConstructorArgValue(locations); + + delegate.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); + + if (StringUtils.hasLength(scriptElement.getAttribute("separator"))) { + delegate.addPropertyValue("separator", scriptElement.getAttribute("separator")); + } + + delegates.add(delegate.getBeanDefinition()); + + } + + builder.addPropertyValue("populators", delegates); return builder.getBeanDefinition(); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java index de063d5f8ad..6b31dcea992 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.java @@ -23,7 +23,6 @@ import java.sql.Types; import org.springframework.jdbc.core.ColumnMapRowMapper; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; -import org.springframework.jdbc.core.SqlInOutParameter; /** * Oracle specific implementation for the {@link CallMetaDataProvider} interface. diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java index aaaf32b5457..5af6dd9a727 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java @@ -18,8 +18,6 @@ package org.springframework.jdbc.core.namedparam; import java.util.HashMap; import java.util.Map; -import java.util.Iterator; - import org.springframework.jdbc.core.SqlParameterValue; /** diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java new file mode 100644 index 00000000000..574a1ef2682 --- /dev/null +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2011 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.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * {@link DatabasePopulator} implementation that delegates to a list of other implementations, executing alll scripts. + * + * @author Dave Syer + * + */ +public class CompositeDatabasePopulator implements DatabasePopulator { + + private List populators = new ArrayList(); + + /** + * @param populators the populators to set + */ + public void setPopulators(List populators) { + this.populators.clear(); + this.populators.addAll(populators); + } + + /** + * @param populator the populator to add + */ + public void addPopulator(DatabasePopulator populator) { + this.populators.add(populator); + } + + /* (non-Javadoc) + * @see org.springframework.jdbc.datasource.init.DatabasePopulator#populate(java.sql.Connection) + */ + public void populate(Connection connection) throws SQLException { + for (DatabasePopulator populator : populators) { + populator.populate(connection); + } + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java index 7bc21ef8f7f..a93d10374d8 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java @@ -50,7 +50,6 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private static final Log logger = LogFactory.getLog(ResourceDatabasePopulator.class); - private List scripts = new ArrayList(); private String sqlScriptEncoding; @@ -61,6 +60,14 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private boolean ignoreFailedDrops = false; + private String separator = null; + + /** + * @param separator the statement separator + */ + public void setSeparator(String separator) { + this.separator = separator; + } /** * Add a script to execute to populate the database. @@ -114,7 +121,6 @@ public class ResourceDatabasePopulator implements DatabasePopulator { this.ignoreFailedDrops = ignoreFailedDrops; } - public void populate(Connection connection) throws SQLException { for (Resource script : this.scripts) { executeSqlScript(connection, applyEncodingIfNecessary(script), this.continueOnError, this.ignoreFailedDrops); @@ -124,8 +130,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private EncodedResource applyEncodingIfNecessary(Resource script) { if (script instanceof EncodedResource) { return (EncodedResource) script; - } - else { + } else { return new EncodedResource(script, this.sqlScriptEncoding); } } @@ -140,8 +145,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * @param continueOnError whether or not to continue without throwing an exception in the event of an error * @param ignoreFailedDrops whether of not to continue in the event of specifically an error on a DROP */ - private void executeSqlScript(Connection connection, EncodedResource resource, - boolean continueOnError, boolean ignoreFailedDrops) throws SQLException { + private void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError, + boolean ignoreFailedDrops) throws SQLException { if (logger.isInfoEnabled()) { logger.info("Executing SQL script from " + resource); @@ -151,13 +156,15 @@ public class ResourceDatabasePopulator implements DatabasePopulator { String script; try { script = readScript(resource); - } - catch (IOException ex) { + } catch (IOException ex) { throw new CannotReadScriptException(resource, ex); } - char delimiter = ';'; - if (!containsSqlScriptDelimiters(script, delimiter)) { - delimiter = '\n'; + String delimiter = separator; + if (delimiter == null) { + delimiter = ";"; + if (!containsSqlScriptDelimiters(script, delimiter)) { + delimiter = "\n"; + } } splitSqlScript(script, delimiter, statements); int lineNumber = 0; @@ -170,26 +177,22 @@ public class ResourceDatabasePopulator implements DatabasePopulator { if (logger.isDebugEnabled()) { logger.debug(rowsAffected + " rows affected by SQL: " + statement); } - } - catch (SQLException ex) { + } catch (SQLException ex) { boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); if (continueOnError || (dropStatement && ignoreFailedDrops)) { if (logger.isDebugEnabled()) { - logger.debug("Failed to execute SQL script statement at line " + lineNumber + - " of resource " + resource + ": " + statement, ex); + logger.debug("Failed to execute SQL script statement at line " + lineNumber + + " of resource " + resource + ": " + statement, ex); } - } - else { + } else { throw new ScriptStatementFailedException(statement, lineNumber, resource, ex); } } } - } - finally { + } finally { try { stmt.close(); - } - catch (Throwable ex) { + } catch (Throwable ex) { logger.debug("Could not close JDBC Statement", ex); } } @@ -210,8 +213,8 @@ public class ResourceDatabasePopulator implements DatabasePopulator { String currentStatement = lnr.readLine(); StringBuilder scriptBuilder = new StringBuilder(); while (currentStatement != null) { - if (StringUtils.hasText(currentStatement) && - (this.commentPrefix != null && !currentStatement.startsWith(this.commentPrefix))) { + if (StringUtils.hasText(currentStatement) + && (this.commentPrefix != null && !currentStatement.startsWith(this.commentPrefix))) { if (scriptBuilder.length() > 0) { scriptBuilder.append('\n'); } @@ -219,22 +222,34 @@ public class ResourceDatabasePopulator implements DatabasePopulator { } currentStatement = lnr.readLine(); } + maybeAddSeparatorToScript(scriptBuilder); return scriptBuilder.toString(); } + private void maybeAddSeparatorToScript(StringBuilder scriptBuilder) { + if (separator==null || separator.trim().length()==separator.length()) { + return; + } + String trimmed = separator.trim(); + // separator ends in whitespace, so we might want to see if the script is trying to end the same way + if (scriptBuilder.lastIndexOf(trimmed)==scriptBuilder.length()-trimmed.length()) { + scriptBuilder.append(separator.substring(trimmed.length())); + } + } + /** * Does the provided SQL script contain the specified delimiter? * @param script the SQL script * @param delim character delimiting each statement - typically a ';' character */ - private boolean containsSqlScriptDelimiters(String script, char delim) { + private boolean containsSqlScriptDelimiters(String script, String delim) { boolean inLiteral = false; char[] content = script.toCharArray(); for (int i = 0; i < script.length(); i++) { if (content[i] == '\'') { inLiteral = !inLiteral; } - if (content[i] == delim && !inLiteral) { + if (!inLiteral && script.substring(i).startsWith(delim)) { return true; } } @@ -248,7 +263,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * @param delim character delimiting each statement (typically a ';' character) * @param statements the List that will contain the individual statements */ - private void splitSqlScript(String script, char delim, List statements) { + private void splitSqlScript(String script, String delim, List statements) { StringBuilder sb = new StringBuilder(); boolean inLiteral = false; boolean inEscape = false; @@ -258,7 +273,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator { if (inEscape) { inEscape = false; sb.append(c); - continue; + continue; } // MySQL style escapes if (c == '\\') { @@ -270,14 +285,14 @@ public class ResourceDatabasePopulator implements DatabasePopulator { inLiteral = !inLiteral; } if (!inLiteral) { - if (c == delim) { + if (script.substring(i).startsWith(delim)) { if (sb.length() > 0) { statements.add(sb.toString()); sb = new StringBuilder(); } + i += delim.length() - 1; continue; - } - else if (c == '\n' || c == '\t') { + } else if (c == '\n' || c == '\t') { c = ' '; } } diff --git a/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-3.1.xsd b/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-3.1.xsd index 269e08a8a12..1ba8f9a82a7 100644 --- a/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-3.1.xsd +++ b/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-3.1.xsd @@ -129,6 +129,13 @@ ]]> + + + + + diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTest.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTest.java index 7ef895d8f72..0512e91ae3d 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTest.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTest.java @@ -1,7 +1,9 @@ package org.springframework.jdbc.config; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import javax.sql.DataSource; @@ -22,6 +24,7 @@ public class JdbcNamespaceIntegrationTest { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config.xml"); assertCorrectSetup(context, "dataSource", "h2DataSource", "derbyDataSource"); + context.close(); } @Test @@ -30,6 +33,7 @@ public class JdbcNamespaceIntegrationTest { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config.xml"); assertCorrectSetup(context, "derbyDataSource"); + context.close(); } @Test @@ -37,6 +41,15 @@ public class JdbcNamespaceIntegrationTest { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config-pattern.xml"); assertCorrectSetup(context, "dataSource"); + context.close(); + } + + @Test + public void testCreateWithEndings() throws Exception { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "org/springframework/jdbc/config/jdbc-initialize-endings-config.xml"); + assertCorrectSetup(context, 2, "dataSource"); + context.close(); } @Test @@ -58,15 +71,21 @@ public class JdbcNamespaceIntegrationTest { } private void assertCorrectSetup(ConfigurableApplicationContext context, String... dataSources) { + assertCorrectSetup(context, 1, dataSources); + } + + private void assertCorrectSetup(ConfigurableApplicationContext context, int count, String... dataSources) { try { for (String dataSourceName : dataSources) { DataSource dataSource = context.getBean(dataSourceName, DataSource.class); JdbcTemplate t = new JdbcTemplate(dataSource); - assertEquals(1, t.queryForInt("select count(*) from T_TEST")); + assertEquals(count, t.queryForInt("select count(*) from T_TEST")); } } finally { context.close(); } + } + } diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java index 551efe2baae..6f672cf1ea4 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java @@ -23,8 +23,6 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.sql.Types; - import junit.framework.TestCase; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java index 1e0d2f09f92..cae62536534 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java @@ -42,7 +42,6 @@ import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.SQLWarningException; import org.springframework.jdbc.UncategorizedSQLException; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java index 1720abe2281..8154fa526ca 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java @@ -102,6 +102,84 @@ public class DatabasePopulatorTests { assertTestDatabaseCreated("\\$Keith\\$"); } + @Test + public void testBuildWithMultipleStatements() throws Exception { + databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); + databasePopulator.addScript(resourceLoader.getResource("db-test-data-multiple.sql")); + Connection connection = db.getConnection(); + try { + databasePopulator.populate(connection); + } finally { + connection.close(); + } + + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'")); + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'")); + } + + @Test + public void testBuildWithMultipleStatementsLongSeparator() throws Exception { + databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); + databasePopulator.addScript(resourceLoader.getResource("db-test-data-endings.sql")); + databasePopulator.setSeparator("@@"); + Connection connection = db.getConnection(); + try { + databasePopulator.populate(connection); + } finally { + connection.close(); + } + + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'")); + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'")); + } + + @Test + public void testBuildWithMultipleStatementsWhitespaceSeparator() throws Exception { + databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); + databasePopulator.addScript(resourceLoader.getResource("db-test-data-whitespace.sql")); + databasePopulator.setSeparator("/\n"); + Connection connection = db.getConnection(); + try { + databasePopulator.populate(connection); + } finally { + connection.close(); + } + + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'")); + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'")); + } + + @Test + public void testBuildWithMultipleStatementsNewlineSeparator() throws Exception { + databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); + databasePopulator.addScript(resourceLoader.getResource("db-test-data-newline.sql")); + Connection connection = db.getConnection(); + try { + databasePopulator.populate(connection); + } finally { + connection.close(); + } + + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'")); + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'")); + } + + @Test + public void testBuildWithMultipleStatementsMultipleNewlineSeparator() throws Exception { + databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); + databasePopulator.addScript(resourceLoader.getResource("db-test-data-multi-newline.sql")); + databasePopulator.setSeparator("\n\n"); + Connection connection = db.getConnection(); + try { + databasePopulator.populate(connection); + } finally { + connection.close(); + } + + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'")); + assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'")); + } + @Test public void scriptWithEolBetweenTokens() throws Exception { databasePopulator.addScript(resourceLoader.getResource("users-schema.sql")); diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java index 9493b5fbbf8..447a8aa9c22 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java @@ -27,7 +27,6 @@ import java.util.Map; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; -import org.springframework.core.JdkVersion; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; import org.springframework.jdbc.core.SqlParameter; diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-test-data-endings.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-test-data-endings.sql new file mode 100644 index 00000000000..383039168f4 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-test-data-endings.sql @@ -0,0 +1,2 @@ +insert into T_TEST (NAME) values ('Keith')@@ +insert into T_TEST (NAME) values ('Dave')@@ \ No newline at end of file diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-endings-config.xml b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-endings-config.xml new file mode 100644 index 00000000000..da9700b7f04 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-endings-config.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-endings.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-endings.sql new file mode 100644 index 00000000000..383039168f4 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-endings.sql @@ -0,0 +1,2 @@ +insert into T_TEST (NAME) values ('Keith')@@ +insert into T_TEST (NAME) values ('Dave')@@ \ No newline at end of file diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multi-newline.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multi-newline.sql new file mode 100644 index 00000000000..307b0175d12 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multi-newline.sql @@ -0,0 +1,5 @@ +insert into T_TEST (NAME) +values ('Keith') + +insert into T_TEST (NAME) +values ('Dave') diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multiple.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multiple.sql new file mode 100644 index 00000000000..573bd4faca3 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-multiple.sql @@ -0,0 +1,2 @@ +insert into T_TEST (NAME) values ('Keith'); +insert into T_TEST (NAME) values ('Dave'); \ No newline at end of file diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-newline.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-newline.sql new file mode 100644 index 00000000000..cef932f8154 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-newline.sql @@ -0,0 +1,2 @@ +insert into T_TEST (NAME) values ('Keith') +insert into T_TEST (NAME) values ('Dave') diff --git a/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-whitespace.sql b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-whitespace.sql new file mode 100644 index 00000000000..4bdf282ad24 --- /dev/null +++ b/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-whitespace.sql @@ -0,0 +1,5 @@ +insert into T_TEST (NAME) values ('Keith') +/ + +insert into T_TEST (NAME) values ('Dave') +/