Merge branch 'dev' into data-import

This commit is contained in:
Chat2DB
2024-06-15 19:27:30 +08:00
committed by GitHub
37 changed files with 3153 additions and 198 deletions

View File

@ -134,6 +134,8 @@ public class MysqlDBManage extends DefaultDBManage implements DBManage {
} catch (Exception e) {
connection.rollback();
throw new RuntimeException(e);
}finally {
connection.setAutoCommit(true);
}
}

View File

@ -2,6 +2,7 @@ package ai.chat2db.plugin.mysql.builder;
import ai.chat2db.plugin.mysql.type.MysqlColumnTypeEnum;
import ai.chat2db.plugin.mysql.type.MysqlIndexTypeEnum;
import ai.chat2db.spi.enums.EditStatus;
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
import ai.chat2db.spi.model.Database;
import ai.chat2db.spi.model.Table;
@ -75,12 +76,14 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
@Override
public String buildModifyTaleSql(Table oldTable, Table newTable) {
StringBuilder script = new StringBuilder();
script.append("ALTER TABLE ");
StringBuilder tableBuilder = new StringBuilder();
tableBuilder.append("ALTER TABLE ");
if (StringUtils.isNotBlank(oldTable.getDatabaseName())) {
script.append("`").append(oldTable.getDatabaseName()).append("`").append(".");
tableBuilder.append("`").append(oldTable.getDatabaseName()).append("`").append(".");
}
script.append("`").append(oldTable.getName()).append("`").append("\n");
tableBuilder.append("`").append(oldTable.getName()).append("`").append("\n");
StringBuilder script = new StringBuilder();
if (!StringUtils.equalsIgnoreCase(oldTable.getName(), newTable.getName())) {
script.append("\t").append("RENAME TO ").append("`").append(newTable.getName()).append("`").append(",\n");
}
@ -91,11 +94,27 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
script.append("\t").append("AUTO_INCREMENT=").append(newTable.getIncrementValue()).append(",\n");
}
// 判断新增字段
List<TableColumn> addColumnList = new ArrayList<>();
for (TableColumn tableColumn : newTable.getColumnList()) {
if (tableColumn.getEditStatus() != null ? tableColumn.getEditStatus().equals("ADD") : false) {
addColumnList.add(tableColumn);
}
}
// 判断移动的字段
List<TableColumn> moveColumnList = movedElements(oldTable.getColumnList(), newTable.getColumnList());
// append modify column
for (TableColumn tableColumn : newTable.getColumnList()) {
if (StringUtils.isNotBlank(tableColumn.getEditStatus()) && StringUtils.isNotBlank(tableColumn.getColumnType()) && StringUtils.isNotBlank(tableColumn.getName())) {
if ((StringUtils.isNotBlank(tableColumn.getEditStatus()) && StringUtils.isNotBlank(tableColumn.getColumnType())
&& StringUtils.isNotBlank(tableColumn.getName())) || moveColumnList.contains(tableColumn) || addColumnList.contains(tableColumn)) {
MysqlColumnTypeEnum typeEnum = MysqlColumnTypeEnum.getByType(tableColumn.getColumnType());
script.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(",\n");
if (moveColumnList.contains(tableColumn) || addColumnList.contains(tableColumn)) {
script.append("\t").append(typeEnum.buildModifyColumn(tableColumn, true, findPrevious(tableColumn, newTable))).append(",\n");
} else {
script.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(",\n");
}
}
}
@ -108,16 +127,31 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
}
// append reorder column
script.append(buildGenerateReorderColumnSql(oldTable, newTable));
// script.append(buildGenerateReorderColumnSql(oldTable, newTable));
if (script.length() > 2) {
script = new StringBuilder(script.substring(0, script.length() - 2));
script.append(";");
return tableBuilder.append(script).toString();
}else {
return StringUtils.EMPTY;
}
return script.toString();
}
private String findPrevious(TableColumn tableColumn, Table newTable) {
int index = newTable.getColumnList().indexOf(tableColumn);
if (index == 0) {
return "-1";
}
// Find the previous column that is not deleted
for (int i = index - 1; i >= 0; i--) {
if (newTable.getColumnList().get(i).getEditStatus() == null || !newTable.getColumnList().get(i).getEditStatus().equals(EditStatus.DELETE.name())) {
return newTable.getColumnList().get(i).getName();
}
}
return "-1";
}
@Override
public String pageLimit(String sql, int offset, int pageNo, int pageSize) {
@ -149,6 +183,47 @@ public class MysqlSqlBuilder extends DefaultSqlBuilder {
return sqlBuilder.toString();
}
public static List<TableColumn> movedElements(List<TableColumn> original, List<TableColumn> modified) {
int[][] dp = new int[original.size() + 1][modified.size() + 1];
// 构建DP表
for (int i = 1; i <= original.size(); i++) {
for (int j = 1; j <= modified.size(); j++) {
if (original.get(i - 1).getName().equals(modified.get(j - 1).getOldName())) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// 追踪LCS找出移动了位置的元素
List<TableColumn> moved = new ArrayList<>();
int i = original.size();
int j = modified.size();
while (i > 0 && j > 0) {
if (original.get(i - 1).equals(modified.get(j - 1))) {
i--;
j--;
} else if (dp[i - 1][j] >= dp[i][j - 1]) {
moved.add(original.get(i - 1));
// modified List中找到original.get(i-1)的位置
System.out.println("Moved elements:"+ original.get(i-1).getName() + " after " + modified.indexOf(original.get(i-1)) );
i--;
} else {
j--;
}
}
// 这里添加原始列表中未被包含在LCS中的元素
while (i > 0) {
moved.add(original.get(i - 1));
i--;
}
return moved;
}
public String buildGenerateReorderColumnSql(Table oldTable, Table newTable) {
StringBuilder sql = new StringBuilder();
int n = 0;

View File

@ -199,6 +199,37 @@ public enum MysqlColumnTypeEnum implements ColumnBuilder {
return "";
}
public String buildModifyColumn(TableColumn tableColumn, boolean isMove, String columnName) {
if (EditStatus.DELETE.name().equals(tableColumn.getEditStatus())) {
return StringUtils.join("DROP COLUMN `", tableColumn.getName() + "`");
}
if (EditStatus.ADD.name().equals(tableColumn.getEditStatus())) {
if (isMove){
if (columnName.equals("-1")) {
return StringUtils.join("ADD COLUMN ", buildCreateColumnSql(tableColumn)," FIRST");
} else {
return StringUtils.join("ADD COLUMN ", buildCreateColumnSql(tableColumn), " AFTER ", columnName);
}
}
return StringUtils.join("ADD COLUMN ", buildCreateColumnSql(tableColumn));
}
if (EditStatus.MODIFY.name().equals(tableColumn.getEditStatus())) {
if (!StringUtils.equalsIgnoreCase(tableColumn.getOldName(), tableColumn.getName())) {
return StringUtils.join("CHANGE COLUMN `", tableColumn.getOldName(), "` ", buildCreateColumnSql(tableColumn));
} else {
return StringUtils.join("MODIFY COLUMN ", buildCreateColumnSql(tableColumn));
}
}
if (isMove) {
if (columnName.equals("-1")) {
return StringUtils.join("MODIFY COLUMN ", buildCreateColumnSql(tableColumn)," FIRST");
} else {
return StringUtils.join("MODIFY COLUMN ", buildCreateColumnSql(tableColumn), " AFTER ", columnName);
}
}
return "";
}
private String buildAutoIncrement(TableColumn column, MysqlColumnTypeEnum type) {
if(!type.getColumnType().isSupportAutoIncrement()){
return "";