297 lines
8.4 KiB
Java
297 lines
8.4 KiB
Java
package com.rjconsultores.ventaboletos;
|
|
|
|
import java.io.BufferedWriter;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.OutputStreamWriter;
|
|
import java.io.Writer;
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.sql.Statement;
|
|
import java.sql.Timestamp;
|
|
import java.util.Calendar;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
import org.apache.log4j.Logger;
|
|
import org.flywaydb.core.Flyway;
|
|
import org.flywaydb.core.api.callback.FlywayCallback;
|
|
|
|
import com.rjconsultores.ventaboletos.vo.FlyWayCustomDetail;
|
|
|
|
public class FlyWay {
|
|
private static Logger log = Logger.getLogger(FlyWay.class);
|
|
|
|
private static final FlyWay INSTANCE = new FlyWay();
|
|
|
|
final private static String TABELA_FLYWAY = "schema_version_cst";
|
|
final File JBOSS_DATA = new File(System.getProperty("jboss.server.data.dir"));
|
|
|
|
private DataSource dataSource = null;
|
|
|
|
private String url = null;
|
|
private String user = null;
|
|
private String password = null;
|
|
|
|
private String location = "db.migration";
|
|
|
|
public static FlyWay getInstance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
public void defineLocation(final String location) {
|
|
this.location = location;
|
|
}
|
|
|
|
public void defineDataSource(final DataSource dataSource) {
|
|
this.dataSource = dataSource;
|
|
|
|
fixFiles(dataSource);
|
|
}
|
|
|
|
public void defineProperties(final String url, final String user, final String password) {
|
|
this.url = url;
|
|
this.user = user;
|
|
this.password = password;
|
|
}
|
|
|
|
private void fixFiles(final DataSource ds) {
|
|
try {
|
|
Connection c = dataSource.getConnection();
|
|
Statement s = c.createStatement();
|
|
|
|
fixVersion(s, "20161710.1833", "20161017.1833", "V20161017_1833__mantis8112.sql");
|
|
fixVersion(s, "20161910.0934", "20161019.0934", "V20161019_0934__mantis7907.sql");
|
|
fixVersion(s, "20162410.1119", "20161024.1119", "V20161024_1119__mantis7904.sql");
|
|
|
|
s.close();
|
|
|
|
} catch (SQLException e) {
|
|
log.error(e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
private void fixVersion(final Statement s, final String oldVersion, final String newVersion, final String newScript) throws SQLException {
|
|
ResultSet rs = s.executeQuery("select count(*) as total from \"schema_version\" where \"version\" like '" + oldVersion + "'");
|
|
|
|
int total = 0;
|
|
|
|
while (rs.next()) {
|
|
total = rs.getInt("total");
|
|
}
|
|
|
|
rs.close();
|
|
|
|
if (total > 0) {
|
|
log.info("Fix version " + oldVersion + " to new version " + newVersion + " and new script " + newScript);
|
|
|
|
StringBuilder sql = new StringBuilder("");
|
|
sql.append(" update \"schema_version\"");
|
|
sql.append(" set \"version\" = '" + newVersion + "', \"script\" = '" + newScript + "'");
|
|
sql.append(" where \"version\" like '" + oldVersion + "'");
|
|
|
|
s.executeUpdate(sql.toString());
|
|
}
|
|
}
|
|
|
|
public boolean start() {
|
|
return start(null, null);
|
|
}
|
|
|
|
public boolean startCustom() {
|
|
String location = "db.performance";
|
|
|
|
if (JBOSS_DATA != null) {
|
|
File data = new File(JBOSS_DATA, "flyway");
|
|
|
|
if (!data.exists()) {
|
|
data.mkdirs();
|
|
}
|
|
|
|
if (!validarScripts(data)) {
|
|
return true;
|
|
}
|
|
|
|
location = "filesystem:" + data.getPath();
|
|
}
|
|
|
|
return start(location, TABELA_FLYWAY);
|
|
}
|
|
|
|
public boolean start(final String customLocation, final String customTable) {
|
|
log.info("Executando Flyway...");
|
|
|
|
try{
|
|
final Flyway flyway = new Flyway();
|
|
|
|
if (customTable != null) {
|
|
flyway.setTable(customTable);
|
|
}
|
|
|
|
if (customLocation != null) {
|
|
flyway.setLocations(customLocation);
|
|
} else if (this.location != null && !this.location.equals("db.migration")) {
|
|
flyway.setLocations(this.location);
|
|
}
|
|
|
|
if (dataSource != null) {
|
|
flyway.setDataSource(dataSource);
|
|
} else {
|
|
flyway.setDataSource(url, user, password);
|
|
|
|
dataSource = flyway.getDataSource();
|
|
}
|
|
|
|
execute(flyway);
|
|
|
|
}catch(Throwable t){
|
|
log.error("Erro ao executar o Flyway",t);
|
|
|
|
return false;
|
|
}
|
|
|
|
log.info("Flyway executado.");
|
|
|
|
return true;
|
|
}
|
|
|
|
public void execute(final Flyway flyway) {
|
|
flyway.setValidateOnMigrate(false);
|
|
flyway.setIgnoreFutureMigrations(true);
|
|
flyway.setOutOfOrder(true);
|
|
flyway.setBaselineOnMigrate(true);
|
|
|
|
if (flyway.getTable().equals(TABELA_FLYWAY)) {
|
|
FlyWayCallback errorCallback = new FlyWayCallback();
|
|
|
|
FlywayCallback[] callbacks = new FlywayCallback[]{ errorCallback };
|
|
flyway.setCallbacks(callbacks);
|
|
|
|
try {
|
|
flyway.migrate();
|
|
} catch (final Exception e) {
|
|
if (errorCallback.getScriptError() != null) {
|
|
log.error("[Flyway] Erro ao executar o script: " + errorCallback.getScriptError() + ". Este script sera desabilitado na tabela FLYWAY_SCRIPTS.");
|
|
|
|
File scriptFile = new File(JBOSS_DATA, "flyway");
|
|
scriptFile = new File(scriptFile, errorCallback.getScriptError());
|
|
|
|
if (scriptFile.exists()) {
|
|
log.info("[Flyway] Excluindo fisicamente o script: " + errorCallback.getScriptError() + ". " + (scriptFile.delete() ? "OK" : "ERROR"));
|
|
}
|
|
|
|
try {
|
|
Connection c = flyway.getDataSource().getConnection();
|
|
PreparedStatement ps = c.prepareStatement("update flyway_scripts set activo = 0 where nome like ?");
|
|
ps.setString(1, errorCallback.getScriptError().replace(".sql", ""));
|
|
ps.executeUpdate();
|
|
|
|
} catch (SQLException e1) {
|
|
}
|
|
}
|
|
|
|
flyway.repair();
|
|
}
|
|
} else {
|
|
flyway.migrate();
|
|
}
|
|
}
|
|
|
|
private boolean validarScripts(File data) {
|
|
Map<String, FlyWayCustomDetail> scripts = new HashMap<String, FlyWayCustomDetail>(0);
|
|
|
|
try {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(" select nome as nome_arquivo, sql as sql_arquivo, sql_erro as erro, datahora_execucao as datahora");
|
|
sb.append(" from flyway_scripts");
|
|
sb.append(" where activo = 1 and nome not in (select replace(\"script\", '.sql', '') from \"schema_version_cst\")");
|
|
sb.append(" order by nome_arquivo");
|
|
|
|
Connection c = dataSource.getConnection();
|
|
Statement s = c.createStatement();
|
|
|
|
ResultSet rs = s.executeQuery(sb.toString());
|
|
|
|
while (rs.next()) {
|
|
Timestamp timestamp = rs.getTimestamp("datahora");
|
|
|
|
FlyWayCustomDetail detail = new FlyWayCustomDetail();
|
|
detail.setVersion(rs.getString("nome_arquivo"));
|
|
detail.setSql(rs.getString("sql_arquivo"));
|
|
detail.setErrorCode(rs.getString("erro"));
|
|
|
|
if (timestamp != null) {
|
|
detail.setDatetimeExecute(new java.util.Date(timestamp.getTime()));
|
|
}
|
|
|
|
scripts.put(rs.getString("nome_arquivo"), detail);
|
|
}
|
|
|
|
rs.close();
|
|
s.close();
|
|
|
|
} catch (SQLException e) {
|
|
log.error(e.getMessage(), e);
|
|
}
|
|
|
|
if (scripts.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
boolean retorno = false;
|
|
|
|
Writer writer = null;
|
|
|
|
for (Map.Entry<String, FlyWayCustomDetail> entry : scripts.entrySet()) {
|
|
if (entry.getValue().getDatetimeExecute() != null) {
|
|
Calendar atual = Calendar.getInstance();
|
|
|
|
if (atual.getTime().before(entry.getValue().getDatetimeExecute())) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
File scriptFile = new File(data, entry.getKey() + ".sql");
|
|
|
|
if (scriptFile.exists()) {
|
|
scriptFile.delete();
|
|
}
|
|
|
|
if (!scriptFile.exists()) {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
if (entry.getValue().getErrorCode() != null) {
|
|
sb.append("declare").append("\n");
|
|
sb.append(" object_exists exception;").append("\n").append("\n");
|
|
sb.append(" pragma exception_init (object_exists , ").append(entry.getValue().getErrorCode()).append(");").append("\n");
|
|
sb.append("begin").append("\n");
|
|
sb.append(" execute immediate '").append(entry.getValue().getSql()).append("';").append("\n");
|
|
sb.append(" exception when object_exists then null;").append("\n");
|
|
sb.append("end;");
|
|
} else {
|
|
sb.append(entry.getValue().getSql());
|
|
}
|
|
|
|
try {
|
|
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(scriptFile), "utf-8"));
|
|
writer.write(sb.toString());
|
|
|
|
log.info("[Flyway] Script gerado: " + scriptFile.toString());
|
|
|
|
retorno = true;
|
|
} catch (IOException ex) {
|
|
} finally {
|
|
try {writer.close();} catch (Exception ex) {log.info(ex.getMessage(), ex);}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retorno;
|
|
}
|
|
}
|