Skip to content

Commit 31c419d

Browse files
author
Igor Polevoy
committed
#414 BUG: Migrations containing strings that span more than one line and have \; fail to run
1 parent 0c33831 commit 31c419d

File tree

4 files changed

+111
-46
lines changed

4 files changed

+111
-46
lines changed

db-migrator/src/main/java/org/javalite/db_migrator/Migration.java

Lines changed: 78 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
55

6-
import java.io.File;
7-
import java.io.FileInputStream;
8-
import java.io.InputStreamReader;
9-
import java.io.LineNumberReader;
6+
import java.io.*;
107

118
import static org.javalite.db_migrator.DbUtils.exec;
129

@@ -32,58 +29,94 @@ public String getName() {
3229
return migrationFile.getName();
3330
}
3431

32+
public static String read(InputStream in, String charset) throws IOException {
33+
if (in == null) {
34+
throw new IllegalArgumentException("input stream cannot be null");
35+
}
36+
InputStreamReader reader = null;
37+
try {
38+
reader = new InputStreamReader(in, charset);
39+
char[] buffer = new char[1024];
40+
StringBuilder sb = new StringBuilder();
41+
int len;
42+
while ((len = reader.read(buffer)) != -1) {
43+
sb.append(buffer, 0, len);
44+
}
45+
return sb.toString();
46+
} finally {
47+
assert reader != null;
48+
reader.close();
49+
}
50+
}
51+
52+
3553
public void migrate(String encoding) throws Exception {
3654

55+
//TODO: I must say this needs to be refactored.
56+
try {
57+
String migration = read(new FileInputStream(migrationFile), encoding == null ? "UTF-8" : encoding);
58+
if (migration.contains("BLOCK")) {
59+
processAsBlocks(migration);
60+
} else {
61+
processLineByLine(encoding);
62+
}
63+
} catch (Exception e) {
64+
throw new MigrationException(e);
65+
}
66+
}
3767

68+
private void processLineByLine(String encoding) throws IOException {
3869
StringBuilder command = null;
39-
try {
40-
String delimiter = DEFAULT_DELIMITER;
41-
LineNumberReader lineReader = new LineNumberReader(new InputStreamReader(new FileInputStream(migrationFile), encoding == null? "UTF-8" : encoding));
42-
String line;
43-
while ((line = lineReader.readLine()) != null) {
44-
if (command == null) {
45-
command = new StringBuilder();
46-
}
4770

48-
line = line.trim(); // Strip extra whitespace too?
71+
String delimiter = DEFAULT_DELIMITER;
72+
LineNumberReader lineReader = new LineNumberReader(new InputStreamReader(new FileInputStream(migrationFile), encoding == null ? "UTF-8" : encoding));
73+
String line;
74+
while ((line = lineReader.readLine()) != null) {
75+
if (command == null) {
76+
command = new StringBuilder();
77+
}
78+
79+
line = line.trim(); // Strip extra whitespace too?
80+
81+
if (line.length() < 1) {
82+
// Do nothing, it's an empty line.
83+
} else if (commentLine(line)) {
84+
logger.debug(line);
85+
} else {
86+
if (startsWithIgnoreCase(line, DEFAULT_DELIMITER_KEYWORD)) {
87+
delimiter = line.substring(9).trim();
88+
} else if ((command.length() == 0) && startsWithIgnoreCase(line, "create ") && containsIgnoreCase(line, " as ")) {
89+
delimiter = line.substring(line.toLowerCase().lastIndexOf(" as ") + 4);
90+
command.append(line);
91+
command.append(" ");
92+
} else if (line.contains(delimiter)) {
93+
if (line.startsWith(delimiter)) {
94+
delimiter = DEFAULT_DELIMITER;
95+
}
4996

50-
if (line.length() < 1) {
51-
// Do nothing, it's an empty line.
52-
} else if (commentLine(line)) {
53-
logger.debug(line);
54-
} else {
55-
if (startsWithIgnoreCase(line, DEFAULT_DELIMITER_KEYWORD)) {
56-
delimiter = line.substring(10).trim();
57-
} else if ((command.length() == 0) && startsWithIgnoreCase(line, "create ") && containsIgnoreCase(line, " as ")) {
58-
delimiter = line.substring(line.toLowerCase().lastIndexOf(" as ") + 4);
59-
command.append(line);
60-
command.append(" ");
61-
} else if (line.contains(delimiter)) {
62-
if (line.startsWith(delimiter)) {
63-
delimiter = DEFAULT_DELIMITER;
64-
}
65-
66-
if (line.endsWith(delimiter)) {
67-
command.append(line.substring(0, line.lastIndexOf(delimiter)));
68-
exec(command.toString().trim());
69-
command = null;
70-
}
71-
} else {
72-
command.append(line);
73-
command.append(" ");
97+
if (line.endsWith(delimiter)) {
98+
command.append(line.substring(0, line.lastIndexOf(delimiter)));
99+
exec(command.toString().trim());
100+
command = null;
74101
}
102+
} else {
103+
command.append(line);
104+
command.append(" ");
75105
}
76106
}
107+
}
77108

78-
// Check to see if we have an unexecuted statement in command.
79-
if (command != null && command.length() > 0) {
80-
//Last statement in script is missing a terminating delimiter, executing anyway.
81-
exec(command.toString().trim());
82-
}
109+
// Check to see if we have an unexecuted statement in command.
110+
if (command != null && command.length() > 0) {
111+
//Last statement in script is missing a terminating delimiter, executing anyway.
112+
exec(command.toString().trim());
113+
}
114+
}
83115

84-
} catch (Exception e) {
85-
logger.error("Error executing: {}", command, e);
86-
throw e;
116+
private void processAsBlocks(String migration) {
117+
String[] statements = migration.split("BLOCK");
118+
for (String statement : statements) {
119+
exec(statement);
87120
}
88121
}
89122

db-migrator/src/test/java/org/javalite/db_migrator/MigrationSpec.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,22 @@ public void shouldExecuteLastStatementWhenDelimiterIsMissing() throws Exception
9797
assertEquals(statements.get(0), "create table users ( username varchar not null, password varchar not null )");
9898
assertEquals(statements.get(1), "create table roles ( name varchar not null unique, description text not null )");
9999
}
100+
101+
@Test
102+
public void shouldHandleNewLinesAndSpacesInStatements() throws Exception {
103+
Migration m = new Migration("123", new File("src/test/resources/sql/newlines_and_spaces.sql"));
104+
m.migrate(null);
105+
List statements = getStatements();
106+
107+
for (Object o : statements) {
108+
109+
String statement = o.toString().trim();
110+
if(!statement.equals("")){
111+
112+
System.out.println("===");
113+
System.out.println(o);
114+
}
115+
116+
}
117+
}
100118
}

db-migrator/src/test/resources/sql/complex.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- END BLOCK
1+
-- END
22

33
update dav_file set parent = ( select id from ( select id from dav_file where name = '__SITE_PROTECTED__' ) as x )
44
where ( name = 'templates' and parent is null )
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
BLOCK
2+
3+
SET @facility_id = (SELECT id from facilities where state = 'Illin;\
4+
5+
6+
ois' and name = 'Cook County');
7+
8+
BLOCK
9+
10+
select * from people where name = ' \;
11+
12+
asdadsy a8fdyg
13+
';
14+

0 commit comments

Comments
 (0)