From 01b2f67f11207c5007164518a83fcfb546b36837 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 13 Mar 2014 13:45:05 +0100 Subject: [PATCH] Introduce constructors in ResourceDatabasePopulator Issue: SPR-9531 --- .../init/ResourceDatabasePopulator.java | 45 +++- .../EmbeddedDatabaseFactoryBeanTests.java | 8 +- .../init/DatabasePopulatorTests.java | 232 +++++++----------- ...TransactionalJUnit4SpringContextTests.java | 8 +- ...TransactionalTestNGSpringContextTests.java | 8 +- .../test/jdbc/JdbcTestUtils.java | 8 +- 6 files changed, 138 insertions(+), 171 deletions(-) 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 c2ebb314c0..d2c7d657e4 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 @@ -39,6 +39,7 @@ import org.springframework.core.io.support.EncodedResource; * @author Sam Brannen * @author Chris Baldwin * @since 3.0 + * @see DatabasePopulatorUtils */ public class ResourceDatabasePopulator implements DatabasePopulator { @@ -59,6 +60,32 @@ public class ResourceDatabasePopulator implements DatabasePopulator { private boolean ignoreFailedDrops = false; + /** + * Construct a new {@code ResourceDatabasePopulator} with default settings. + */ + public ResourceDatabasePopulator() { + /* no-op */ + } + + /** + * Construct a new {@code ResourceDatabasePopulator} with the supplied values. + * + * @param continueOnError flag to indicate that all failures in SQL should be + * logged but not cause a failure + * @param ignoreFailedDrops flag to indicate that a failed SQL {@code DROP} + * statement can be ignored + * @param sqlScriptEncoding the encoding for the supplied SQL scripts, if + * different from the platform encoding; may be {@code null} + * @param scripts the scripts to execute to populate the database + */ + public ResourceDatabasePopulator(boolean continueOnError, boolean ignoreFailedDrops, String sqlScriptEncoding, + Resource... scripts) { + this.continueOnError = continueOnError; + this.ignoreFailedDrops = ignoreFailedDrops; + this.sqlScriptEncoding = sqlScriptEncoding; + this.scripts = Arrays.asList(scripts); + } + /** * Add a script to execute to populate the database. * @param script the path to an SQL script @@ -77,8 +104,6 @@ public class ResourceDatabasePopulator implements DatabasePopulator { /** * Specify the encoding for SQL scripts, if different from the platform encoding. - *

Note that setting this property has no effect on added scripts that are - * already {@linkplain EncodedResource encoded resources}. * @see #addScript(Resource) */ public void setSqlScriptEncoding(String sqlScriptEncoding) { @@ -145,18 +170,18 @@ public class ResourceDatabasePopulator implements DatabasePopulator { @Override public void populate(Connection connection) throws SQLException { for (Resource script : this.scripts) { - ScriptUtils.executeSqlScript(connection, applyEncodingIfNecessary(script), this.continueOnError, + ScriptUtils.executeSqlScript(connection, encodeScript(script), this.continueOnError, this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter, this.blockCommentEndDelimiter); } } - private EncodedResource applyEncodingIfNecessary(Resource script) { - if (script instanceof EncodedResource) { - return (EncodedResource) script; - } - else { - return new EncodedResource(script, this.sqlScriptEncoding); - } + /** + * {@link EncodedResource} is not a sub-type of {@link Resource}. Thus we + * always need to wrap each script resource in an encoded resource. + */ + private EncodedResource encodeScript(Resource script) { + return new EncodedResource(script, this.sqlScriptEncoding); } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java index 97326b470e..8844063648 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java @@ -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. @@ -16,16 +16,16 @@ package org.springframework.jdbc.datasource.embedded; -import static org.junit.Assert.assertEquals; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import static org.junit.Assert.*; + /** * @author Keith Donald */ 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/DatabasePopulatorTests.java index 73f3629ba5..571b744384 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/DatabasePopulatorTests.java @@ -22,6 +22,7 @@ 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; @@ -29,9 +30,8 @@ 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.mockito.BDDMockito.*; +import static org.mockito.Mockito.*; /** * @author Dave Syer @@ -65,6 +65,18 @@ public class DatabasePopulatorTests { } } + 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()) { @@ -75,178 +87,121 @@ public class DatabasePopulatorTests { } @Test - public void testBuildWithCommentsAndFailedDrop() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema-failed-drop-comments.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data.sql")); + public void buildWithCommentsAndFailedDrop() throws Exception { + databasePopulator.addScript(resource("db-schema-failed-drop-comments.sql")); + databasePopulator.addScript(resource("db-test-data.sql")); databasePopulator.setIgnoreFailedDrops(true); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - + DatabasePopulatorUtils.execute(databasePopulator, db); assertTestDatabaseCreated(); } @Test - public void testBuildWithNormalEscapedLiteral() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-escaped-literal.sql")); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - + public void buildWithNormalEscapedLiteral() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-escaped-literal.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); assertTestDatabaseCreated("'Keith'"); } @Test - public void testBuildWithMySQLEscapedLiteral() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-mysql-escaped-literal.sql")); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - + public void buildWithMySQLEscapedLiteral() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-mysql-escaped-literal.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); 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(); - } - - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + public void buildWithMultipleStatements() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-multiple.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } @Test - public void testBuildWithMultipleStatementsLongSeparator() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-endings.sql")); + public void buildWithMultipleStatementsLongSeparator() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-endings.sql")); databasePopulator.setSeparator("@@"); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } @Test - public void testBuildWithMultipleStatementsWhitespaceSeparator() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-whitespace.sql")); + public void buildWithMultipleStatementsWhitespaceSeparator() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-whitespace.sql")); databasePopulator.setSeparator("/\n"); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } @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(); - } - - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + public void buildWithMultipleStatementsNewlineSeparator() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-newline.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } @Test - public void testBuildWithMultipleStatementsMultipleNewlineSeparator() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-multi-newline.sql")); + public void buildWithMultipleStatementsMultipleNewlineSeparator() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-multi-newline.sql")); databasePopulator.setSeparator("\n\n"); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } @Test public void scriptWithEolBetweenTokens() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("users-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("users-data.sql")); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - + databasePopulator.addScript(usersSchema()); + databasePopulator.addScript(resource("users-data.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); assertUsersDatabaseCreated("Brannen"); } @Test public void scriptWithCommentsWithinStatements() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("users-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("users-data-with-comments.sql")); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } - + databasePopulator.addScript(usersSchema()); + databasePopulator.addScript(resource("users-data-with-comments.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); assertUsersDatabaseCreated("Brannen", "Hoeller"); } @Test - public void testBuildWithSelectStatements() throws Exception { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-select.sql")); - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } + public void constructorWithMultipleScriptResources() throws Exception { + final ResourceDatabasePopulator populator = new ResourceDatabasePopulator(false, false, null, usersSchema(), + resource("users-data-with-comments.sql")); + DatabasePopulatorUtils.execute(populator, db); + assertUsersDatabaseCreated("Brannen", "Hoeller"); + } - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), equalTo(1)); - assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), equalTo(1)); + @Test + public void buildWithSelectStatements() throws Exception { + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-select.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Keith'", Integer.class), + equalTo(1)); + assertThat(jdbcTemplate.queryForObject("select COUNT(NAME) from T_TEST where NAME='Dave'", Integer.class), + equalTo(1)); } /** @@ -266,16 +221,9 @@ public class DatabasePopulatorTests { */ @Test(timeout = 1000) public void executesHugeScriptInReasonableTime() throws SQLException { - databasePopulator.addScript(resourceLoader.getResource("db-schema.sql")); - databasePopulator.addScript(resourceLoader.getResource("db-test-data-huge.sql")); - - Connection connection = db.getConnection(); - try { - databasePopulator.populate(connection); - } - finally { - connection.close(); - } + databasePopulator.addScript(defaultSchema()); + databasePopulator.addScript(resource("db-test-data-huge.sql")); + DatabasePopulatorUtils.execute(databasePopulator, db); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java index 2bc4582716..7ab768effd 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java @@ -23,6 +23,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.init.DatabasePopulator; import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.test.context.ContextConfiguration; @@ -184,11 +185,8 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst */ protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { Resource resource = this.applicationContext.getResource(sqlResourcePath); - ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - databasePopulator.setContinueOnError(continueOnError); - databasePopulator.addScript(resource); - databasePopulator.setSqlScriptEncoding(this.sqlScriptEncoding); - + DatabasePopulator databasePopulator = new ResourceDatabasePopulator(continueOnError, false, + this.sqlScriptEncoding, resource); DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource()); } diff --git a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java index 3d99d31c71..a768c29dbf 100644 --- a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java @@ -23,6 +23,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.init.DatabasePopulator; import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.test.context.TestExecutionListeners; @@ -175,11 +176,8 @@ public abstract class AbstractTransactionalTestNGSpringContextTests extends Abst */ protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { Resource resource = this.applicationContext.getResource(sqlResourcePath); - ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - databasePopulator.setContinueOnError(continueOnError); - databasePopulator.addScript(resource); - databasePopulator.setSqlScriptEncoding(this.sqlScriptEncoding); - + DatabasePopulator databasePopulator = new ResourceDatabasePopulator(continueOnError, false, + this.sqlScriptEncoding, resource); DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource()); } diff --git a/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java b/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java index 952ef1e87c..aa7d17a102 100644 --- a/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java +++ b/spring-test/src/main/java/org/springframework/test/jdbc/JdbcTestUtils.java @@ -29,6 +29,7 @@ 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.DatabasePopulator; import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.jdbc.datasource.init.ScriptUtils; @@ -220,11 +221,8 @@ public class JdbcTestUtils { @Deprecated public static void executeSqlScript(JdbcTemplate jdbcTemplate, EncodedResource resource, boolean continueOnError) throws DataAccessException { - ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - databasePopulator.setContinueOnError(continueOnError); - databasePopulator.addScript(resource.getResource()); - databasePopulator.setSqlScriptEncoding(resource.getEncoding()); - + DatabasePopulator databasePopulator = new ResourceDatabasePopulator(continueOnError, false, + resource.getEncoding(), resource.getResource()); DatabasePopulatorUtils.execute(databasePopulator, jdbcTemplate.getDataSource()); }