package core.framework.test.db;
import core.framework.api.db.Database;
import core.framework.api.util.Exceptions;
import core.framework.api.util.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author neo
*/
public final class SQLScriptRunner {
private static final String DEFAULT_DELIMITER = ";";
private static final Pattern NEW_DELIMITER_PATTERN = Pattern.compile("(?:--|\\/\\/|\\#)?!DELIMITER=(.+)");
private static final Pattern COMMENT_PATTERN = Pattern.compile("^(?:--|\\/\\/|\\#).+");
private final Logger logger = LoggerFactory.getLogger(SQLScriptRunner.class);
private final Database database;
private final String script;
public SQLScriptRunner(Database database, String script) {
this.database = database;
this.script = script;
}
public void run() {
int lineNumber = 0;
try (BufferedReader reader = new BufferedReader(new StringReader(script))) {
StringBuilder sql = new StringBuilder();
String delimiter = DEFAULT_DELIMITER;
String line;
while (true) {
line = reader.readLine();
if (line == null) break;
lineNumber++;
String trimmedLine = line.trim();
Matcher delimiterMatcher = NEW_DELIMITER_PATTERN.matcher(trimmedLine);
Matcher commentMatcher = COMMENT_PATTERN.matcher(trimmedLine);
if (delimiterMatcher.find()) {
delimiter = delimiterMatcher.group(1);
} else if (!commentMatcher.find()) {
sql.append(trimmedLine);
if (trimmedLine.endsWith(delimiter)) {
executeSQL(sql.toString());
sql = new StringBuilder();
}
}
}
} catch (RuntimeException | IOException e) {
throw Exceptions.error("failed to run script, error={}, line={}", e.getMessage(), lineNumber, e);
}
}
private void executeSQL(String sql) {
StopWatch watch = new StopWatch();
try {
database.execute(sql);
} finally {
logger.info("execute, sql={}, elapsedTime={}", sql, watch.elapsedTime());
}
}
}