Merge pull request #143 from olivergierke/SPR-9781

# By Oliver Gierke
* SPR-9781:
  Work around JDK7 String#substring performance regression
master
Chris Beams 12 years ago
commit ec2df7d229
  1. 32
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java
  2. 17
      spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.java
  3. 2013
      spring-jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data-huge.sql

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2011 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,6 +43,7 @@ import org.springframework.util.StringUtils;
* @author Dave Syer * @author Dave Syer
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
* @author Oliver Gierke
* @since 3.0 * @since 3.0
*/ */
public class ResourceDatabasePopulator implements DatabasePopulator { public class ResourceDatabasePopulator implements DatabasePopulator {
@ -265,7 +266,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
if (content[i] == '\'') { if (content[i] == '\'') {
inLiteral = !inLiteral; inLiteral = !inLiteral;
} }
if (!inLiteral && script.substring(i).startsWith(delim)) { if (!inLiteral && startsWithDelimiter(script, i, delim)) {
return true; return true;
} }
} }
@ -273,8 +274,29 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
} }
/** /**
* Split an SQL script into separate statements delimited with the provided delimiter character. * Return whether the substring of a given source {@link String} starting at the
* Each individual statement will be added to the provided <code>List</code>. * given index starts with the given delimiter.
*
* @param source the source {@link String} to inspect
* @param startIndex the index to look for the delimiter
* @param delim the delimiter to look for
*/
private boolean startsWithDelimiter(String source, int startIndex, String delim) {
int endIndex = startIndex + delim.length();
if (source.length() < endIndex) {
// String is too short to contain the delimiter
return false;
}
return source.substring(startIndex, endIndex).equals(delim);
}
/**
* Split an SQL script into separate statements delimited with the provided delimiter
* character. Each individual statement will be added to the provided {@code List}.
*
* @param script the SQL script * @param script the SQL script
* @param delim character delimiting each statement (typically a ';' character) * @param delim character delimiting each statement (typically a ';' character)
* @param statements the List that will contain the individual statements * @param statements the List that will contain the individual statements
@ -301,7 +323,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
inLiteral = !inLiteral; inLiteral = !inLiteral;
} }
if (!inLiteral) { if (!inLiteral) {
if (script.substring(i).startsWith(delim)) { if (startsWithDelimiter(script, i, delim)) {
if (sb.length() > 0) { if (sb.length() > 0) {
statements.add(sb.toString()); statements.add(sb.toString());
sb = new StringBuilder(); sb = new StringBuilder();

@ -238,4 +238,21 @@ public class DatabasePopulatorTests {
EasyMock.verify(populator); EasyMock.verify(populator);
} }
/**
* @see SPR-9781
*/
@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();
}
}
} }

Loading…
Cancel
Save