[DEV] Migration base 1 OK
This commit is contained in:
parent
7c37b65842
commit
1826f40874
@ -71,13 +71,14 @@ public class SqlWrapper {
|
|||||||
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
|
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
|
||||||
PreparedStatement ps = entry.connection.prepareStatement("show databases");
|
PreparedStatement ps = entry.connection.prepareStatement("show databases");
|
||||||
ResultSet rs = ps.executeQuery();
|
ResultSet rs = ps.executeQuery();
|
||||||
|
//LOGGER.info("List all tables: equals? '{}'", name);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
String data = rs.getString(1);
|
String data = rs.getString(1);
|
||||||
|
//LOGGER.info(" - '{}'", data);
|
||||||
if (name.equals(data)) {
|
if (name.equals(data)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//int count = ret.getInt("total");
|
|
||||||
return false;
|
return false;
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.error("Can not check if the DB exist SQL-error !!! {}", ex.getMessage());
|
LOGGER.error("Can not check if the DB exist SQL-error !!! {}", ex.getMessage());
|
||||||
@ -92,64 +93,56 @@ public class SqlWrapper {
|
|||||||
}
|
}
|
||||||
throw new InternalServerErrorException("Can Not manage the DB-access");
|
throw new InternalServerErrorException("Can Not manage the DB-access");
|
||||||
}
|
}
|
||||||
public static boolean createDB(String name) throws InternalServerErrorException {
|
public static boolean createDB(String name) {
|
||||||
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
// no base manage in sqLite ...
|
// no base manage in sqLite ...
|
||||||
// TODO: check if the file exist or not ...
|
// TODO: check if the file exist or not ...
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
DBEntry entry;
|
|
||||||
try {
|
try {
|
||||||
entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, true);
|
return 1 == SqlWrapper.executeSimpleQuerry("CREATE DATABASE `" + name + "`;", true);
|
||||||
} catch (IOException ex) {
|
} catch (SQLException ex) {
|
||||||
// TODO Auto-generated catch block
|
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
LOGGER.error("Can not Create the DB {}", ex.getMessage());
|
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
PreparedStatement ps = entry.connection.prepareStatement("CREATE DATABASE ?");
|
|
||||||
ps.setString(1, name);
|
|
||||||
int ret = ps.executeUpdate();
|
|
||||||
return ret == 1;
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.error("Can not Create the DB SQL-error !!! {}", ex.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
entry.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
entry = null;
|
|
||||||
}
|
|
||||||
throw new InternalServerErrorException("Can Not manage the DB-access");
|
|
||||||
}
|
}
|
||||||
public static boolean isTableExist(String name) throws InternalServerErrorException {
|
public static boolean isTableExist(String name) throws InternalServerErrorException {
|
||||||
try {
|
try {
|
||||||
String request = "";
|
String request = "";
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
request = """
|
|
||||||
SELECT count(*) AS total
|
|
||||||
FROM information_schema.tables
|
|
||||||
WHERE table_name = ?;
|
|
||||||
LIMIT 1;
|
|
||||||
""";
|
|
||||||
} else {
|
|
||||||
request = """
|
request = """
|
||||||
SELECT COUNT(*) AS total
|
SELECT COUNT(*) AS total
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
AND name = ?;
|
AND name = ?;
|
||||||
""";
|
""";
|
||||||
|
// PreparedStatement ps = entry.connection.prepareStatement("show tables");
|
||||||
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
||||||
|
PreparedStatement ps = entry.connection.prepareStatement(request);
|
||||||
|
ps.setString(1, name);
|
||||||
|
ResultSet ret = ps.executeQuery();
|
||||||
|
int count = ret.getInt("total");
|
||||||
|
return count == 1;
|
||||||
|
} else {
|
||||||
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
||||||
|
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
|
||||||
|
PreparedStatement ps = entry.connection.prepareStatement("show tables");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
//LOGGER.info("List all tables: equals? '{}'", name);
|
||||||
|
while (rs.next()) {
|
||||||
|
String data = rs.getString(1);
|
||||||
|
//LOGGER.info(" - '{}'", data);
|
||||||
|
if (name.equals(data)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreparedStatement ps = entry.connection.prepareStatement("show tables");
|
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
|
||||||
PreparedStatement ps = entry.connection.prepareStatement(request);
|
|
||||||
ps.setString(1, name);
|
|
||||||
ResultSet ret = ps.executeQuery();
|
|
||||||
int count = ret.getInt("total");
|
|
||||||
return count == 1;
|
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.error("Can not check if the table exist SQL-error !!! {}", ex.getMessage());
|
LOGGER.error("Can not check if the table exist SQL-error !!! {}", ex.getMessage());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -793,11 +786,23 @@ public class SqlWrapper {
|
|||||||
addElement(ps, elem.Value(), iii++);
|
addElement(ps, elem.Value(), iii++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static int executeSimpleQuerry(String querry, boolean root) throws SQLException, IOException {
|
||||||
public static void executeSimpleQuerry(String querry) throws SQLException, IOException {
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
|
||||||
Statement stmt = entry.connection.createStatement();
|
Statement stmt = entry.connection.createStatement();
|
||||||
stmt.executeUpdate(querry);
|
return stmt.executeUpdate(querry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int executeSimpleQuerry(String querry) throws SQLException, IOException {
|
||||||
|
return executeSimpleQuerry(querry, false);
|
||||||
|
}
|
||||||
|
public static boolean executeQuerry(String querry, boolean root) throws SQLException, IOException {
|
||||||
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
|
||||||
|
Statement stmt = entry.connection.createStatement();
|
||||||
|
return stmt.execute(querry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean executeQuerry(String querry) throws SQLException, IOException {
|
||||||
|
return executeQuerry(querry, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -939,9 +944,6 @@ public class SqlWrapper {
|
|||||||
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
query.append("SELECT ");
|
query.append("SELECT ");
|
||||||
//query.append(tableName);
|
|
||||||
//query.append(" SET ");
|
|
||||||
|
|
||||||
boolean firstField = true;
|
boolean firstField = true;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
StateLoad[] autoClasify = new StateLoad[clazz.getFields().length];
|
StateLoad[] autoClasify = new StateLoad[clazz.getFields().length];
|
||||||
@ -1228,17 +1230,22 @@ public class SqlWrapper {
|
|||||||
entry = null;
|
entry = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createTable(Class<?> clazz) throws Exception {
|
public static List<String> createTable(Class<?> clazz) throws Exception {
|
||||||
|
return createTable(clazz, true);
|
||||||
|
}
|
||||||
|
public static List<String> createTable(Class<?> clazz, boolean createDrop) throws Exception {
|
||||||
String tableName = getTableName(clazz);
|
String tableName = getTableName(clazz);
|
||||||
boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
|
List<String> outList = new ArrayList<>();
|
||||||
StringBuilder out = new StringBuilder();
|
StringBuilder out = new StringBuilder();
|
||||||
StringBuilder otherTable = new StringBuilder();
|
|
||||||
// Drop Table
|
// Drop Table
|
||||||
if (createIfNotExist) {
|
if (createIfNotExist && createDrop) {
|
||||||
out.append("DROP TABLE IF EXISTS `");
|
StringBuilder tableTmp = new StringBuilder();
|
||||||
out.append(tableName);
|
tableTmp.append("DROP TABLE IF EXISTS `");
|
||||||
out.append("`;\n");
|
tableTmp.append(tableName);
|
||||||
|
tableTmp.append("`;");
|
||||||
|
outList.add(tableTmp.toString());
|
||||||
}
|
}
|
||||||
// create Table:
|
// create Table:
|
||||||
out.append("CREATE TABLE `");
|
out.append("CREATE TABLE `");
|
||||||
@ -1273,13 +1280,16 @@ public class SqlWrapper {
|
|||||||
if (name.endsWith("s")) {
|
if (name.endsWith("s")) {
|
||||||
localName = name.substring(0, name.length()-1);
|
localName = name.substring(0, name.length()-1);
|
||||||
}
|
}
|
||||||
if (createIfNotExist) {
|
if (createIfNotExist && createDrop) {
|
||||||
otherTable.append("DROP TABLE IF EXISTS `");
|
StringBuilder tableTmp = new StringBuilder();
|
||||||
otherTable.append(tableName);
|
tableTmp.append("DROP TABLE IF EXISTS `");
|
||||||
otherTable.append("_link_");
|
tableTmp.append(tableName);
|
||||||
otherTable.append(localName);
|
tableTmp.append("_link_");
|
||||||
otherTable.append("`;\n");
|
tableTmp.append(localName);
|
||||||
|
tableTmp.append("`;");
|
||||||
|
outList.add(tableTmp.toString());
|
||||||
}
|
}
|
||||||
|
StringBuilder otherTable = new StringBuilder();
|
||||||
otherTable.append("CREATE TABLE `");
|
otherTable.append("CREATE TABLE `");
|
||||||
otherTable.append(tableName);
|
otherTable.append(tableName);
|
||||||
otherTable.append("_link_");
|
otherTable.append("_link_");
|
||||||
@ -1317,7 +1327,8 @@ public class SqlWrapper {
|
|||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
|
otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
|
||||||
}
|
}
|
||||||
otherTable.append(";\n\n");
|
otherTable.append(";");
|
||||||
|
outList.add(otherTable.toString());
|
||||||
} else {
|
} else {
|
||||||
if (firstField) {
|
if (firstField) {
|
||||||
out.append("\n\t\t`");
|
out.append("\n\t\t`");
|
||||||
@ -1355,11 +1366,18 @@ public class SqlWrapper {
|
|||||||
}
|
}
|
||||||
if (defaultValue == null) {
|
if (defaultValue == null) {
|
||||||
if (updateTime || createTime) {
|
if (updateTime || createTime) {
|
||||||
|
out.append("DEFAULT CURRENT_TIMESTAMP");
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
out.append("DEFAULT CURRENT_TIMESTAMP ");
|
out.append("(3)");
|
||||||
} else {
|
}
|
||||||
out.append("DEFAULT CURRENT_TIMESTAMP(3) ");
|
out.append(" ");
|
||||||
}
|
}
|
||||||
|
if (updateTime) {
|
||||||
|
out.append("ON UPDATE CURRENT_TIMESTAMP");
|
||||||
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
|
out.append("(3)");
|
||||||
|
}
|
||||||
|
out.append(" ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.append("DEFAULT ");
|
out.append("DEFAULT ");
|
||||||
@ -1369,6 +1387,13 @@ public class SqlWrapper {
|
|||||||
out.append(defaultValue);
|
out.append(defaultValue);
|
||||||
}
|
}
|
||||||
out.append(" ");
|
out.append(" ");
|
||||||
|
if (updateTime) {
|
||||||
|
out.append("ON UPDATE CURRENT_TIMESTAMP");
|
||||||
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
|
out.append("(3)");
|
||||||
|
}
|
||||||
|
out.append(" ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (defaultValue == null) {
|
} else if (defaultValue == null) {
|
||||||
if (updateTime || createTime) {
|
if (updateTime || createTime) {
|
||||||
@ -1414,8 +1439,9 @@ public class SqlWrapper {
|
|||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
|
out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
|
||||||
}
|
}
|
||||||
out.append(";\n");
|
out.append(";");
|
||||||
return out.toString() + otherTable.toString();
|
outList.add( out.toString());
|
||||||
|
return outList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ implements ExceptionMapper<ClientErrorException> {
|
|||||||
public Response toResponse(ClientErrorException exception) {
|
public Response toResponse(ClientErrorException exception) {
|
||||||
RestErrorResponse ret = build(exception);
|
RestErrorResponse ret = build(exception);
|
||||||
logger.error("Error UUID={}", ret.uuid);
|
logger.error("Error UUID={}", ret.uuid);
|
||||||
return Response.status(Response.Status.NOT_FOUND)
|
return Response.status(exception.getResponse().getStatusInfo().toEnum())
|
||||||
.entity(ret)
|
.entity(ret)
|
||||||
.type(MediaType.APPLICATION_JSON)
|
.type(MediaType.APPLICATION_JSON)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package org.kar.archidata.migration;
|
package org.kar.archidata.migration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
|
import org.kar.archidata.annotation.SQLLimitSize;
|
||||||
|
import org.kar.archidata.db.DBConfig;
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.db.DBEntry;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -34,15 +39,10 @@ public class MigrationEngine {
|
|||||||
* Get the current version/migration name
|
* Get the current version/migration name
|
||||||
* @return String represent the last migration. If null then no migration has been done.
|
* @return String represent the last migration. If null then no migration has been done.
|
||||||
*/
|
*/
|
||||||
public String getCurrentVersion() {
|
public MigrationModel getCurrentVersion() {
|
||||||
// TODO: check if the DB exist :
|
if (!SqlWrapper.isTableExist("KAR_migration")) {
|
||||||
if (SqlWrapper.isTableExist("migration")) {
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if migration table exist:
|
|
||||||
|
|
||||||
// get the current migration
|
|
||||||
try {
|
try {
|
||||||
List<MigrationModel> data = SqlWrapper.gets(MigrationModel.class, false);
|
List<MigrationModel> data = SqlWrapper.gets(MigrationModel.class, false);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
@ -53,30 +53,11 @@ public class MigrationEngine {
|
|||||||
LOGGER.error("Fail to Request migration table in the DB: empty size");
|
LOGGER.error("Fail to Request migration table in the DB: empty size");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return data.get(data.size()-1).name;
|
LOGGER.debug("List of migrations:");
|
||||||
} catch (Exception ex) {
|
for (MigrationModel elem : data) {
|
||||||
LOGGER.error("Fail to Request migration table in the DB:{}", ex.getMessage());
|
LOGGER.debug(" - date={} name={} end{}", elem.modify_date, elem.name, elem.terminated);
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current migration log generated
|
|
||||||
* @return String represent migration log (separate with \\n)
|
|
||||||
*/
|
|
||||||
public String getLastLog() {
|
|
||||||
try {
|
|
||||||
List<MigrationModel> data = SqlWrapper.gets(MigrationModel.class, false);
|
|
||||||
if (data == null) {
|
|
||||||
LOGGER.error("Can not collect the migration table in the DB:{}");
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
if (data.size() == 0) {
|
return data.get(data.size()-1);
|
||||||
LOGGER.error("Fail to Request migration table in the DB: empty size");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return data.get(data.size()-1).log;
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOGGER.error("Fail to Request migration table in the DB:{}", ex.getMessage());
|
LOGGER.error("Fail to Request migration table in the DB:{}", ex.getMessage());
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@ -84,53 +65,141 @@ public class MigrationEngine {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void migrate(DBEntry entry) {
|
public void migrate(DBConfig config) throws InterruptedException, IOException {
|
||||||
String currentVersion = getCurrentVersion();
|
LOGGER.info("Execute migration ... [BEGIN]");
|
||||||
List<MigrationInterface> toApply = new ArrayList<>();
|
|
||||||
boolean find = false;
|
// STEP 1: Check the DB exist:
|
||||||
for (int iii=0; iii<this.datas.size(); iii++) {
|
LOGGER.info("Verify existance of '{}'", config.getDbName());
|
||||||
if ( ! find) {
|
boolean exist = SqlWrapper.isDBExist(config.getDbName());
|
||||||
if (this.datas.get(iii).getName() == currentVersion) {
|
if(!exist) {
|
||||||
find = true;
|
LOGGER.warn("DB: '{}' DOES NOT EXIST ==> create one", config.getDbName());
|
||||||
|
// create the local DB:
|
||||||
|
SqlWrapper.createDB(config.getDbName());
|
||||||
|
}
|
||||||
|
exist = SqlWrapper.isDBExist(config.getDbName());
|
||||||
|
while (!exist) {
|
||||||
|
LOGGER.error("DB: '{}' DOES NOT EXIST after trying to create one ", config.getDbName());
|
||||||
|
LOGGER.error("Waiting administrator create a new one, we check after 30 seconds...");
|
||||||
|
Thread.sleep(30000);
|
||||||
|
exist = SqlWrapper.isDBExist(config.getDbName());
|
||||||
|
}
|
||||||
|
LOGGER.info("DB '{}' exist.", config.getDbName());
|
||||||
|
// STEP 2: Check migration table exist:
|
||||||
|
LOGGER.info("Verify existance of migration table '{}'", "KAR_migration");
|
||||||
|
exist = SqlWrapper.isTableExist("KAR_migration");
|
||||||
|
if (!exist) {
|
||||||
|
// create the table:
|
||||||
|
List<String> sqlQuery;
|
||||||
|
try {
|
||||||
|
sqlQuery = SqlWrapper.createTable(MigrationModel.class, false);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
while (true) {
|
||||||
|
LOGGER.error("Fail to create the local DB SQL model for migaration ==> wait administrator interventions");
|
||||||
|
Thread.sleep(60*60*1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info("Create Table with : {}", sqlQuery.get(0));
|
||||||
|
try {
|
||||||
|
SqlWrapper.executeQuerry(sqlQuery.get(0));//.replace("`", "").replace("\t", ""));
|
||||||
|
} catch (SQLException | IOException ex) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
ex.printStackTrace();
|
||||||
|
while (true) {
|
||||||
|
LOGGER.error("Fail to create the local DB model for migaration ==> wait administrator interventions");
|
||||||
|
Thread.sleep(60*60*1000);
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
toApply.add(this.datas.get(iii));
|
|
||||||
}
|
}
|
||||||
|
MigrationModel currentVersion = getCurrentVersion();
|
||||||
|
List<MigrationInterface> toApply = new ArrayList<>();
|
||||||
|
if (currentVersion == null) {
|
||||||
|
//This is a first migration
|
||||||
|
LOGGER.info("First installation of the system ==> Create the DB");
|
||||||
|
if (this.init == null) {
|
||||||
|
toApply = this.datas;
|
||||||
|
} else {
|
||||||
|
toApply.add(this.init);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentVersion.terminated == false) {
|
||||||
|
while(true) {
|
||||||
|
LOGGER.error("An error occured in the last migration: '{}' defect @{}/{} ==> wait administrator interventions", currentVersion.name , currentVersion.stepId, currentVersion.count);
|
||||||
|
Thread.sleep(60*60*1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info("Upgrade the system Current version: {}", currentVersion);
|
||||||
|
boolean find = false;
|
||||||
|
for (int iii=0; iii<this.datas.size(); iii++) {
|
||||||
|
if ( ! find) {
|
||||||
|
if (this.datas.get(iii).getName() == currentVersion.name) {
|
||||||
|
find = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
toApply.add(this.datas.get(iii));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBEntry entry = DBEntry.createInterface(config);
|
||||||
|
int id = 0;
|
||||||
|
int count = toApply.size();
|
||||||
for (MigrationInterface elem : toApply) {
|
for (MigrationInterface elem : toApply) {
|
||||||
migrateSingle(entry, elem);
|
migrateSingle(entry, elem, id, count);
|
||||||
}
|
}
|
||||||
|
LOGGER.info("Execute migration ... [ END ]");
|
||||||
}
|
}
|
||||||
public void migrateSingle(DBEntry entry, MigrationInterface elem) {
|
public void migrateSingle(DBEntry entry, MigrationInterface elem, int id, int count) {
|
||||||
LOGGER.info("Revert migration: {} [BEGIN]", elem.getName());
|
LOGGER.info("Migrate: [{}/{}] {} [BEGIN]", id, count, elem.getName());
|
||||||
StringBuilder log = new StringBuilder();
|
StringBuilder log = new StringBuilder();
|
||||||
if (elem.applyMigration(entry, log)) {
|
log.append("Start migration");
|
||||||
|
MigrationModel migrationResult = new MigrationModel();
|
||||||
|
migrationResult.name = elem.getName();
|
||||||
|
migrationResult.stepId = 0;
|
||||||
|
migrationResult.terminated = false;
|
||||||
|
migrationResult.count = elem.getNumberOfStep();
|
||||||
|
migrationResult.log = log.toString();
|
||||||
|
try {
|
||||||
|
migrationResult = SqlWrapper.insert(migrationResult);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
LOGGER.info("Revert migration: {} [ END ]", elem.getName());
|
|
||||||
|
if (elem.applyMigration(entry, log, migrationResult)) {
|
||||||
|
migrationResult.terminated = true;
|
||||||
|
try {
|
||||||
|
SqlWrapper.update(migrationResult, migrationResult.id, List.of("terminated"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info("Migrate: [{}/{}] {} [ END ]", id, count, elem.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void revertTo(DBEntry entry, String migrationName) {
|
public void revertTo(DBEntry entry, String migrationName) {
|
||||||
String currentVersion = getCurrentVersion();
|
MigrationModel currentVersion = getCurrentVersion();
|
||||||
List<MigrationInterface> toApply = new ArrayList<>();
|
List<MigrationInterface> toApply = new ArrayList<>();
|
||||||
boolean find = false;
|
boolean find = false;
|
||||||
for (int iii=this.datas.size()-1; iii>=0; iii--) {
|
for (int iii=this.datas.size()-1; iii>=0; iii--) {
|
||||||
if ( ! find) {
|
if ( ! find) {
|
||||||
if (this.datas.get(iii).getName() == currentVersion) {
|
if (this.datas.get(iii).getName() == currentVersion.name) {
|
||||||
find = true;
|
find = true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (this.datas.get(iii).getName() == currentVersion) {
|
if (this.datas.get(iii).getName() == currentVersion.name) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
toApply.add(this.datas.get(iii));
|
toApply.add(this.datas.get(iii));
|
||||||
}
|
}
|
||||||
|
int id = 0;
|
||||||
|
int count = toApply.size();
|
||||||
for (MigrationInterface elem : toApply) {
|
for (MigrationInterface elem : toApply) {
|
||||||
revertSingle(entry, elem);
|
revertSingle(entry, elem, id, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void revertSingle(DBEntry entry, MigrationInterface elem) {
|
public void revertSingle(DBEntry entry, MigrationInterface elem, int id, int count) {
|
||||||
LOGGER.info("Revert migration: {} [BEGIN]", elem.getName());
|
LOGGER.info("Revert migration: {} [BEGIN]", elem.getName());
|
||||||
|
|
||||||
LOGGER.info("Revert migration: {} [ END ]", elem.getName());
|
LOGGER.info("Revert migration: {} [ END ]", elem.getName());
|
||||||
|
@ -12,9 +12,10 @@ public interface MigrationInterface {
|
|||||||
* Migrate the system to a new version.
|
* Migrate the system to a new version.
|
||||||
* @param entry DB interface for the migration.
|
* @param entry DB interface for the migration.
|
||||||
* @param log Stored data in the BDD for the migration progression.
|
* @param log Stored data in the BDD for the migration progression.
|
||||||
|
* @param migration Migration post data on each step...
|
||||||
* @return true if migration is finished.
|
* @return true if migration is finished.
|
||||||
*/
|
*/
|
||||||
boolean applyMigration(DBEntry entry, StringBuilder log);
|
boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model);
|
||||||
/**
|
/**
|
||||||
* Remove a migration the system to the previous version.
|
* Remove a migration the system to the previous version.
|
||||||
* @param entry DB interface for the migration.
|
* @param entry DB interface for the migration.
|
||||||
@ -22,4 +23,10 @@ public interface MigrationInterface {
|
|||||||
* @return true if migration is finished.
|
* @return true if migration is finished.
|
||||||
*/
|
*/
|
||||||
boolean revertMigration(DBEntry entry, StringBuilder log);
|
boolean revertMigration(DBEntry entry, StringBuilder log);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of step in the migration process.
|
||||||
|
* @return count of SQL access.
|
||||||
|
*/
|
||||||
|
int getNumberOfStep();
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,33 @@
|
|||||||
package org.kar.archidata.migration;
|
package org.kar.archidata.migration;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.SQLComment;
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
|
import org.kar.archidata.annotation.SQLDefault;
|
||||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||||
import org.kar.archidata.annotation.SQLLimitSize;
|
import org.kar.archidata.annotation.SQLLimitSize;
|
||||||
|
import org.kar.archidata.annotation.SQLNotNull;
|
||||||
import org.kar.archidata.annotation.SQLTableName;
|
import org.kar.archidata.annotation.SQLTableName;
|
||||||
import org.kar.archidata.model.GenericTable;
|
import org.kar.archidata.model.GenericTable;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
// For logs only
|
||||||
|
//public static final String TABLE_NAME = "KAR_migration";
|
||||||
|
|
||||||
@SQLTableName ("KAR_migration")
|
@SQLTableName ("KAR_migration")
|
||||||
@SQLIfNotExists
|
@SQLIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class MigrationModel extends GenericTable{
|
public class MigrationModel extends GenericTable{
|
||||||
@SQLComment("Name of the migration")
|
@SQLComment("Name of the migration")
|
||||||
@SQLLimitSize(256)
|
@SQLLimitSize(256)
|
||||||
public String name;
|
public String name;
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLDefault("'0'")
|
||||||
|
@SQLComment("if the migration is well terminated or not")
|
||||||
|
public Boolean terminated = false;
|
||||||
@SQLComment("index in the migration progression")
|
@SQLComment("index in the migration progression")
|
||||||
public Integer index;
|
public Integer stepId = 0;
|
||||||
@SQLComment("number of element in the migration")
|
@SQLComment("number of element in the migration")
|
||||||
public Integer count;
|
public Integer count;
|
||||||
@SQLComment("Log generate by the migration")
|
@SQLComment("Log generate by the migration")
|
||||||
public String log;
|
public String log = "";
|
||||||
}
|
}
|
||||||
|
@ -20,28 +20,45 @@ public class MigrationSqlStep implements MigrationInterface{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applyMigration(DBEntry entry, StringBuilder log) {
|
public boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model) {
|
||||||
for (int iii=0; iii<actions.size(); iii++) {
|
for (int iii=0; iii<actions.size(); iii++) {
|
||||||
log.append("action [" + iii + "/" + actions.size() + "]\n");
|
log.append("action [" + iii + "/" + actions.size() + "]\n");
|
||||||
LOGGER.debug(" >>>> SQL ACTION : {}/{}", iii, actions.size());
|
LOGGER.info(" >>>> SQL ACTION : {}/{}", iii, actions.size());
|
||||||
String action = actions.get(iii);
|
String action = actions.get(iii);
|
||||||
LOGGER.debug("SQL request: ```{}```", action);
|
LOGGER.info("SQL request: ```{}```", action);
|
||||||
log.append("SQL: " + action + "\n");
|
log.append("SQL: " + action + "\n");
|
||||||
try {
|
try {
|
||||||
SqlWrapper.executeSimpleQuerry(action);
|
SqlWrapper.executeQuerry(action);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException | IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
LOGGER.debug("SQL request ERROR: ", ex.getMessage());
|
LOGGER.info("SQL request ERROR: ", ex.getMessage());
|
||||||
log.append("SQL request ERROR: " + ex.getMessage() + "\n");
|
log.append("SQL request ERROR: " + ex.getMessage() + "\n");
|
||||||
return false;
|
model.stepId = iii+1;
|
||||||
} catch (IOException ex) {
|
model.log = log.toString();
|
||||||
ex.printStackTrace();
|
try {
|
||||||
LOGGER.debug("IO request ERROR: ", ex.getMessage());
|
SqlWrapper.update(model, model.id, List.of("stepId", "log"));
|
||||||
log.append("IO request ERROR: " + ex.getMessage() + "\n");
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log.append("action [" + iii + "/" + actions.size() + "] ==> DONE\n");
|
log.append("action [" + iii + "/" + actions.size() + "] ==> DONE\n");
|
||||||
LOGGER.debug(" >>>> SQL ACTION : {}/{} ==> DONE", iii, actions.size());
|
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> DONE", iii, actions.size());
|
||||||
|
model.stepId = iii+1;
|
||||||
|
model.log = log.toString();
|
||||||
|
try {
|
||||||
|
SqlWrapper.update(model, model.id, List.of("stepId", "log"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -55,7 +72,13 @@ public class MigrationSqlStep implements MigrationInterface{
|
|||||||
actions.add(action);
|
actions.add(action);
|
||||||
}
|
}
|
||||||
public void addClass(Class<?> clazz) throws Exception {
|
public void addClass(Class<?> clazz) throws Exception {
|
||||||
actions.add(SqlWrapper.createTable(clazz));
|
List<String> tmp = SqlWrapper.createTable(clazz, false);
|
||||||
|
actions.addAll(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumberOfStep() {
|
||||||
|
return actions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user