Skip to content

Commit 082bb34

Browse files
committed
fixes #1116 Allow using multiple characters as a delimiter. Also added a test that verifies various delimiter syntax.
1 parent f1b0458 commit 082bb34

File tree

2 files changed

+70
-7
lines changed

2 files changed

+70
-7
lines changed

src/main/java/org/apache/ibatis/jdbc/ScriptRunner.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
import java.io.BufferedReader;
1919
import java.io.PrintWriter;
2020
import java.io.Reader;
21-
import java.io.UnsupportedEncodingException;
2221
import java.sql.Connection;
2322
import java.sql.ResultSet;
2423
import java.sql.ResultSetMetaData;
2524
import java.sql.SQLException;
2625
import java.sql.SQLWarning;
2726
import java.sql.Statement;
27+
import java.util.regex.Matcher;
28+
import java.util.regex.Pattern;
2829

2930
/**
3031
* @author Clinton Begin
@@ -35,6 +36,8 @@ public class ScriptRunner {
3536

3637
private static final String DEFAULT_DELIMITER = ";";
3738

39+
private static final Pattern DELIMITER_PATTERN = Pattern.compile("^\\s*((--)|(//))?\\s*(//)?\\s*@DELIMITER\\s+([^\\s]+)", Pattern.CASE_INSENSITIVE);
40+
3841
private final Connection connection;
3942

4043
private boolean stopOnError;
@@ -192,14 +195,14 @@ private void checkForMissingLineTerminator(StringBuilder command) {
192195
}
193196
}
194197

195-
private StringBuilder handleLine(StringBuilder command, String line) throws SQLException, UnsupportedEncodingException {
198+
private StringBuilder handleLine(StringBuilder command, String line) throws SQLException {
196199
String trimmedLine = line.trim();
197200
if (lineIsComment(trimmedLine)) {
198-
final String cleanedString = trimmedLine.substring(2).trim().replaceFirst("//", "");
199-
if(cleanedString.toUpperCase().startsWith("@DELIMITER")) {
200-
delimiter = cleanedString.substring(11,12);
201-
return command;
202-
}
201+
Matcher matcher = DELIMITER_PATTERN.matcher(trimmedLine);
202+
if (matcher.find()) {
203+
delimiter = matcher.group(5);
204+
return command;
205+
}
203206
println(trimmedLine);
204207
} else if (commandReadyToExecute(trimmedLine)) {
205208
command.append(line.substring(0, line.lastIndexOf(delimiter)));

src/test/java/org/apache/ibatis/jdbc/ScriptRunnerTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
2121
import org.apache.ibatis.io.Resources;
2222
import static org.junit.Assert.*;
23+
import static org.mockito.Mockito.*;
2324

2425
import org.junit.Ignore;
2526
import org.junit.Test;
27+
import org.mockito.Mockito;
2628

2729
import javax.sql.DataSource;
2830
import java.io.IOException;
@@ -32,6 +34,7 @@
3234
import java.io.StringWriter;
3335
import java.sql.Connection;
3436
import java.sql.SQLException;
37+
import java.sql.Statement;
3538
import java.util.List;
3639
import java.util.Map;
3740
import java.util.Properties;
@@ -241,4 +244,61 @@ private void assertProductsTableExistsAndLoaded() throws IOException, SQLExcepti
241244
}
242245
}
243246

247+
@Test
248+
public void shouldAcceptDelimiterVariations() throws Exception {
249+
Connection conn = mock(Connection.class);
250+
Statement stmt = mock(Statement.class);
251+
when(conn.createStatement()).thenReturn(stmt);
252+
ScriptRunner runner = new ScriptRunner(conn);
253+
254+
String sql = "-- @DELIMITER | \n"
255+
+ "line 1;\n"
256+
+ "line 2;\n"
257+
+ "|\n"
258+
+ "// @DELIMITER ;\n"
259+
+ "line 3; \n"
260+
+ "-- //@deLimiTer $ blah\n"
261+
+ "line 4$\n"
262+
+ "// //@DELIMITER %\n"
263+
+ "line 5%\n";
264+
Reader reader = new StringReader(sql);
265+
runner.runScript(reader);
266+
267+
verify(stmt, Mockito.times(1)).execute(eq("line 1;\n" + "line 2;\n\n"));
268+
verify(stmt, Mockito.times(1)).execute(eq("line 3\n"));
269+
verify(stmt, Mockito.times(1)).execute(eq("line 4\n"));
270+
verify(stmt, Mockito.times(1)).execute(eq("line 5\n"));
271+
}
272+
273+
@Test
274+
public void test() throws Exception {
275+
StringBuilder sb = new StringBuilder();
276+
StringBuilder sb2 = y(sb);
277+
assertTrue(sb == sb2);
278+
}
279+
280+
private StringBuilder y(StringBuilder sb) {
281+
sb.append("ABC");
282+
return sb;
283+
}
284+
285+
@Test
286+
public void shouldAcceptMultiCharDelimiter() throws Exception {
287+
Connection conn = mock(Connection.class);
288+
Statement stmt = mock(Statement.class);
289+
when(conn.createStatement()).thenReturn(stmt);
290+
ScriptRunner runner = new ScriptRunner(conn);
291+
292+
String sql = "-- @DELIMITER || \n"
293+
+ "line 1;\n"
294+
+ "line 2;\n"
295+
+ "||\n"
296+
+ "// @DELIMITER ;\n"
297+
+ "line 3; \n";
298+
Reader reader = new StringReader(sql);
299+
runner.runScript(reader);
300+
301+
verify(stmt, Mockito.times(1)).execute(eq("line 1;\n" + "line 2;\n\n"));
302+
verify(stmt, Mockito.times(1)).execute(eq("line 3\n"));
303+
}
244304
}

0 commit comments

Comments
 (0)