mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-31 19:52:54 +08:00
support oracle table edit
This commit is contained in:
@ -1,24 +1,28 @@
|
||||
package ai.chat2db.plugin.oracle;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ai.chat2db.plugin.oracle.builder.OracleSqlBuilder;
|
||||
import ai.chat2db.plugin.oracle.type.OracleColumnTypeEnum;
|
||||
import ai.chat2db.plugin.oracle.type.OracleIndexTypeEnum;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
||||
import ai.chat2db.spi.model.Function;
|
||||
import ai.chat2db.spi.model.Procedure;
|
||||
import ai.chat2db.spi.model.Table;
|
||||
import ai.chat2db.spi.model.Trigger;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
@Override
|
||||
public String tableDDL(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = "select dbms_metadata.get_ddl('TABLE','" + tableName + "') as sql from dual,"
|
||||
+ "user_tables where table_name = '" + tableName + "'";
|
||||
+ "user_tables where table_name = '" + tableName + "'";
|
||||
return SQLExecutor.getInstance().executeSql(connection, sql, resultSet -> {
|
||||
try {
|
||||
if (resultSet.next()) {
|
||||
@ -32,15 +36,69 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
});
|
||||
}
|
||||
|
||||
private static String SELECT_TABLE_SQL = "SELECT A.OWNER, A.TABLE_NAME, B.COMMENTS " +
|
||||
"FROM ALL_TABLES A LEFT JOIN ALL_TAB_COMMENTS B ON A.OWNER = B.OWNER AND A.TABLE_NAME = B.TABLE_NAME\n" +
|
||||
"where A.OWNER = '%s' ";
|
||||
|
||||
@Override
|
||||
public List<Table> tables(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = String.format(SELECT_TABLE_SQL, schemaName);
|
||||
if(StringUtils.isNotBlank(tableName)){
|
||||
sql = sql + " and A.TABLE_NAME = '" + tableName + "'";
|
||||
}
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
List<Table> tables = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
Table table = new Table();
|
||||
table.setDatabaseName(databaseName);
|
||||
table.setSchemaName(schemaName);
|
||||
table.setName(resultSet.getString("TABLE_NAME"));
|
||||
table.setComment(resultSet.getString("COMMENTS"));
|
||||
tables.add(table);
|
||||
}
|
||||
return tables;
|
||||
});
|
||||
}
|
||||
|
||||
private static String SELECT_TAB_COLS = "SELECT atc.column_id , atc.column_name as COLUMN_NAME, atc.data_type as DATA_TYPE , atc.data_length as DATA_LENGTH , atc.data_type_mod , atc.nullable , atc.data_default , acc.comments , atc.DATA_PRECISION , atc.DATA_SCALE , atc.CHAR_USED FROM all_tab_columns atc, all_col_comments acc WHERE atc.owner = acc.owner AND atc.table_name = acc.table_name AND atc.column_name = acc.column_name AND atc.owner = '%s' AND atc.table_name = '%s' order by atc.column_id";
|
||||
@Override
|
||||
public List<TableColumn> columns(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = String.format(SELECT_TAB_COLS, schemaName, tableName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
List<TableColumn> tableColumns = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
TableColumn tableColumn = new TableColumn();
|
||||
tableColumn.setTableName(tableName);
|
||||
tableColumn.setSchemaName(schemaName);
|
||||
tableColumn.setName(resultSet.getString("COLUMN_NAME"));
|
||||
tableColumn.setColumnType(resultSet.getString("DATA_TYPE"));
|
||||
tableColumn.setColumnSize(resultSet.getInt("DATA_LENGTH"));
|
||||
tableColumn.setDefaultValue(resultSet.getString("DATA_DEFAULT"));
|
||||
tableColumn.setComment(resultSet.getString("COMMENTS"));
|
||||
tableColumn.setNullable("Y".equalsIgnoreCase(resultSet.getString("NULLABLE"))?1:0);
|
||||
tableColumn.setOrdinalPosition(resultSet.getInt("COLUMN_ID"));
|
||||
tableColumn.setDecimalDigits(resultSet.getInt("DATA_SCALE"));
|
||||
String charUsed = resultSet.getString("CHAR_USED");
|
||||
if("B".equalsIgnoreCase(charUsed)){
|
||||
tableColumn.setUnit("BYTE");
|
||||
}else if("C".equalsIgnoreCase(charUsed)){
|
||||
tableColumn.setUnit("CHAR");
|
||||
}
|
||||
tableColumns.add(tableColumn);
|
||||
}
|
||||
return tableColumns;
|
||||
});
|
||||
}
|
||||
|
||||
private static String ROUTINES_SQL
|
||||
= "SELECT LINE, TEXT "
|
||||
+ "FROM ALL_SOURCE "
|
||||
+ "WHERE TYPE = '%s' AND NAME = '%s' "
|
||||
+ "ORDER BY LINE";
|
||||
= "SELECT LINE, TEXT "
|
||||
+ "FROM ALL_SOURCE "
|
||||
+ "WHERE TYPE = '%s' AND NAME = '%s' "
|
||||
+ "ORDER BY LINE";
|
||||
|
||||
@Override
|
||||
public Function function(Connection connection, @NotEmpty String databaseName, String schemaName,
|
||||
String functionName) {
|
||||
String functionName) {
|
||||
|
||||
String sql = String.format(ROUTINES_SQL, "FUNCTION", functionName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
@ -60,28 +118,101 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
}
|
||||
|
||||
private static String TRIGGER_SQL_LIST
|
||||
= "SELECT TRIGGER_NAME "
|
||||
+ "FROM ALL_TRIGGERS WHERE OWNER = '%s'";
|
||||
= "SELECT TRIGGER_NAME "
|
||||
+ "FROM ALL_TRIGGERS WHERE OWNER = '%s'";
|
||||
|
||||
private static String SELECT_PK_SQL = "select acc.CONSTRAINT_NAME from all_cons_columns acc, all_constraints ac where acc.constraint_name = ac.constraint_name and acc.owner = ac.owner and acc.owner = '%s' and ac.constraint_type = 'P' and ac.table_name = '%s' ";
|
||||
|
||||
private static String SELECT_TABLE_INDEX = "SELECT ai.index_name AS Key_name, aic.column_name AS Column_name, ai.index_type AS Index_type, ai.uniqueness AS Unique_name, aic.COLUMN_POSITION as Seq_in_index, aic.descend AS Collation, ex.COLUMN_EXPRESSION as COLUMN_EXPRESSION FROM all_ind_columns aic JOIN all_indexes ai ON aic.table_owner = ai.table_owner and aic.table_name = ai.table_name and aic.index_name = ai.index_name LEFT JOIN ALL_IND_EXPRESSIONS ex ON aic.table_owner = ex.table_owner and aic.table_name = ex.table_name and aic.index_name = ex.index_name where ai.table_owner = '%s' AND ai.table_name = '%s' ";
|
||||
|
||||
|
||||
@Override
|
||||
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String pkSql = String.format(SELECT_PK_SQL, schemaName, tableName);
|
||||
Set<String> pkSet = new HashSet<>();
|
||||
SQLExecutor.getInstance().execute(connection, pkSql, resultSet -> {
|
||||
while (resultSet.next()) {
|
||||
pkSet.add(resultSet.getString("CONSTRAINT_NAME"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
String sql = String.format(SELECT_TABLE_INDEX, schemaName, tableName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
LinkedHashMap<String, TableIndex> map = new LinkedHashMap();
|
||||
while (resultSet.next()) {
|
||||
String keyName = resultSet.getString("Key_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("Unique_name")));
|
||||
index.setType(resultSet.getString("Index_type"));
|
||||
List<TableIndexColumn> tableIndexColumns = new ArrayList<>();
|
||||
tableIndexColumns.add(getTableIndexColumn(resultSet));
|
||||
index.setColumnList(tableIndexColumns);
|
||||
if (index.getUnique()) {
|
||||
index.setType(OracleIndexTypeEnum.UNIQUE.getName());
|
||||
} else if ("NORMAL".equalsIgnoreCase(index.getType())) {
|
||||
index.setType(OracleIndexTypeEnum.NORMAL.getName());
|
||||
} else if ("BITMAP".equalsIgnoreCase(index.getType())) {
|
||||
index.setType(OracleIndexTypeEnum.BITMAP.getName());
|
||||
} else if(StringUtils.isNotBlank(index.getType()) && index.getType().toUpperCase().contains("NORMAL")){
|
||||
index.setType(OracleIndexTypeEnum.NORMAL.getName());
|
||||
}
|
||||
if(pkSet.contains(keyName)){
|
||||
index.setType(OracleIndexTypeEnum.PRIMARY_KEY.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"));
|
||||
String expression = resultSet.getString("COLUMN_EXPRESSION");
|
||||
if(!StringUtils.isBlank(expression)){
|
||||
tableIndexColumn.setColumnName(expression.replace("\"",""));
|
||||
}
|
||||
tableIndexColumn.setOrdinalPosition(resultSet.getShort("Seq_in_index"));
|
||||
tableIndexColumn.setCollation(resultSet.getString("Collation"));
|
||||
tableIndexColumn.setAscOrDesc(resultSet.getString("Collation"));
|
||||
return tableIndexColumn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Trigger> triggers(Connection connection, String databaseName, String schemaName) {
|
||||
List<Trigger> triggers = new ArrayList<>();
|
||||
return SQLExecutor.getInstance().execute(connection, String.format(TRIGGER_SQL_LIST, schemaName),
|
||||
resultSet -> {
|
||||
while (resultSet.next()) {
|
||||
Trigger trigger = new Trigger();
|
||||
trigger.setTriggerName(resultSet.getString("TRIGGER_NAME"));
|
||||
trigger.setSchemaName(schemaName);
|
||||
trigger.setDatabaseName(databaseName);
|
||||
triggers.add(trigger);
|
||||
}
|
||||
return triggers;
|
||||
});
|
||||
resultSet -> {
|
||||
while (resultSet.next()) {
|
||||
Trigger trigger = new Trigger();
|
||||
trigger.setTriggerName(resultSet.getString("TRIGGER_NAME"));
|
||||
trigger.setSchemaName(schemaName);
|
||||
trigger.setDatabaseName(databaseName);
|
||||
triggers.add(trigger);
|
||||
}
|
||||
return triggers;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger trigger(Connection connection, @NotEmpty String databaseName, String schemaName,
|
||||
String triggerName) {
|
||||
String triggerName) {
|
||||
|
||||
String sql = String.format(ROUTINES_SQL, "TRIGGER", triggerName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
@ -100,7 +231,7 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
|
||||
@Override
|
||||
public Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName,
|
||||
String procedureName) {
|
||||
String procedureName) {
|
||||
String sql = String.format(ROUTINES_SQL, "PROCEDURE", procedureName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -117,7 +248,7 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
}
|
||||
|
||||
private static String VIEW_SQL
|
||||
= "SELECT VIEW_NAME, TEXT FROM ALL_VIEWS WHERE OWNER = '%s' AND VIEW_NAME = '%s'";
|
||||
= "SELECT VIEW_NAME, TEXT FROM ALL_VIEWS WHERE OWNER = '%s' AND VIEW_NAME = '%s'";
|
||||
|
||||
@Override
|
||||
public Table view(Connection connection, String databaseName, String schemaName, String viewName) {
|
||||
@ -133,4 +264,18 @@ public class OracleMetaData extends DefaultMetaService implements MetaData {
|
||||
return table;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlBuilder getSqlBuilder() {
|
||||
return new OracleSqlBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableMeta getTableMeta(String databaseName, String schemaName, String tableName) {
|
||||
return TableMeta.builder()
|
||||
.columnTypes(OracleColumnTypeEnum.getTypes())
|
||||
.charsets(Lists.newArrayList())
|
||||
.collations(Lists.newArrayList())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
package ai.chat2db.plugin.oracle.builder;
|
||||
|
||||
import ai.chat2db.plugin.oracle.type.OracleColumnTypeEnum;
|
||||
import ai.chat2db.plugin.oracle.type.OracleIndexTypeEnum;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
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 OracleSqlBuilder implements SqlBuilder {
|
||||
@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;
|
||||
}
|
||||
OracleColumnTypeEnum typeEnum = OracleColumnTypeEnum.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;
|
||||
}
|
||||
OracleIndexTypeEnum oracleColumnTypeEnum = OracleIndexTypeEnum.getByType(tableIndex.getType());
|
||||
script.append("\n").append("").append(oracleColumnTypeEnum.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("").append("\"").append(oldTable.getName()).append("\"");
|
||||
script.append(" ").append("RENAME TO ").append("\"").append(newTable.getName()).append("\"").append(";");
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(oldTable.getComment(), newTable.getComment())) {
|
||||
script.append("\n").append(buildTableComment(newTable)).append(";");
|
||||
}
|
||||
|
||||
|
||||
// append modify column
|
||||
for (TableColumn tableColumn : newTable.getColumnList()) {
|
||||
if (StringUtils.isNotBlank(tableColumn.getEditStatus())) {
|
||||
OracleColumnTypeEnum typeEnum = OracleColumnTypeEnum.getByType(tableColumn.getColumnType());
|
||||
script.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
// append modify index
|
||||
for (TableIndex tableIndex : newTable.getIndexList()) {
|
||||
if (StringUtils.isNotBlank(tableIndex.getEditStatus()) && StringUtils.isNotBlank(tableIndex.getType())) {
|
||||
OracleIndexTypeEnum mysqlIndexTypeEnum = OracleIndexTypeEnum.getByType(tableIndex.getType());
|
||||
script.append("\t").append(mysqlIndexTypeEnum.buildModifyIndex(tableIndex)).append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||
script.append(";");
|
||||
|
||||
return script.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,252 @@
|
||||
package ai.chat2db.plugin.oracle.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 OracleColumnTypeEnum implements ColumnBuilder {
|
||||
//JSON("JSON", false, false, true, false, false, false, true, false, false, false)
|
||||
|
||||
BFILE("BFILE", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
BINARY_DOUBLE("BINARY_DOUBLE", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
|
||||
BINARY_FLOAT("BINARY_FLOAT", 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_PRECISION("DOUBLE PRECISION", 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),
|
||||
|
||||
LONG("LONG", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
LONG_RAW("LONG RAW", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
|
||||
LONG_VARCHAR("LONG VARCHAR", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
NATIONAL_CHAR("NATIONAL CHAR", true, false, true, false, false, false, true, true, false, true),
|
||||
|
||||
|
||||
NATIONAL_CHAR_VARYING("NATIONAL CHAR VARYING", true, false, true, false, false, false, true, true, false, true),
|
||||
|
||||
|
||||
NATIONAL_CHARACTER("NATIONAL CHARACTER", true, false, true, false, false, false, true, true, false, true),
|
||||
|
||||
|
||||
NATIONAL_CHARACTER_VARYING("NATIONAL CHARACTER VARYING", true, false, true, false, false, false, true, true, false, true),
|
||||
|
||||
NCHAR("NCHAR", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
NCHAR_VARYING("NCHAR VARYING", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
NCLOB("NCLOB", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
NUMBER("NUMBER", true, true, true, false, false, false, true, true, false, false),
|
||||
|
||||
|
||||
NVARCHAR2("NVARCHAR2", true, false, true, false, false, false, true, true, false, true),
|
||||
|
||||
RAW("RAW", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
REAL("REAL", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
ROWID("ROWID", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
|
||||
SMALLINT("SMALLINT", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
TIMESTAMP("TIMESTAMP", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
TIMESTAMP_WITH_LOCAL_TIME_ZONE("TIMESTAMP WITH LOCAL TIME ZONE", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
|
||||
TIMESTAMP_WITH_TIME_ZONE("TIMESTAMP WITH TIME ZONE", true, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
UROWID("UROWID", true, 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 OracleColumnTypeEnum getByType(String dataType) {
|
||||
return COLUMN_TYPE_MAP.get(dataType.toUpperCase());
|
||||
}
|
||||
|
||||
private static Map<String, OracleColumnTypeEnum> COLUMN_TYPE_MAP = Maps.newHashMap();
|
||||
|
||||
static {
|
||||
for (OracleColumnTypeEnum value : OracleColumnTypeEnum.values()) {
|
||||
COLUMN_TYPE_MAP.put(value.getColumnType().getTypeName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
public ColumnType getColumnType() {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
|
||||
OracleColumnTypeEnum(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) {
|
||||
OracleColumnTypeEnum 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,OracleColumnTypeEnum type) {
|
||||
if(!type.getColumnType().isSupportNullable()){
|
||||
return "";
|
||||
}
|
||||
if (column.getNullable()!=null && 1==column.getNullable()) {
|
||||
return "NULL";
|
||||
} else {
|
||||
return "NOT NULL";
|
||||
}
|
||||
}
|
||||
|
||||
private String buildDefaultValue(TableColumn column, OracleColumnTypeEnum 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, OracleColumnTypeEnum type) {
|
||||
String columnType = type.columnType.getTypeName();
|
||||
if (Arrays.asList(CHAR, CHAR_VARYING, CHARACTER, CHARACTER_VARYING,
|
||||
NVARCHAR2, VARCHAR, VARCHAR2,NATIONAL_CHAR,
|
||||
NATIONAL_CHAR_VARYING,NATIONAL_CHARACTER,
|
||||
NATIONAL_CHARACTER_VARYING,NCHAR,NCHAR_VARYING).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, UROWID,RAW,TIMESTAMP).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,TIMESTAMP_WITH_LOCAL_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();
|
||||
}
|
||||
|
||||
|
||||
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("").append("\"").append(tableColumn.getTableName()).append("\"");
|
||||
script.append(" ").append("DROP COLUMN ").append("\"").append(tableColumn.getName()).append("\"").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("").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("").append("\"").append(tableColumn.getTableName()).append("\"");
|
||||
script.append(" ").append("MODIFY (").append(buildCreateColumnSql(tableColumn)).append("); \n" );
|
||||
|
||||
if (!StringUtils.equalsIgnoreCase(tableColumn.getOldName(), tableColumn.getName())) {
|
||||
script.append("ALTER TABLE "). append("\"").append(tableColumn.getSchemaName()).append("\"").append("").append("\"").append(tableColumn.getTableName()).append("\"");
|
||||
script.append(" ").append("RENAME COLUMN ").append("\"").append(tableColumn.getOldName()).append("\"").append(" TO ").append("\"").append(tableColumn.getName()).append("\"").append(";");
|
||||
|
||||
}
|
||||
return script.toString();
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public static List<ColumnType> getTypes(){
|
||||
return Arrays.stream(OracleColumnTypeEnum.values()).map(columnTypeEnum ->
|
||||
columnTypeEnum.getColumnType()
|
||||
).toList();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package ai.chat2db.plugin.oracle.type;
|
||||
|
||||
import ai.chat2db.spi.enums.EditStatus;
|
||||
import ai.chat2db.spi.model.TableIndex;
|
||||
import ai.chat2db.spi.model.TableIndexColumn;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public enum OracleIndexTypeEnum {
|
||||
|
||||
PRIMARY_KEY("Primary", "PRIMARY KEY"),
|
||||
|
||||
NORMAL("Normal", "INDEX"),
|
||||
|
||||
UNIQUE("Unique", "UNIQUE INDEX"),
|
||||
|
||||
BITMAP("BITMAP", "BITMAP INDEX");
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
private String keyword;
|
||||
|
||||
OracleIndexTypeEnum(String name, String keyword) {
|
||||
this.name = name;
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
|
||||
public static OracleIndexTypeEnum getByType(String type) {
|
||||
for (OracleIndexTypeEnum value : OracleIndexTypeEnum.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("CREATE PRIMARY KEY ");
|
||||
} else if (UNIQUE.equals(this)) {
|
||||
script.append("CREATE UNIQUE INDEX ");
|
||||
} else {
|
||||
script.append("CREATE INDEX ");
|
||||
}
|
||||
script.append(buildIndexName(tableIndex)).append(" ON \"").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())){
|
||||
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 (OracleIndexTypeEnum.PRIMARY_KEY.getName().equals(tableIndex.getType())) {
|
||||
return StringUtils.join("DROP PRIMARY KEY");
|
||||
}
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append("DROP INDEX ");
|
||||
script.append(buildIndexName(tableIndex));
|
||||
|
||||
return script.toString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user