Skip to content

Commit

Permalink
Backported "Work around JDK7 String#substring performance regression"
Browse files Browse the repository at this point in the history
Issue: SPR-9781
Issue: SPR-9784
  • Loading branch information
jhoeller committed Oct 10, 2012
1 parent b2fce2f commit 86ef22d
Show file tree
Hide file tree
Showing 3 changed files with 2,081 additions and 20 deletions.
@@ -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");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,13 +43,14 @@
* @author Dave Syer
* @author Juergen Hoeller
* @author Chris Beams
* @author Oliver Gierke
* @since 3.0
*/
public class ResourceDatabasePopulator implements DatabasePopulator {

private static String DEFAULT_COMMENT_PREFIX = "--";
private static final String DEFAULT_COMMENT_PREFIX = "--";

private static String DEFAULT_STATEMENT_SEPARATOR = ";";
private static final String DEFAULT_STATEMENT_SEPARATOR = ";";

private static final Log logger = LogFactory.getLog(ResourceDatabasePopulator.class);

Expand Down Expand Up @@ -265,16 +266,32 @@ private boolean containsSqlScriptDelimiters(String script, String delim) {
if (content[i] == '\'') {
inLiteral = !inLiteral;
}
if (!inLiteral && script.substring(i).startsWith(delim)) {
if (!inLiteral && startsWithDelimiter(script, i, delim)) {
return true;
}
}
return false;
}

/**
* Split an SQL script into separate statements delimited with the provided delimiter character.
* Each individual statement will be added to the provided <code>List</code>.
* Return whether the substring of a given source {@link String} starting at the
* 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 delim character delimiting each statement (typically a ';' character)
* @param statements the List that will contain the individual statements
Expand All @@ -301,7 +318,7 @@ private void splitSqlScript(String script, String delim, List<String> statements
inLiteral = !inLiteral;
}
if (!inLiteral) {
if (script.substring(i).startsWith(delim)) {
if (startsWithDelimiter(script, i, delim)) {
if (sb.length() > 0) {
statements.add(sb.toString());
sb = new StringBuilder();
Expand Down
Expand Up @@ -41,11 +41,16 @@
public class DatabasePopulatorTests {

private final EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();

private final EmbeddedDatabase db = builder.build();

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");
}
Expand All @@ -61,15 +66,14 @@ private void assertUsersDatabaseCreated() {

@After
public void shutDown() {

if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.clear();
TransactionSynchronizationManager.unbindResource(db);
}

db.shutdown();
}


@Test
public void testBuildWithCommentsAndFailedDrop() throws Exception {
databasePopulator.addScript(resourceLoader.getResource("db-schema-failed-drop-comments.sql"));
Expand All @@ -78,7 +82,8 @@ public void testBuildWithCommentsAndFailedDrop() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -92,7 +97,8 @@ public void testBuildWithNormalEscapedLiteral() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -106,7 +112,8 @@ public void testBuildWithMySQLEscapedLiteral() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -120,7 +127,8 @@ public void testBuildWithMultipleStatements() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -136,7 +144,8 @@ public void testBuildWithMultipleStatementsLongSeparator() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -152,7 +161,8 @@ public void testBuildWithMultipleStatementsWhitespaceSeparator() throws Exceptio
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -167,7 +177,8 @@ public void testBuildWithMultipleStatementsNewlineSeparator() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -183,7 +194,8 @@ public void testBuildWithMultipleStatementsMultipleNewlineSeparator() throws Exc
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -198,7 +210,8 @@ public void scriptWithEolBetweenTokens() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -212,7 +225,8 @@ public void testBuildWithSelectStatements() throws Exception {
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
}
finally {
connection.close();
}

Expand All @@ -225,7 +239,6 @@ public void testBuildWithSelectStatements() throws Exception {
*/
@Test
public void usesBoundConnectionIfAvailable() throws SQLException {

TransactionSynchronizationManager.initSynchronization();
Connection connection = DataSourceUtils.getConnection(db);

Expand All @@ -238,4 +251,22 @@ public void usesBoundConnectionIfAvailable() throws SQLException {

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();
}
}

}

0 comments on commit 86ef22d

Please sign in to comment.