Browse Source

Merge branch '6.2.x'

pull/35307/head
Sam Brannen 7 months ago
parent
commit
0efa04f32c
  1. 41
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
  2. 10
      spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientIntegrationTests.java
  3. 2
      spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertIntegrationTests.java
  4. 69
      spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java
  5. 2
      spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-with-custom-schema.sql
  6. 2
      spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql

41
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java

@ -258,18 +258,29 @@ public abstract class ScriptUtils {
for (String statement : statements) { for (String statement : statements) {
stmtNumber++; stmtNumber++;
try { try {
stmt.execute(statement); boolean hasResultSet = stmt.execute(statement);
int rowsAffected = stmt.getUpdateCount(); int updateCount = -1;
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(rowsAffected + " returned as update count for SQL: " + statement); logSqlWarnings(stmt);
SQLWarning warningToLog = stmt.getWarnings();
while (warningToLog != null) {
logger.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() +
"', error code '" + warningToLog.getErrorCode() +
"', message [" + warningToLog.getMessage() + "]");
warningToLog = warningToLog.getNextWarning();
}
} }
do {
if (hasResultSet) {
// We invoke getResultSet() to ensure the JDBC driver processes
// it, but we intentionally ignore the returned ResultSet since
// we cannot do anything meaningful with it here.
stmt.getResultSet();
if (logger.isDebugEnabled()) {
logger.debug("ResultSet returned for SQL: " + statement);
}
}
else {
updateCount = stmt.getUpdateCount();
if (updateCount >= 0 && logger.isDebugEnabled()) {
logger.debug(updateCount + " returned as update count for SQL: " + statement);
}
}
hasResultSet = stmt.getMoreResults();
} while (hasResultSet || updateCount != -1);
} }
catch (SQLException ex) { catch (SQLException ex) {
boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop");
@ -307,6 +318,16 @@ public abstract class ScriptUtils {
} }
} }
private static void logSqlWarnings(Statement stmt) throws SQLException {
SQLWarning warningToLog = stmt.getWarnings();
while (warningToLog != null) {
logger.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() +
"', error code '" + warningToLog.getErrorCode() +
"', message [" + warningToLog.getMessage() + "]");
warningToLog = warningToLog.getNextWarning();
}
}
/** /**
* Read a script from the provided resource, using the supplied comment prefixes * Read a script from the provided resource, using the supplied comment prefixes
* and statement separator, and build a {@code String} containing the lines. * and statement separator, and build a {@code String} containing the lines.

10
spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientIntegrationTests.java

@ -74,7 +74,7 @@ class JdbcClientIntegrationTests {
@Test @Test
void updateWithGeneratedKeys() { void updateWithGeneratedKeys() {
int expectedId = 2; int expectedId = 1;
String firstName = "Jane"; String firstName = "Jane";
String lastName = "Smith"; String lastName = "Smith";
@ -92,7 +92,7 @@ class JdbcClientIntegrationTests {
@Test @Test
void updateWithGeneratedKeysAndKeyColumnNames() { void updateWithGeneratedKeysAndKeyColumnNames() {
int expectedId = 2; int expectedId = 1;
String firstName = "Jane"; String firstName = "Jane";
String lastName = "Smith"; String lastName = "Smith";
@ -110,7 +110,7 @@ class JdbcClientIntegrationTests {
@Test @Test
void updateWithGeneratedKeysUsingNamedParameters() { void updateWithGeneratedKeysUsingNamedParameters() {
int expectedId = 2; int expectedId = 1;
String firstName = "Jane"; String firstName = "Jane";
String lastName = "Smith"; String lastName = "Smith";
@ -129,7 +129,7 @@ class JdbcClientIntegrationTests {
@Test @Test
void updateWithGeneratedKeysAndKeyColumnNamesUsingNamedParameters() { void updateWithGeneratedKeysAndKeyColumnNamesUsingNamedParameters() {
int expectedId = 2; int expectedId = 1;
String firstName = "Jane"; String firstName = "Jane";
String lastName = "Smith"; String lastName = "Smith";
@ -242,7 +242,7 @@ class JdbcClientIntegrationTests {
} }
private static void assertResults(List<User> users) { private static void assertResults(List<User> users) {
assertThat(users).containsExactly(new User(2, "John", "John"), new User(3, "John", "Smith")); assertThat(users).containsExactly(new User(1, "John", "John"), new User(2, "John", "Smith"));
} }
private static void assertSingleResult(List<User> users) { private static void assertSingleResult(List<User> users) {

2
spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertIntegrationTests.java

@ -323,7 +323,7 @@ class SimpleJdbcInsertIntegrationTests {
protected void insertJaneSmith(SimpleJdbcInsert insert) { protected void insertJaneSmith(SimpleJdbcInsert insert) {
Number id = insert.executeAndReturnKey(Map.of("first_name", "Jane", "last_name", "Smith")); Number id = insert.executeAndReturnKey(Map.of("first_name", "Jane", "last_name", "Smith"));
assertThat(id.intValue()).isEqualTo(2); assertThat(id.intValue()).isEqualTo(1);
assertNumRows(2); assertNumRows(2);
} }

69
spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java

@ -16,13 +16,24 @@
package org.springframework.jdbc.datasource.init; package org.springframework.jdbc.datasource.init;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.Parameter;
import org.junit.jupiter.params.ParameterizedClass;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.jdbc.core.DataClassRowMapper;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import static org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript; import static org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript;
/** /**
@ -32,16 +43,22 @@ import static org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScr
* @since 4.0.3 * @since 4.0.3
* @see ScriptUtilsTests * @see ScriptUtilsTests
*/ */
@ParameterizedClass
@EnumSource(EmbeddedDatabaseType.class)
class ScriptUtilsIntegrationTests extends AbstractDatabaseInitializationTests { class ScriptUtilsIntegrationTests extends AbstractDatabaseInitializationTests {
@Parameter
EmbeddedDatabaseType databaseType;
@Override @Override
protected EmbeddedDatabaseType getEmbeddedDatabaseType() { protected EmbeddedDatabaseType getEmbeddedDatabaseType() {
return EmbeddedDatabaseType.HSQL; return this.databaseType;
} }
@BeforeEach @BeforeEach
void setUpSchema() throws SQLException { void setUpSchema() throws SQLException {
executeSqlScript(db.getConnection(), usersSchema()); executeSqlScript(db.getConnection(), encodedResource(usersSchema()), false, true, "--", null, "/*", "*/");
} }
@Test @Test
@ -59,4 +76,52 @@ class ScriptUtilsIntegrationTests extends AbstractDatabaseInitializationTests {
assertUsersDatabaseCreated("Hoeller", "Brannen"); assertUsersDatabaseCreated("Hoeller", "Brannen");
} }
@Test
@SuppressWarnings("unchecked")
void statementWithMultipleResultSets() throws SQLException {
// Derby does not support multiple statements/ResultSets within a single Statement.
assumeThat(this.databaseType).isNotSameAs(EmbeddedDatabaseType.DERBY);
EncodedResource resource = encodedResource(resource("users-data.sql"));
executeSqlScript(db.getConnection(), resource, false, true, "--", null, "/*", "*/");
assertUsersInDatabase(user("Sam", "Brannen"));
resource = encodedResource(inlineResource("""
SELECT last_name FROM users WHERE id = 0;
UPDATE users SET first_name = 'Jane' WHERE id = 0;
UPDATE users SET last_name = 'Smith' WHERE id = 0;
SELECT last_name FROM users WHERE id = 0;
GO
"""));
String separator = "GO\n";
executeSqlScript(db.getConnection(), resource, false, true, "--", separator, "/*", "*/");
assertUsersInDatabase(user("Jane", "Smith"));
}
private void assertUsersInDatabase(User... expectedUsers) {
List<User> users = jdbcTemplate.query("SELECT * FROM users WHERE id = 0",
new DataClassRowMapper<>(User.class));
assertThat(users).containsExactly(expectedUsers);
}
private static EncodedResource encodedResource(Resource resource) {
return new EncodedResource(resource);
}
private static Resource inlineResource(String sql) {
byte[] bytes = sql.getBytes(StandardCharsets.UTF_8);
return new ByteArrayResource(bytes, "inline SQL");
}
private static User user(String firstName, String lastName) {
return new User(0, firstName, lastName);
}
record User(int id, String firstName, String lastName) {
}
} }

2
spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema-with-custom-schema.sql

@ -5,7 +5,7 @@ SET SCHEMA my_schema;
DROP TABLE users IF EXISTS; DROP TABLE users IF EXISTS;
CREATE TABLE users ( CREATE TABLE users (
id INTEGER GENERATED BY DEFAULT AS IDENTITY, id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY,
first_name VARCHAR(50) NOT NULL, first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL last_name VARCHAR(50) NOT NULL
); );

2
spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sql

@ -1,7 +1,7 @@
DROP TABLE users IF EXISTS; DROP TABLE users IF EXISTS;
CREATE TABLE users ( CREATE TABLE users (
id INTEGER GENERATED BY DEFAULT AS IDENTITY, id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY,
first_name VARCHAR(50) NOT NULL, first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL last_name VARCHAR(50) NOT NULL
); );

Loading…
Cancel
Save