mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-29 10:43:06 +08:00
Support DM TABLE create and edit.
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
package ai.chat2db.plugin.db2.builder;
|
package ai.chat2db.plugin.db2.builder;
|
||||||
|
|
||||||
import ai.chat2db.spi.SqlBuilder;
|
|
||||||
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
||||||
import ai.chat2db.spi.model.Schema;
|
import ai.chat2db.spi.model.Schema;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -13,9 +12,9 @@ public class DB2SqlBuilder extends DefaultSqlBuilder {
|
|||||||
int startRow = offset + 1;
|
int startRow = offset + 1;
|
||||||
int endRow = offset + pageSize;
|
int endRow = offset + pageSize;
|
||||||
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120);
|
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120);
|
||||||
sqlBuilder.append("SELECT * FROM (SELECT TMP_PAGE.*,ROWNUMBER() OVER() AS PAGEHELPER_ROW_ID FROM ( \n");
|
sqlBuilder.append("SELECT * FROM (SELECT TMP_PAGE.*,ROWNUMBER() OVER() AS CAHT2DB_AUTO_ROW_ID FROM ( \n");
|
||||||
sqlBuilder.append(sql);
|
sqlBuilder.append(sql);
|
||||||
sqlBuilder.append("\n ) AS TMP_PAGE) TMP_PAGE WHERE PAGEHELPER_ROW_ID BETWEEN ");
|
sqlBuilder.append("\n ) AS TMP_PAGE) TMP_PAGE WHERE CAHT2DB_AUTO_ROW_ID BETWEEN ");
|
||||||
sqlBuilder.append(startRow);
|
sqlBuilder.append(startRow);
|
||||||
sqlBuilder.append(" AND ");
|
sqlBuilder.append(" AND ");
|
||||||
sqlBuilder.append(endRow);
|
sqlBuilder.append(endRow);
|
||||||
@ -33,4 +32,7 @@ public class DB2SqlBuilder extends DefaultSqlBuilder {
|
|||||||
|
|
||||||
return sqlBuilder.toString();
|
return sqlBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,31 @@
|
|||||||
package ai.chat2db.plugin.dm;
|
package ai.chat2db.plugin.dm;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import ai.chat2db.spi.DBManage;
|
import ai.chat2db.spi.DBManage;
|
||||||
import ai.chat2db.spi.jdbc.DefaultDBManage;
|
import ai.chat2db.spi.jdbc.DefaultDBManage;
|
||||||
|
import ai.chat2db.spi.sql.Chat2DBContext;
|
||||||
|
import ai.chat2db.spi.sql.ConnectInfo;
|
||||||
import ai.chat2db.spi.sql.SQLExecutor;
|
import ai.chat2db.spi.sql.SQLExecutor;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public class DMDBManage extends DefaultDBManage implements DBManage {
|
public class DMDBManage extends DefaultDBManage implements DBManage {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectDatabase(Connection connection, String database) {
|
||||||
|
ConnectInfo connectInfo = Chat2DBContext.getConnectInfo();
|
||||||
|
if (ObjectUtils.anyNull(connectInfo) || StringUtils.isEmpty(connectInfo.getSchemaName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String schemaName = connectInfo.getSchemaName();
|
||||||
|
try {
|
||||||
|
SQLExecutor.getInstance().execute(connection, "SET SCHEMA \"" + schemaName + "\"");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dropTable(Connection connection, String databaseName, String schemaName, String tableName) {
|
public void dropTable(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||||
|
@ -1,18 +1,24 @@
|
|||||||
package ai.chat2db.plugin.dm;
|
package ai.chat2db.plugin.dm;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
import java.util.stream.Collectors;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
import ai.chat2db.plugin.dm.builder.DMSqlBuilder;
|
||||||
|
import ai.chat2db.plugin.dm.type.DMColumnTypeEnum;
|
||||||
|
import ai.chat2db.plugin.dm.type.DMIndexTypeEnum;
|
||||||
import ai.chat2db.spi.MetaData;
|
import ai.chat2db.spi.MetaData;
|
||||||
|
import ai.chat2db.spi.SqlBuilder;
|
||||||
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
||||||
import ai.chat2db.spi.model.*;
|
import ai.chat2db.spi.model.*;
|
||||||
import ai.chat2db.spi.sql.SQLExecutor;
|
import ai.chat2db.spi.sql.SQLExecutor;
|
||||||
import ai.chat2db.spi.util.SortUtils;
|
import ai.chat2db.spi.util.SortUtils;
|
||||||
import ai.chat2db.spi.util.SqlUtils;
|
import ai.chat2db.spi.util.SqlUtils;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public class DMMetaData extends DefaultMetaService implements MetaData {
|
public class DMMetaData extends DefaultMetaService implements MetaData {
|
||||||
|
|
||||||
@ -138,4 +144,85 @@ public class DMMetaData extends DefaultMetaService implements MetaData {
|
|||||||
return table;
|
return table;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String INDEX_SQL = "SELECT i.TABLE_NAME, i.INDEX_TYPE, i.INDEX_NAME, i.UNIQUENESS ,c.COLUMN_NAME, c.COLUMN_POSITION, c.DESCEND, cons.CONSTRAINT_TYPE FROM ALL_INDEXES i JOIN ALL_IND_COLUMNS c ON i.INDEX_NAME = c.INDEX_NAME AND i.TABLE_NAME = c.TABLE_NAME AND i.TABLE_OWNER = c.TABLE_OWNER LEFT JOIN ALL_CONSTRAINTS cons ON i.INDEX_NAME = cons.INDEX_NAME AND i.TABLE_NAME = cons.TABLE_NAME AND i.TABLE_OWNER = cons.OWNER WHERE i.TABLE_NAME = '%s' ORDER BY i.INDEX_NAME, c.COLUMN_POSITION;";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||||
|
String sql = String.format(INDEX_SQL, schemaName, tableName);
|
||||||
|
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||||
|
LinkedHashMap<String, TableIndex> map = new LinkedHashMap();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
String keyName = resultSet.getString("INDEX_NAME");
|
||||||
|
TableIndex tableIndex = map.get(keyName);
|
||||||
|
if (tableIndex != null) {
|
||||||
|
List<TableIndexColumn> columnList = tableIndex.getColumnList();
|
||||||
|
columnList.add(getTableIndexColumn(resultSet));
|
||||||
|
columnList = columnList.stream().sorted(Comparator.comparing(TableIndexColumn::getOrdinalPosition))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
tableIndex.setColumnList(columnList);
|
||||||
|
} else {
|
||||||
|
TableIndex index = new TableIndex();
|
||||||
|
index.setDatabaseName(databaseName);
|
||||||
|
index.setSchemaName(schemaName);
|
||||||
|
index.setTableName(tableName);
|
||||||
|
index.setName(keyName);
|
||||||
|
index.setUnique("UNIQUE".equalsIgnoreCase(resultSet.getString("UNIQUENESS")));
|
||||||
|
// index.setType(resultSet.getString("Index_type"));
|
||||||
|
// index.setComment(resultSet.getString("Index_comment"));
|
||||||
|
List<TableIndexColumn> tableIndexColumns = new ArrayList<>();
|
||||||
|
tableIndexColumns.add(getTableIndexColumn(resultSet));
|
||||||
|
index.setColumnList(tableIndexColumns);
|
||||||
|
if ("P".equalsIgnoreCase(resultSet.getString("CONSTRAINT_TYPE"))) {
|
||||||
|
index.setType(DMIndexTypeEnum.PRIMARY_KEY.getName());
|
||||||
|
} else if (index.getUnique()) {
|
||||||
|
index.setType(DMIndexTypeEnum.UNIQUE.getName());
|
||||||
|
} else if ("BITMAP".equalsIgnoreCase(resultSet.getString("INDEX_TYPE"))) {
|
||||||
|
index.setType(DMIndexTypeEnum.BITMAP.getName());
|
||||||
|
} else {
|
||||||
|
index.setType(DMIndexTypeEnum.NORMAL.getName());
|
||||||
|
}
|
||||||
|
map.put(keyName, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map.values().stream().collect(Collectors.toList());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private TableIndexColumn getTableIndexColumn(ResultSet resultSet) throws SQLException {
|
||||||
|
TableIndexColumn tableIndexColumn = new TableIndexColumn();
|
||||||
|
tableIndexColumn.setColumnName(resultSet.getString("COLUMN_NAME"));
|
||||||
|
tableIndexColumn.setOrdinalPosition(resultSet.getShort("COLUMN_POSITION"));
|
||||||
|
// tableIndexColumn.setCollation(resultSet.getString("Collation"));
|
||||||
|
// tableIndexColumn.setCardinality(resultSet.getLong("Cardinality"));
|
||||||
|
// tableIndexColumn.setSubPart(resultSet.getLong("Sub_part"));
|
||||||
|
String collation = resultSet.getString("DESCEND");
|
||||||
|
if ("ASC".equalsIgnoreCase(collation)) {
|
||||||
|
tableIndexColumn.setAscOrDesc("ASC");
|
||||||
|
} else if ("DESC".equalsIgnoreCase(collation)) {
|
||||||
|
tableIndexColumn.setAscOrDesc("DESC");
|
||||||
|
}
|
||||||
|
return tableIndexColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlBuilder getSqlBuilder() {
|
||||||
|
return new DMSqlBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableMeta getTableMeta(String databaseName, String schemaName, String tableName) {
|
||||||
|
return TableMeta.builder()
|
||||||
|
.columnTypes(DMColumnTypeEnum.getTypes())
|
||||||
|
.charsets(Lists.newArrayList())
|
||||||
|
.collations(Lists.newArrayList())
|
||||||
|
.indexTypes(DMIndexTypeEnum.getIndexTypes())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMetaDataName(String... names) {
|
||||||
|
return Arrays.stream(names).filter(name -> StringUtils.isNotBlank(name)).map(name -> "\"" + name + "\"").collect(Collectors.joining("."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
package ai.chat2db.plugin.dm.builder;
|
||||||
|
|
||||||
|
import ai.chat2db.plugin.dm.type.DMColumnTypeEnum;
|
||||||
|
import ai.chat2db.plugin.dm.type.DMIndexTypeEnum;
|
||||||
|
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
||||||
|
import ai.chat2db.spi.model.Schema;
|
||||||
|
import ai.chat2db.spi.model.Table;
|
||||||
|
import ai.chat2db.spi.model.TableColumn;
|
||||||
|
import ai.chat2db.spi.model.TableIndex;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
public class DMSqlBuilder extends DefaultSqlBuilder {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildCreateTableSql(Table table) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
|
||||||
|
script.append("CREATE TABLE ").append("\"").append(table.getSchemaName()).append("\".\"").append(table.getName()).append("\" (").append("\n");
|
||||||
|
|
||||||
|
for (TableColumn column : table.getColumnList()) {
|
||||||
|
if (StringUtils.isBlank(column.getName()) || StringUtils.isBlank(column.getColumnType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DMColumnTypeEnum typeEnum = DMColumnTypeEnum.getByType(column.getColumnType());
|
||||||
|
script.append("\t").append(typeEnum.buildCreateColumnSql(column)).append(",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||||
|
script.append("\n);");
|
||||||
|
|
||||||
|
for (TableIndex tableIndex : table.getIndexList()) {
|
||||||
|
if (StringUtils.isBlank(tableIndex.getName()) || StringUtils.isBlank(tableIndex.getType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DMIndexTypeEnum indexTypeEnum = DMIndexTypeEnum.getByType(tableIndex.getType());
|
||||||
|
script.append("\n").append("").append(indexTypeEnum.buildIndexScript(tableIndex)).append(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TableColumn column : table.getColumnList()) {
|
||||||
|
if (StringUtils.isBlank(column.getName()) || StringUtils.isBlank(column.getColumnType()) || StringUtils.isBlank(column.getComment())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
script.append("\n").append(buildComment(column)).append(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(table.getComment())) {
|
||||||
|
script.append("\n").append(buildTableComment(table)).append(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildTableComment(Table table) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("COMMENT ON TABLE ").append("\"").append(table.getSchemaName()).append("\".\"").append(table.getName()).append("\" IS '").append(table.getComment()).append("'");
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildComment(TableColumn column) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("COMMENT ON COLUMN ").append("\"").append(column.getSchemaName()).append("\".\"").append(column.getTableName()).append("\".\"").append(column.getName()).append("\" IS '").append(column.getComment()).append("'");
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildModifyTaleSql(Table oldTable, Table newTable) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
|
||||||
|
if (!StringUtils.equalsIgnoreCase(oldTable.getName(), newTable.getName())) {
|
||||||
|
script.append("ALTER TABLE ").append("\"").append(oldTable.getSchemaName()).append("\".\"").append(oldTable.getName()).append("\"");
|
||||||
|
script.append(" ").append("RENAME TO ").append("\"").append(newTable.getName()).append("\"").append(";\n");
|
||||||
|
}
|
||||||
|
if (!StringUtils.equalsIgnoreCase(oldTable.getComment(), newTable.getComment())) {
|
||||||
|
script.append("").append(buildTableComment(newTable)).append(";\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// append modify column
|
||||||
|
for (TableColumn tableColumn : newTable.getColumnList()) {
|
||||||
|
if (StringUtils.isNotBlank(tableColumn.getEditStatus())) {
|
||||||
|
DMColumnTypeEnum typeEnum = DMColumnTypeEnum.getByType(tableColumn.getColumnType());
|
||||||
|
script.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(";\n");
|
||||||
|
if (StringUtils.isNotBlank(tableColumn.getComment())) {
|
||||||
|
script.append("\n").append(buildComment(tableColumn)).append(";\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append modify index
|
||||||
|
for (TableIndex tableIndex : newTable.getIndexList()) {
|
||||||
|
if (StringUtils.isNotBlank(tableIndex.getEditStatus()) && StringUtils.isNotBlank(tableIndex.getType())) {
|
||||||
|
DMIndexTypeEnum mysqlIndexTypeEnum = DMIndexTypeEnum.getByType(tableIndex.getType());
|
||||||
|
script.append("\t").append(mysqlIndexTypeEnum.buildModifyIndex(tableIndex)).append(";\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (script.length() > 2) {
|
||||||
|
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||||
|
script.append(";");
|
||||||
|
}
|
||||||
|
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String pageLimit(String sql, int offset, int pageNo, int pageSize) {
|
||||||
|
StringBuilder sqlStr = new StringBuilder(sql.length() + 17);
|
||||||
|
sqlStr.append(sql);
|
||||||
|
if (offset == 0) {
|
||||||
|
sqlStr.append(" LIMIT ");
|
||||||
|
sqlStr.append(pageSize);
|
||||||
|
} else {
|
||||||
|
sqlStr.append(" LIMIT ");
|
||||||
|
sqlStr.append(pageSize);
|
||||||
|
sqlStr.append(" OFFSET ");
|
||||||
|
sqlStr.append(offset);
|
||||||
|
}
|
||||||
|
return sqlStr.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildCreateSchemaSql(Schema schema) {
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder();
|
||||||
|
sqlBuilder.append("CREATE SCHEMA \""+schema.getName()+"\"");
|
||||||
|
if(StringUtils.isNotBlank(schema.getOwner())){
|
||||||
|
sqlBuilder.append(" AUTHORIZATION ").append(schema.getOwner());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,289 @@
|
|||||||
|
package ai.chat2db.plugin.dm.type;
|
||||||
|
|
||||||
|
import ai.chat2db.spi.ColumnBuilder;
|
||||||
|
import ai.chat2db.spi.enums.EditStatus;
|
||||||
|
import ai.chat2db.spi.model.ColumnType;
|
||||||
|
import ai.chat2db.spi.model.TableColumn;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum DMColumnTypeEnum implements ColumnBuilder {
|
||||||
|
|
||||||
|
|
||||||
|
BFILE("BFILE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
BIGINT("BIGINT", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
BINARY("BINARY", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
BIT("BIT", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
BLOB("BLOB", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
CHAR("CHAR", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
|
||||||
|
// CHAR_VARYING("CHAR VARYING", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
//
|
||||||
|
// CHARACTER("CHARACTER", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
//
|
||||||
|
// CHARACTER_VARYING("CHARACTER VARYING", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
|
||||||
|
CLOB("CLOB", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
DATE("DATE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
DECIMAL("DECIMAL", true, true, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
DOUBLE("DOUBLE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
FLOAT("FLOAT", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INT("INT", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
// INTEGER("INTEGER", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_DAY("INTERVAL DAY", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_DAY_TO_HOUR("INTERVAL DAY TO HOUR", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
INTERVAL_DAY_TO_MINUTE("INTERVAL DAY TO MINUTE", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_DAY_TO_SECOND("INTERVAL DAY TO SECOND", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_HOUR("INTERVAL HOUR", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_HOUR_TO_MINUTE("INTERVAL HOUR TO MINUTE", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_HOUR_TO_SECOND("INTERVAL HOUR TO SECOND", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_MINUTE("INTERVAL MINUTE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_MINUTE_TO_SECOND("INTERVAL MINUTE TO SECOND", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
INTERVAL_MONTH("INTERVAL MONTH", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
INTERVAL_SECOND("INTERVAL SECOND", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
INTERVAL_YEAR("INTERVAL YEAR", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
INTERVAL_YEAR_TO_MONTH("INTERVAL YEAR TO MONTH", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
LONGVARBINARY("LONGVARBINARY", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
LONGVARCHAR("LONGVARCHAR", true, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
NUMBERIC("NUMBERIC", true, true, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
NUMBER("NUMBER", true, true, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
REAL("REAL", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
SMALLINT("SMALLINT", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
TIME("TIME", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
TIME_WITH_TIME_ZONE("TIME WITH TIME ZONE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
TIMESTAMP("TIMESTAMP", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
TIMESTAMP_WITH_TIME_ZONE("TIMESTAMP WITH TIME ZONE", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
TINYINT("TINYINT", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
VARBINARY("VARBINARY", false, false, true, false, false, false, true, true, false, false),
|
||||||
|
|
||||||
|
|
||||||
|
VARCHAR("VARCHAR", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
|
||||||
|
|
||||||
|
VARCHAR2("VARCHAR2", true, false, true, false, false, false, true, true, false, true),
|
||||||
|
|
||||||
|
;
|
||||||
|
private ColumnType columnType;
|
||||||
|
|
||||||
|
public static DMColumnTypeEnum getByType(String dataType) {
|
||||||
|
return COLUMN_TYPE_MAP.get(dataType.toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, DMColumnTypeEnum> COLUMN_TYPE_MAP = Maps.newHashMap();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (DMColumnTypeEnum value : DMColumnTypeEnum.values()) {
|
||||||
|
COLUMN_TYPE_MAP.put(value.getColumnType().getTypeName(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColumnType getColumnType() {
|
||||||
|
return columnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DMColumnTypeEnum(String dataTypeName, boolean supportLength, boolean supportScale, boolean supportNullable, boolean supportAutoIncrement, boolean supportCharset, boolean supportCollation, boolean supportComments, boolean supportDefaultValue, boolean supportExtent, boolean supportUnit) {
|
||||||
|
this.columnType = new ColumnType(dataTypeName, supportLength, supportScale, supportNullable, supportAutoIncrement, supportCharset, supportCollation, supportComments, supportDefaultValue, supportExtent, false, supportUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildCreateColumnSql(TableColumn column) {
|
||||||
|
DMColumnTypeEnum type = COLUMN_TYPE_MAP.get(column.getColumnType().toUpperCase());
|
||||||
|
if (type == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
|
||||||
|
script.append("\"").append(column.getName()).append("\"").append(" ");
|
||||||
|
|
||||||
|
script.append(buildDataType(column, type)).append(" ");
|
||||||
|
|
||||||
|
script.append(buildDefaultValue(column, type)).append(" ");
|
||||||
|
|
||||||
|
script.append(buildNullable(column, type)).append(" ");
|
||||||
|
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String buildNullable(TableColumn column, DMColumnTypeEnum type) {
|
||||||
|
if (!type.getColumnType().isSupportNullable()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (column.getNullable() != null && 1 == column.getNullable()) {
|
||||||
|
return "NULL";
|
||||||
|
} else {
|
||||||
|
return "NOT NULL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDefaultValue(TableColumn column, DMColumnTypeEnum type) {
|
||||||
|
if (!type.getColumnType().isSupportDefaultValue() || StringUtils.isEmpty(column.getDefaultValue())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("EMPTY_STRING".equalsIgnoreCase(column.getDefaultValue().trim())) {
|
||||||
|
return StringUtils.join("DEFAULT ''");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("NULL".equalsIgnoreCase(column.getDefaultValue().trim())) {
|
||||||
|
return StringUtils.join("DEFAULT NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.join("DEFAULT ", column.getDefaultValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDataType(TableColumn column, DMColumnTypeEnum type) {
|
||||||
|
String columnType = type.columnType.getTypeName();
|
||||||
|
if (Arrays.asList(CHAR, VARCHAR, VARCHAR2, LONGVARCHAR).contains(type)) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append(columnType);
|
||||||
|
if (column.getColumnSize() != null && StringUtils.isEmpty(column.getUnit())) {
|
||||||
|
script.append("(").append(column.getColumnSize()).append(")");
|
||||||
|
} else if (column.getColumnSize() != null && !StringUtils.isEmpty(column.getUnit())) {
|
||||||
|
script.append("(").append(column.getColumnSize()).append(" ").append(column.getUnit()).append(")");
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arrays.asList(DECIMAL, FLOAT, NUMBER, TIMESTAMP, NUMBERIC).contains(type)) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append(columnType);
|
||||||
|
if (column.getColumnSize() != null && column.getDecimalDigits() == null) {
|
||||||
|
script.append("(").append(column.getColumnSize()).append(")");
|
||||||
|
} else if (column.getColumnSize() != null && column.getDecimalDigits() != null) {
|
||||||
|
script.append("(").append(column.getColumnSize()).append(",").append(column.getDecimalDigits()).append(")");
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arrays.asList(TIMESTAMP_WITH_TIME_ZONE).contains(type)) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
if (column.getColumnSize() == null) {
|
||||||
|
script.append(columnType);
|
||||||
|
} else {
|
||||||
|
String[] split = columnType.split("TIMESTAMP");
|
||||||
|
script.append("TIMESTAMP").append("(").append(column.getColumnSize()).append(")").append(split[1]);
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arrays.asList(INTERVAL_DAY_TO_HOUR,
|
||||||
|
INTERVAL_DAY_TO_MINUTE, INTERVAL_DAY_TO_SECOND,
|
||||||
|
INTERVAL_HOUR_TO_MINUTE,
|
||||||
|
INTERVAL_HOUR_TO_SECOND,
|
||||||
|
INTERVAL_MINUTE_TO_SECOND,
|
||||||
|
INTERVAL_YEAR_TO_MONTH).contains(type)) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
if (column.getColumnSize() == null) {
|
||||||
|
script.append(columnType);
|
||||||
|
} else {
|
||||||
|
String[] split = columnType.split(" ");
|
||||||
|
if (split.length == 4) {
|
||||||
|
script.append(split[0]).append(" ").append(split[1]).append(" (").append(column.getColumnSize()).append(") ").append(split[2]).append(" ").append(split[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildModifyColumn(TableColumn tableColumn) {
|
||||||
|
|
||||||
|
if (EditStatus.DELETE.name().equals(tableColumn.getEditStatus())) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("ALTER TABLE ").append("\"").append(tableColumn.getSchemaName()).append("\".\"").append(tableColumn.getTableName()).append("\"");
|
||||||
|
script.append(" ").append("DROP COLUMN ").append("\"").append(tableColumn.getName()).append("\"");
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
if (EditStatus.ADD.name().equals(tableColumn.getEditStatus())) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("ALTER TABLE ").append("\"").append(tableColumn.getSchemaName()).append("\".\"").append(tableColumn.getTableName()).append("\"");
|
||||||
|
script.append(" ").append("ADD (").append(buildCreateColumnSql(tableColumn)).append(")");
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
if (EditStatus.MODIFY.name().equals(tableColumn.getEditStatus())) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("ALTER TABLE ").append("\"").append(tableColumn.getSchemaName()).append("\".\"").append(tableColumn.getTableName()).append("\"");
|
||||||
|
script.append(" ").append("MODIFY (").append(buildCreateColumnSql(tableColumn)).append(") \n");
|
||||||
|
|
||||||
|
if (!StringUtils.equalsIgnoreCase(tableColumn.getOldName(), tableColumn.getName())) {
|
||||||
|
script.append(";");
|
||||||
|
script.append("ALTER TABLE ").append("\"").append(tableColumn.getSchemaName()).append("\".\"").append(tableColumn.getTableName()).append("\"");
|
||||||
|
script.append(" ").append("RENAME COLUMN ").append("\"").append(tableColumn.getOldName()).append("\"").append(" TO ").append("\"").append(tableColumn.getName()).append("\"");
|
||||||
|
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ColumnType> getTypes() {
|
||||||
|
return Arrays.stream(DMColumnTypeEnum.values()).map(columnTypeEnum ->
|
||||||
|
columnTypeEnum.getColumnType()
|
||||||
|
).toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package ai.chat2db.plugin.dm.type;
|
||||||
|
|
||||||
|
import ai.chat2db.spi.enums.EditStatus;
|
||||||
|
import ai.chat2db.spi.model.IndexType;
|
||||||
|
import ai.chat2db.spi.model.TableIndex;
|
||||||
|
import ai.chat2db.spi.model.TableIndexColumn;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum DMIndexTypeEnum {
|
||||||
|
|
||||||
|
PRIMARY_KEY("Primary", "PRIMARY KEY"),
|
||||||
|
|
||||||
|
NORMAL("Normal", "INDEX"),
|
||||||
|
|
||||||
|
UNIQUE("Unique", "UNIQUE INDEX"),
|
||||||
|
|
||||||
|
BITMAP("BITMAP", "BITMAP INDEX");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public IndexType getIndexType() {
|
||||||
|
return indexType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndexType(IndexType indexType) {
|
||||||
|
this.indexType = indexType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexType indexType;
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
public String getKeyword() {
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String keyword;
|
||||||
|
|
||||||
|
DMIndexTypeEnum(String name, String keyword) {
|
||||||
|
this.name = name;
|
||||||
|
this.keyword = keyword;
|
||||||
|
this.indexType = new IndexType(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static DMIndexTypeEnum getByType(String type) {
|
||||||
|
for (DMIndexTypeEnum value : DMIndexTypeEnum.values()) {
|
||||||
|
if (value.name.equalsIgnoreCase(type)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String buildIndexScript(TableIndex tableIndex) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
if (PRIMARY_KEY.equals(this)) {
|
||||||
|
script.append("ALTER TABLE \"").append(tableIndex.getSchemaName()).append("\".\"").append(tableIndex.getTableName()).append("\" ADD PRIMARY KEY ").append(buildIndexColumn(tableIndex));
|
||||||
|
} else {
|
||||||
|
if (UNIQUE.equals(this)) {
|
||||||
|
script.append("CREATE UNIQUE INDEX ");
|
||||||
|
} else {
|
||||||
|
script.append("CREATE INDEX ");
|
||||||
|
}
|
||||||
|
script.append(buildIndexName(tableIndex)).append(" ON \"").append(tableIndex.getSchemaName()).append("\".\"").append(tableIndex.getTableName()).append("\" ").append(buildIndexColumn(tableIndex));
|
||||||
|
}
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String buildIndexColumn(TableIndex tableIndex) {
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("(");
|
||||||
|
for (TableIndexColumn column : tableIndex.getColumnList()) {
|
||||||
|
if (StringUtils.isNotBlank(column.getColumnName())) {
|
||||||
|
script.append("\"").append(column.getColumnName()).append("\"");
|
||||||
|
if (!StringUtils.isBlank(column.getAscOrDesc()) && !PRIMARY_KEY.equals(this)) {
|
||||||
|
script.append(" ").append(column.getAscOrDesc());
|
||||||
|
}
|
||||||
|
script.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
script.deleteCharAt(script.length() - 1);
|
||||||
|
script.append(")");
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildIndexName(TableIndex tableIndex) {
|
||||||
|
return "\"" + tableIndex.getSchemaName() + "\"." + "\"" + tableIndex.getName() + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String buildModifyIndex(TableIndex tableIndex) {
|
||||||
|
if (EditStatus.DELETE.name().equals(tableIndex.getEditStatus())) {
|
||||||
|
return buildDropIndex(tableIndex);
|
||||||
|
}
|
||||||
|
if (EditStatus.MODIFY.name().equals(tableIndex.getEditStatus())) {
|
||||||
|
return StringUtils.join(buildDropIndex(tableIndex), ";\n", buildIndexScript(tableIndex));
|
||||||
|
}
|
||||||
|
if (EditStatus.ADD.name().equals(tableIndex.getEditStatus())) {
|
||||||
|
return StringUtils.join(buildIndexScript(tableIndex));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDropIndex(TableIndex tableIndex) {
|
||||||
|
if (DMIndexTypeEnum.PRIMARY_KEY.getName().equals(tableIndex.getType())) {
|
||||||
|
String tableName = "\"" + tableIndex.getSchemaName() + "\"." + "\"" + tableIndex.getTableName() + "\"";
|
||||||
|
return StringUtils.join("ALTER TABLE ",tableName," DROP PRIMARY KEY");
|
||||||
|
}
|
||||||
|
StringBuilder script = new StringBuilder();
|
||||||
|
script.append("DROP INDEX ");
|
||||||
|
script.append(buildIndexName(tableIndex));
|
||||||
|
|
||||||
|
return script.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<IndexType> getIndexTypes() {
|
||||||
|
return Arrays.asList(DMIndexTypeEnum.values()).stream().map(DMIndexTypeEnum::getIndexType).collect(java.util.stream.Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user