diff --git a/chat2db-server/chat2db-plugins/chat2db-mariadb/pom.xml b/chat2db-server/chat2db-plugins/chat2db-mariadb/pom.xml index a73c0c59..c34a9f66 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mariadb/pom.xml +++ b/chat2db-server/chat2db-plugins/chat2db-mariadb/pom.xml @@ -15,6 +15,11 @@ ai.chat2db chat2db-spi + + ai.chat2db + chat2db-mysql + 2.0.0-SNAPSHOT + chat2db-mariadb diff --git a/chat2db-server/chat2db-plugins/chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/MariaDBMetaData.java b/chat2db-server/chat2db-plugins/chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/MariaDBMetaData.java index b2c48805..ccfca079 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/MariaDBMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-mariadb/src/main/java/ai/chat2db/plugin/mariadb/MariaDBMetaData.java @@ -4,6 +4,7 @@ import java.sql.Connection; import java.util.ArrayList; import java.util.List; +import ai.chat2db.plugin.mysql.MysqlMetaData; import ai.chat2db.spi.MetaData; import ai.chat2db.spi.jdbc.DefaultMetaService; import ai.chat2db.spi.model.Function; @@ -13,109 +14,109 @@ import ai.chat2db.spi.model.Trigger; import ai.chat2db.spi.sql.SQLExecutor; import jakarta.validation.constraints.NotEmpty; -public class MariaDBMetaData extends DefaultMetaService implements MetaData { +public class MariaDBMetaData extends MysqlMetaData implements MetaData { - private static String ROUTINES_SQL - = - "SELECT SPECIFIC_NAME, ROUTINE_COMMENT, ROUTINE_DEFINITION FROM information_schema.routines WHERE " - + "routine_type = '%s' AND ROUTINE_SCHEMA ='%s' AND " - + "routine_name = '%s';"; - - @Override - public Function function(Connection connection, @NotEmpty String databaseName, String schemaName, - String functionName) { - - String sql = String.format(ROUTINES_SQL, "FUNCTION", databaseName, functionName); - return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { - Function function = new Function(); - function.setDatabaseName(databaseName); - function.setSchemaName(schemaName); - function.setFunctionName(functionName); - if (resultSet.next()) { - function.setSpecificName(resultSet.getString("SPECIFIC_NAME")); - function.setRemarks(resultSet.getString("ROUTINE_COMMENT")); - function.setFunctionBody(resultSet.getString("ROUTINE_DEFINITION")); - } - return function; - }); - - } - - private static String TRIGGER_SQL - = "SELECT TRIGGER_NAME,EVENT_MANIPULATION, ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS where " - + "TRIGGER_SCHEMA = '%s' AND TRIGGER_NAME = '%s';"; - - private static String TRIGGER_SQL_LIST - = "SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS where TRIGGER_SCHEMA = '%s';"; - - @Override - public List triggers(Connection connection, String databaseName, String schemaName) { - List triggers = new ArrayList<>(); - String sql = String.format(TRIGGER_SQL_LIST, databaseName); - return SQLExecutor.getInstance().execute(connection, sql, 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 sql = String.format(TRIGGER_SQL, databaseName, triggerName); - return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { - Trigger trigger = new Trigger(); - trigger.setDatabaseName(databaseName); - trigger.setSchemaName(schemaName); - trigger.setTriggerName(triggerName); - if (resultSet.next()) { - trigger.setTriggerBody(resultSet.getString("ACTION_STATEMENT")); - } - return trigger; - }); - } - - @Override - public Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName, - String procedureName) { - String sql = String.format(ROUTINES_SQL, "PROCEDURE", databaseName, procedureName); - return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { - Procedure procedure = new Procedure(); - procedure.setDatabaseName(databaseName); - procedure.setSchemaName(schemaName); - procedure.setProcedureName(procedureName); - if (resultSet.next()) { - procedure.setSpecificName(resultSet.getString("SPECIFIC_NAME")); - procedure.setRemarks(resultSet.getString("ROUTINE_COMMENT")); - procedure.setProcedureBody(resultSet.getString("ROUTINE_DEFINITION")); - } - return procedure; - }); - } - - private static String VIEW_SQL - = "SELECT TABLE_SCHEMA AS DatabaseName, TABLE_NAME AS ViewName, VIEW_DEFINITION AS definition, CHECK_OPTION, " - + "IS_UPDATABLE FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s';"; - - @Override - public Table view(Connection connection, String databaseName, String schemaName, String viewName) { - String sql = String.format(VIEW_SQL, databaseName, viewName); - return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { - Table table = new Table(); - table.setDatabaseName(databaseName); - table.setSchemaName(schemaName); - table.setName(viewName); - if (resultSet.next()) { - table.setDdl(resultSet.getString("definition")); - } - return table; - }); - } +// private static String ROUTINES_SQL +// = +// "SELECT SPECIFIC_NAME, ROUTINE_COMMENT, ROUTINE_DEFINITION FROM information_schema.routines WHERE " +// + "routine_type = '%s' AND ROUTINE_SCHEMA ='%s' AND " +// + "routine_name = '%s';"; +// +// @Override +// public Function function(Connection connection, @NotEmpty String databaseName, String schemaName, +// String functionName) { +// +// String sql = String.format(ROUTINES_SQL, "FUNCTION", databaseName, functionName); +// return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { +// Function function = new Function(); +// function.setDatabaseName(databaseName); +// function.setSchemaName(schemaName); +// function.setFunctionName(functionName); +// if (resultSet.next()) { +// function.setSpecificName(resultSet.getString("SPECIFIC_NAME")); +// function.setRemarks(resultSet.getString("ROUTINE_COMMENT")); +// function.setFunctionBody(resultSet.getString("ROUTINE_DEFINITION")); +// } +// return function; +// }); +// +// } +// +// private static String TRIGGER_SQL +// = "SELECT TRIGGER_NAME,EVENT_MANIPULATION, ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS where " +// + "TRIGGER_SCHEMA = '%s' AND TRIGGER_NAME = '%s';"; +// +// private static String TRIGGER_SQL_LIST +// = "SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS where TRIGGER_SCHEMA = '%s';"; +// +// @Override +// public List triggers(Connection connection, String databaseName, String schemaName) { +// List triggers = new ArrayList<>(); +// String sql = String.format(TRIGGER_SQL_LIST, databaseName); +// return SQLExecutor.getInstance().execute(connection, sql, 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 sql = String.format(TRIGGER_SQL, databaseName, triggerName); +// return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { +// Trigger trigger = new Trigger(); +// trigger.setDatabaseName(databaseName); +// trigger.setSchemaName(schemaName); +// trigger.setTriggerName(triggerName); +// if (resultSet.next()) { +// trigger.setTriggerBody(resultSet.getString("ACTION_STATEMENT")); +// } +// return trigger; +// }); +// } +// +// @Override +// public Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName, +// String procedureName) { +// String sql = String.format(ROUTINES_SQL, "PROCEDURE", databaseName, procedureName); +// return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { +// Procedure procedure = new Procedure(); +// procedure.setDatabaseName(databaseName); +// procedure.setSchemaName(schemaName); +// procedure.setProcedureName(procedureName); +// if (resultSet.next()) { +// procedure.setSpecificName(resultSet.getString("SPECIFIC_NAME")); +// procedure.setRemarks(resultSet.getString("ROUTINE_COMMENT")); +// procedure.setProcedureBody(resultSet.getString("ROUTINE_DEFINITION")); +// } +// return procedure; +// }); +// } +// +// private static String VIEW_SQL +// = "SELECT TABLE_SCHEMA AS DatabaseName, TABLE_NAME AS ViewName, VIEW_DEFINITION AS definition, CHECK_OPTION, " +// + "IS_UPDATABLE FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s';"; +// +// @Override +// public Table view(Connection connection, String databaseName, String schemaName, String viewName) { +// String sql = String.format(VIEW_SQL, databaseName, viewName); +// return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { +// Table table = new Table(); +// table.setDatabaseName(databaseName); +// table.setSchemaName(schemaName); +// table.setName(viewName); +// if (resultSet.next()) { +// table.setDdl(resultSet.getString("definition")); +// } +// return table; +// }); +// } } diff --git a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlMetaData.java b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlMetaData.java index 35e46995..a7c39c74 100644 --- a/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-mysql/src/main/java/ai/chat2db/plugin/mysql/MysqlMetaData.java @@ -125,7 +125,7 @@ public class MysqlMetaData extends DefaultMetaService implements MetaData { @Override public List columns(Connection connection, String databaseName, String schemaName, String tableName) { - String sql = String.format(SELECT_TABLE_COLUMNS, databaseName, tableName); + String sql = String.format(SELECT_TABLE_COLUMNS, databaseName, tableName); List tableColumns = new ArrayList<>(); return SQLExecutor.getInstance().execute(connection, sql, resultSet -> { while (resultSet.next()) { @@ -146,20 +146,20 @@ public class MysqlMetaData extends DefaultMetaService implements MetaData { column.setDecimalDigits(resultSet.getInt("NUMERIC_SCALE")); column.setCharSetName(resultSet.getString("CHARACTER_SET_NAME")); column.setCollationName(resultSet.getString("COLLATION_NAME")); - setColumnSize(column,resultSet.getString("COLUMN_TYPE")); + setColumnSize(column, resultSet.getString("COLUMN_TYPE")); tableColumns.add(column); } return tableColumns; }); } - private void setColumnSize(TableColumn column,String columnType){ + private void setColumnSize(TableColumn column, String columnType) { try { if (columnType.contains("(")) { String size = columnType.substring(columnType.indexOf("(") + 1, columnType.indexOf(")")); - if("SET".equalsIgnoreCase(column.getColumnType())|| "ENUM".equalsIgnoreCase(column.getColumnType())){ + if ("SET".equalsIgnoreCase(column.getColumnType()) || "ENUM".equalsIgnoreCase(column.getColumnType())) { column.setValue(size); - }else { + } else { if (size.contains(",")) { String[] sizes = size.split(","); if (StringUtils.isNotBlank(sizes[0])) { @@ -173,12 +173,11 @@ public class MysqlMetaData extends DefaultMetaService implements MetaData { } } } - }catch (Exception e){ + } catch (Exception e) { } } - private static String VIEW_SQL = "SELECT TABLE_SCHEMA AS DatabaseName, TABLE_NAME AS ViewName, VIEW_DEFINITION AS definition, CHECK_OPTION, " + "IS_UPDATABLE FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s';"; @@ -271,4 +270,9 @@ public class MysqlMetaData extends DefaultMetaService implements MetaData { .collations(MysqlCollationEnum.getCollations()) .build(); } + + @Override + public String getMetaDataName(String... names) { + return Arrays.stream(names).map(name -> "`" + name + "`").collect(Collectors.joining(".")); + } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/OracleMetaData.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/OracleMetaData.java index 7204d0d8..b9ffa432 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/OracleMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/OracleMetaData.java @@ -281,4 +281,9 @@ public class OracleMetaData extends DefaultMetaService implements MetaData { .collations(Lists.newArrayList()) .build(); } + + @Override + public String getMetaDataName(String... names) { + return Arrays.stream(names).map(name -> "\"" + name + "\"").collect(Collectors.joining(".")); + } } diff --git a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/builder/OracleSqlBuilder.java b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/builder/OracleSqlBuilder.java index 2a566415..1a7eb589 100644 --- a/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/builder/OracleSqlBuilder.java +++ b/chat2db-server/chat2db-plugins/chat2db-oracle/src/main/java/ai/chat2db/plugin/oracle/builder/OracleSqlBuilder.java @@ -79,6 +79,9 @@ public class OracleSqlBuilder implements SqlBuilder { if (StringUtils.isNotBlank(tableColumn.getEditStatus())) { OracleColumnTypeEnum typeEnum = OracleColumnTypeEnum.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"); + } } } diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlite/src/main/java/ai/chat2db/plugin/sqlite/SqliteMetaData.java b/chat2db-server/chat2db-plugins/chat2db-sqlite/src/main/java/ai/chat2db/plugin/sqlite/SqliteMetaData.java index 872e63fa..ccda182a 100644 --- a/chat2db-server/chat2db-plugins/chat2db-sqlite/src/main/java/ai/chat2db/plugin/sqlite/SqliteMetaData.java +++ b/chat2db-server/chat2db-plugins/chat2db-sqlite/src/main/java/ai/chat2db/plugin/sqlite/SqliteMetaData.java @@ -2,7 +2,9 @@ package ai.chat2db.plugin.sqlite; import java.sql.Connection; import java.sql.SQLException; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import ai.chat2db.spi.MetaData; import ai.chat2db.spi.jdbc.DefaultMetaService; @@ -35,4 +37,9 @@ public class SqliteMetaData extends DefaultMetaService implements MetaData { public List schemas(Connection connection,String databaseName) { return Lists.newArrayList(); } + + @Override + public String getMetaDataName(String... names) { + return Arrays.stream(names).collect(Collectors.joining(".")); + } } diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlserver/pom.xml b/chat2db-server/chat2db-plugins/chat2db-sqlserver/pom.xml index 4f9b8eda..d040a7fe 100644 --- a/chat2db-server/chat2db-plugins/chat2db-sqlserver/pom.xml +++ b/chat2db-server/chat2db-plugins/chat2db-sqlserver/pom.xml @@ -17,6 +17,12 @@ ai.chat2db chat2db-spi + + com.microsoft.sqlserver + mssql-jdbc + 11.2.1.jre17 + test + \ No newline at end of file diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/builder/SqlServerSqlBuilder.java b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/builder/SqlServerSqlBuilder.java new file mode 100644 index 00000000..5101f8d0 --- /dev/null +++ b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/builder/SqlServerSqlBuilder.java @@ -0,0 +1,124 @@ +package ai.chat2db.plugin.sqlserver.builder; + +import ai.chat2db.plugin.sqlserver.type.SqlServerColumnTypeEnum; +import ai.chat2db.plugin.sqlserver.type.SqlServerIndexTypeEnum; +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 SqlServerSqlBuilder 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; + } + SqlServerColumnTypeEnum typeEnum = SqlServerColumnTypeEnum.getByType(column.getColumnType()); + script.append("\t").append(typeEnum.buildCreateColumnSql(column)).append(",\n"); + } + + script = new StringBuilder(script.substring(0, script.length() - 2)); + script.append("\n)\ngo\n"); + + for (TableIndex tableIndex : table.getIndexList()) { + if (StringUtils.isBlank(tableIndex.getName()) || StringUtils.isBlank(tableIndex.getType())) { + continue; + } + SqlServerIndexTypeEnum sqlServerIndexTypeEnum = SqlServerIndexTypeEnum.getByType(tableIndex.getType()); + script.append("\n").append(sqlServerIndexTypeEnum.buildIndexScript(tableIndex)); + if (StringUtils.isNotBlank(tableIndex.getComment())) { + script.append("\n").append(buildIndexComment(tableIndex)); + } + } + + for (TableColumn column : table.getColumnList()) { + if (StringUtils.isBlank(column.getName()) || StringUtils.isBlank(column.getColumnType()) || StringUtils.isBlank(column.getComment())) { + continue; + } + script.append("\n").append(buildColumnComment(column)); + } + + if (StringUtils.isNotBlank(table.getComment())) { + script.append("\n").append(buildTableComment(table)); + } + + + return script.toString(); + } + + private static String INDEX_COMMENT_SCRIPT = "exec sp_addextendedproperty 'MS_Description','%s','SCHEMA','%s','TABLE','%s','INDEX','%s' \ngo"; + + + private String buildIndexComment(TableIndex tableIndex) { + return String.format(INDEX_COMMENT_SCRIPT, tableIndex.getComment(), tableIndex.getSchemaName(), tableIndex.getTableName(), tableIndex.getName()); + } + + private static String TABLE_COMMENT_SCRIPT = "exec sp_addextendedproperty 'MS_Description','%s','SCHEMA','%s','TABLE','%s' \ngo"; + + + private String buildTableComment(Table table) { + return String.format(TABLE_COMMENT_SCRIPT, table.getComment(), table.getSchemaName(), table.getName()); + } + + private static String COLUMN_COMMENT_SCRIPT = "exec sp_addextendedproperty 'MS_Description','%s','SCHEMA','%s','TABLE','%s','COLUMN','%s' \ngo"; + + private String buildColumnComment(TableColumn column) { + return String.format(COLUMN_COMMENT_SCRIPT, column.getComment(), column.getSchemaName(), column.getTableName(), column.getName()); + } + + @Override + public String buildModifyTaleSql(Table oldTable, Table newTable) { + StringBuilder script = new StringBuilder(); + + if (!StringUtils.equalsIgnoreCase(oldTable.getName(), newTable.getName())) { + script.append(buildRenameTable(oldTable, newTable)); + } + if (!StringUtils.equalsIgnoreCase(oldTable.getComment(), newTable.getComment())) { + if(oldTable.getComment() == null){ + script.append("\n").append(buildTableComment(newTable)); + }else { + script.append("\n").append(buildUpdateTableComment(newTable)); + } + } + + + // append modify column + for (TableColumn tableColumn : newTable.getColumnList()) { + if (StringUtils.isNotBlank(tableColumn.getEditStatus())) { + SqlServerColumnTypeEnum typeEnum = SqlServerColumnTypeEnum.getByType(tableColumn.getColumnType()); + script.append(typeEnum.buildModifyColumn(tableColumn)).append("\n"); + } + } + + // append modify index + for (TableIndex tableIndex : newTable.getIndexList()) { + if (StringUtils.isNotBlank(tableIndex.getEditStatus()) && StringUtils.isNotBlank(tableIndex.getType())) { + SqlServerIndexTypeEnum mysqlIndexTypeEnum = SqlServerIndexTypeEnum.getByType(tableIndex.getType()); + script.append("\t").append(mysqlIndexTypeEnum.buildModifyIndex(tableIndex)).append("\n"); + if (StringUtils.isNotBlank(tableIndex.getComment())) { + script.append("\n").append(buildIndexComment(tableIndex)).append("\ngo"); + } + } + } + + return script.toString(); + } + + + private static String UPDATE_TABLE_COMMENT_SCRIPT = "exec sp_updateextendedproperty 'MS_Description','%s','SCHEMA','%s','TABLE','%s' \ngo"; + private String buildUpdateTableComment(Table newTable) { + return String.format(UPDATE_TABLE_COMMENT_SCRIPT, newTable.getComment(), newTable.getSchemaName(), newTable.getName()); + } + + private static String RENAME_TABLE_SCRIPT = "exec sp_rename '%s','%s','OBJECT' \ngo"; + + private String buildRenameTable(Table oldTable, Table newTable) { + return String.format(RENAME_TABLE_SCRIPT, oldTable.getName(), newTable.getName()); + } +} diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/builder/item.json b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/builder/item.json deleted file mode 100644 index e69de29b..00000000 diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerColumnTypeEnum.java new file mode 100644 index 00000000..9aecd681 --- /dev/null +++ b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerColumnTypeEnum.java @@ -0,0 +1,337 @@ +package ai.chat2db.plugin.sqlserver.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 SqlServerColumnTypeEnum implements ColumnBuilder { + //JSON("JSON", false, false, true, false, false, false, true, false, false, false) + + BIGINT("BIGINT", false, false, true, false, false, false, true, true), + + BINARY("BINARY", false, false, true, false, false, false, true, true), + + BIT("BIT", false, false, true, false, false, false, true, true), + + CHAR("CHAR", true, false, true, false, false, true, true, true), + + DATE("DATE", false, false, true, false, false, false, true, true), + + DATETIME("DATETIME", false, false, true, false, false, false, true, true), + + DATETIME2("DATETIME2", true, false, true, false, false, false, true, true), + + + DATETIMEOFFSET("DATETIMEOFFSET", true, false, true, false, false, false, true, true), + + + DECIMAL("DECIMAL", true, true, true, false, false, false, true, true), + + + FLOAT("FLOAT", true, false, true, false, false, false, true, true), + + + GEOGRAPHY("GEOGRAPHY", false, false, true, false, false, false, true, true), + + GEOMETRY("GEOMETRY", false, false, true, false, false, false, true, true), + + HIERARCHYID("HIERARCHYID", false, false, true, false, false, false, true, true), + + IMAGE("IMAGE", false, false, true, false, false, false, true, true), + + INT("INT", false, false, true, false, false, false, true, true), + + + MONEY("MONEY", false, false, true, false, false, false, true, true), + + NCHAR("NCHAR", true, false, true, false, false, true, true, true), + + NTEXT("NTEXT", false, false, true, false, false, false, true, true), + + NUMERIC("NUMERIC", true, true, true, false, false, false, true, true), + + NVARCHAR("NVARCHAR", true, false, true, false, false, true, true, true), + + NVARCHAR_MAX("NVARCHAR(MAX)", false, false, true, false, false, true, true, true), + + + REAL("REAL", false, false, true, false, false, false, true, true), + + SMALLDATETIME("SMALLDATETIME", false, false, true, false, false, false, true, true), + + SMALLINT("SMALLINT", false, false, true, false, false, false, true, true), + + SMALLMONEY("SMALLMONEY", false, false, true, false, false, false, true, true), + + SQL_VARIANT("SQL_VARIANT", false, false, true, false, false, false, true, true), + + SYSNAME("SYSNAME", false, false, true, false, false, false, true, true), + + TEXT("TEXT", false, false, true, false, false, true, true, true), + + TIME("TIME", true, false, true, false, false, false, true, true), + + TIMESTAMP("TIMESTAMP", false, false, true, false, false, false, true, true), + + + TINYINT("TINYINT", false, false, true, false, false, false, true, true), + + UNIQUEIDENTIFIER("UNIQUEIDENTIFIER", false, false, true, false, false, false, true, true), + + + VARBINARY("VARBINARY", true, false, true, false, false, false, true, true), + + VARBINARY_MAX("VARBINARY(MAX)", false, false, true, false, false, false, true, true), + + VARCHAR("VARCHAR", true, false, true, false, false, true, true, true), + + VARCHAR_MAX("VARCHAR(MAX)", false, false, true, false, false, true, true, true), + + XML("XML", false, false, true, false, false, false, true, true), + + + ; + private ColumnType columnType; + + public static SqlServerColumnTypeEnum getByType(String dataType) { + return COLUMN_TYPE_MAP.get(dataType.toUpperCase()); + } + + private static Map COLUMN_TYPE_MAP = Maps.newHashMap(); + + static { + for (SqlServerColumnTypeEnum value : SqlServerColumnTypeEnum.values()) { + COLUMN_TYPE_MAP.put(value.getColumnType().getTypeName(), value); + } + } + + public ColumnType getColumnType() { + return columnType; + } + + + SqlServerColumnTypeEnum(String dataTypeName, boolean supportLength, boolean supportScale, boolean supportNullable, boolean supportAutoIncrement, boolean supportCharset, boolean supportCollation, boolean supportComments, boolean supportDefaultValue) { + this.columnType = new ColumnType(dataTypeName, supportLength, supportScale, supportNullable, supportAutoIncrement, supportCharset, supportCollation, supportComments, supportDefaultValue, false, false, false); + } + + @Override + public String buildCreateColumnSql(TableColumn column) { + SqlServerColumnTypeEnum type = this; + StringBuilder script = new StringBuilder(); + + script.append("[").append(column.getName()).append("]").append(" "); + + script.append(buildDataType(column, type)).append(" "); + + script.append(buildSparse(column, type)).append(" "); + + script.append(buildDefaultValue(column, type)).append(" "); + + script.append(buildNullable(column, type)).append(" "); + + script.append(buildCollation(column, type)).append(" "); + + return script.toString(); + } + + public String buildUpdateColumnSql(TableColumn column) { + SqlServerColumnTypeEnum type = this; + + StringBuilder script = new StringBuilder(); + + script.append("[").append(column.getName()).append("]").append(" "); + + script.append(buildDataType(column, type)).append(" "); + + script.append(buildNullable(column, type)).append(" \ngo\n"); + + if (StringUtils.isNotBlank(column.getDefaultValue()) && column.getOldColumn().getDefaultValue() != null && !StringUtils.equalsIgnoreCase(column.getDefaultValue(), column.getOldColumn().getDefaultValue())) { + script.append("ALTER TABLE ").append("[").append(column.getSchemaName()).append("].[").append(column.getTableName()).append("]"); + script.append(" ").append("DROP CONSTRAINT ").append("[").append(column.getDefaultConstraintName()).append("]"); + + script.append("ALTER TABLE ").append("[").append(column.getSchemaName()).append("].[").append(column.getTableName()).append("]"); + script.append(" ").append("ADD ").append(buildDefaultValue(column, type)).append(" for ").append(column.getName()).append(" \ngo\n"); + } + + if (StringUtils.isNotBlank(column.getDefaultValue()) && column.getOldColumn().getDefaultValue() == null) { + script.append("ALTER TABLE ").append("[").append(column.getSchemaName()).append("].[").append(column.getTableName()).append("]"); + script.append(" ").append("ADD ").append(buildDefaultValue(column, type)).append(" for ").append(column.getName()).append(" \ngo\n"); + } + + + if (column.getSparse() != null && column.getSparse()) { + script.append("ALTER TABLE ").append("[").append(column.getSchemaName()).append("].[").append(column.getTableName()).append("]"); + script.append(" ").append("ALTER COLUMN ").append("[").append(column.getName()).append("]").append(" add ").append("SPARSE").append(" \ngo\n"); + } + + if (StringUtils.isNotBlank(column.getCollationName())) { + script.append("ALTER TABLE ").append("[").append(column.getSchemaName()).append("].[").append(column.getTableName()).append("]"); + script.append(" ").append("ALTER COLUMN ").append("[").append(column.getName()).append("]").append(" ").append("COLLATE ").append(column.getCollationName()).append(" \ngo\n"); + } + return script.toString(); + } + + private String buildSparse(TableColumn column, SqlServerColumnTypeEnum type) { + if (Boolean.TRUE.equals(column.getSparse())) { + return "SPARSE"; + } else { + return ""; + } + } + + private String buildCollation(TableColumn column, SqlServerColumnTypeEnum type) { + if (!type.getColumnType().isSupportCollation() || StringUtils.isEmpty(column.getCollationName())) { + return ""; + } + return StringUtils.join("COLLATE ", column.getCollationName()); + } + + + private String buildNullable(TableColumn column, SqlServerColumnTypeEnum type) { + if (!type.getColumnType().isSupportNullable()) { + return ""; + } + if (column.getNullable() != null && 1 == column.getNullable()) { + return "NULL"; + } else { + return "NOT NULL"; + } + } + + private String buildDefaultValue(TableColumn column, SqlServerColumnTypeEnum 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, SqlServerColumnTypeEnum type) { + String columnType = type.columnType.getTypeName(); + if (Arrays.asList(CHAR, NCHAR, NVARCHAR, VARBINARY, VARCHAR).contains(type)) { + StringBuilder script = new StringBuilder(); + script.append(columnType); + if (column.getColumnSize() != null) { + script.append("(").append(column.getColumnSize()).append(")"); + } + + return script.toString(); + } + + if (Arrays.asList(DECIMAL, FLOAT, TIMESTAMP, TIME, DATETIME2, DATETIMEOFFSET, FLOAT, NUMERIC).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().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; + } + + private static String RENAME_COLUMN_SCRIPT = "exec sp_rename '%s.%s','%s','COLUMN' \ngo"; + + private String renameColumn(TableColumn tableColumn) { + return String.format(RENAME_COLUMN_SCRIPT, tableColumn.getTableName(), tableColumn.getOldName(), tableColumn.getName()); + } + + + @Override + public String buildModifyColumn(TableColumn tableColumn) { + + if (EditStatus.DELETE.name().equals(tableColumn.getEditStatus())) { + StringBuilder script = new StringBuilder(); + if (StringUtils.isNotBlank(tableColumn.getDefaultConstraintName())) { + script.append("ALTER TABLE ").append("[").append(tableColumn.getSchemaName()).append("].[").append(tableColumn.getTableName()).append("]"); + script.append(" ").append("DROP CONSTRAINT ").append("[").append(tableColumn.getDefaultConstraintName()).append("]"); + script.append("\ngo\n"); + } + script.append("ALTER TABLE ").append("[").append(tableColumn.getSchemaName()).append("].[").append(tableColumn.getTableName()).append("]"); + script.append(" ").append("DROP COLUMN ").append("[").append(tableColumn.getName()).append("]"); + script.append("\ngo\n"); + 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(" \ngo\n"); + return script.toString(); + } + if (EditStatus.MODIFY.name().equals(tableColumn.getEditStatus())) { + StringBuilder script = new StringBuilder(); + + if (!StringUtils.equalsIgnoreCase(tableColumn.getOldName(), tableColumn.getName())) { + script.append(renameColumn(tableColumn)); + script.append("\n"); + } + script.append("ALTER TABLE ").append("[").append(tableColumn.getSchemaName()).append("].[").append(tableColumn.getTableName()).append("]"); + script.append(" ").append("ALTER COLUMN ").append(buildUpdateColumnSql(tableColumn)).append(" \n"); + + if (StringUtils.isNotBlank(tableColumn.getComment())) { + script.append("\n").append(buildModifyColumnComment(tableColumn)); + } + + return script.toString(); + + } + return ""; + } + + private static String COLUMN_MODIFY_COMMENT_SCRIPT = "IF ((SELECT COUNT(*) FROM ::fn_listextendedproperty('MS_Description',\n" + + "'SCHEMA', N'%s',\n" + + "'TABLE', N'%s',\n" + + "'COLUMN', N'%s')) > 0)\n" + + " EXEC sp_updateextendedproperty\n" + + "'MS_Description', N'%s',\n" + + "'SCHEMA', N'%s',\n" + + "'TABLE', N'%s',\n" + + "'COLUMN', N'%s'\n" + + "ELSE\n" + + " EXEC sp_addextendedproperty\n" + + "'MS_Description', N'%s',\n" + + "'SCHEMA', N'%s',\n" + + "'TABLE', N'%s',\n" + + "'COLUMN', N'%s'\n go"; + + private String buildModifyColumnComment(TableColumn tableColumn) { + return String.format(COLUMN_MODIFY_COMMENT_SCRIPT, tableColumn.getSchemaName(), tableColumn.getTableName(), + tableColumn.getName(), tableColumn.getComment(), tableColumn.getSchemaName(), tableColumn.getTableName(), tableColumn.getName(), + tableColumn.getComment(), tableColumn.getSchemaName(), tableColumn.getTableName(), tableColumn.getName()); + } + + public static List getTypes() { + return Arrays.stream(SqlServerColumnTypeEnum.values()).map(columnTypeEnum -> + columnTypeEnum.getColumnType() + ).toList(); + } +} diff --git a/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerIndexTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerIndexTypeEnum.java new file mode 100644 index 00000000..74e8f93a --- /dev/null +++ b/chat2db-server/chat2db-plugins/chat2db-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/type/SqlServerIndexTypeEnum.java @@ -0,0 +1,119 @@ +package ai.chat2db.plugin.sqlserver.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 SqlServerIndexTypeEnum { + + PRIMARY_KEY("Primary", "PRIMARY KEY"), + +// NORMAL("Normal", "INDEX"), +// +// UNIQUE("Unique", "UNIQUE INDEX"), + + + UNIQUE_CLUSTERED("UNIQUE CLUSTERED", "UNIQUE CLUSTERED INDEX"), + + CLUSTERED("CLUSTERED", "CLUSTERED INDEX"), + + + NONCLUSTERED("NONCLUSTERED", "NONCLUSTERED INDEX"), + + UNIQUE_NONCLUSTERED("UNIQUE NONCLUSTERED", "UNIQUE NONCLUSTERED INDEX"), + + SPATIAL("SPATIAL", "SPATIAL INDEX"), + + XML("XML", "XML INDEX"); + + + public String getName() { + return name; + } + + private String name; + + + public String getKeyword() { + return keyword; + } + + private String keyword; + + SqlServerIndexTypeEnum(String name, String keyword) { + this.name = name; + this.keyword = keyword; + } + + + public static SqlServerIndexTypeEnum getByType(String type) { + for (SqlServerIndexTypeEnum value : SqlServerIndexTypeEnum.values()) { + if (value.name.equalsIgnoreCase(type)) { + return value; + } + } + return null; + } + + //ALTER TABLE [dbo].[Employees] ADD CONSTRAINT [PK__Employee__7AD04FF164ABF7C7] PRIMARY KEY CLUSTERED ([FirstName]) + + 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 CONSTRAINT ").append(buildIndexName(tableIndex)).append(" ").append(keyword).append(" ").append(buildIndexColumn(tableIndex)); + } else { + script.append("CREATE ").append(keyword).append(" "); + script.append(buildIndexName(tableIndex)).append("\n ON [").append(tableIndex.getSchemaName()).append("].[").append(tableIndex.getTableName()).append("] ").append(buildIndexColumn(tableIndex)); + } + script.append("\ngo"); + 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.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 (SqlServerIndexTypeEnum.PRIMARY_KEY.getName().equals(tableIndex.getType())) { + return StringUtils.join("ALTER TABLE [", tableIndex.getSchemaName(), "].[", tableIndex.getTableName(), "] DROP CONSTRAINT ", buildIndexName(tableIndex),"\ngo"); + } + StringBuilder script = new StringBuilder(); + script.append("DROP INDEX "); + script.append(buildIndexName(tableIndex)); + script.append(" ON [").append(tableIndex.getSchemaName()).append("].[").append(tableIndex.getTableName()).append("] \ngo"); + + return script.toString(); + } +} diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-api/src/main/java/ai/chat2db/server/domain/api/param/UpdateSelectResultParam.java b/chat2db-server/chat2db-server-domain/chat2db-server-domain-api/src/main/java/ai/chat2db/server/domain/api/param/UpdateSelectResultParam.java new file mode 100644 index 00000000..68725bc6 --- /dev/null +++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-api/src/main/java/ai/chat2db/server/domain/api/param/UpdateSelectResultParam.java @@ -0,0 +1,60 @@ +package ai.chat2db.server.domain.api.param; + +import ai.chat2db.spi.model.Header; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Data +public class UpdateSelectResultParam { + /** + * 控制台id + */ + @NotNull + private Long consoleId; + + /** + * 数据源id + */ + @NotNull + private Long dataSourceId; + + /** + * DB名称 + */ + private String databaseName; + + + /** + * schema名称 + */ + private String schemaName; + + + /** + * 展示头的列表 + */ + @NotEmpty + private List
headerList; + + + /** + * 修改后数据的列表 + */ + @NotEmpty + private List> dataList; + + /** + * 数据的列表 + */ + @NotEmpty + private List> oldDataList; + + /** + * 表名 + */ + @NotEmpty + private String tableName; +} diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java index d5ba425e..b4858c8c 100644 --- a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java +++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/TableServiceImpl.java @@ -86,6 +86,7 @@ public class TableServiceImpl implements TableService { @Override public ListResult buildSql(Table oldTable, Table newTable) { + initOldTable(oldTable, newTable); SqlBuilder sqlBuilder = Chat2DBContext.getSqlBuilder(); List sqls = new ArrayList<>(); if (oldTable == null) { @@ -96,6 +97,19 @@ public class TableServiceImpl implements TableService { return ListResult.of(sqls); } + private void initOldTable(Table oldTable, Table newTable) { + if (oldTable == null) { + return; + } + Map columnMap = oldTable.getColumnList().stream().collect(Collectors.toMap(TableColumn::getName, Function.identity())); + for (TableColumn newColumn : newTable.getColumnList()) { + TableColumn oldColumn = columnMap.get(newColumn.getName()); + if (oldColumn != null) { + newColumn.setOldColumn(oldColumn); + } + } + } + @Override public PageResult pageQuery(TablePageQueryParam param, TableSelector selector) { MetaData metaSchema = Chat2DBContext.getMetaData(); diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlController.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlController.java index 154a1938..2c7a0cc8 100644 --- a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlController.java +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlController.java @@ -4,6 +4,7 @@ import java.sql.Connection; import java.util.List; import ai.chat2db.server.domain.api.param.DlExecuteParam; +import ai.chat2db.server.domain.api.param.UpdateSelectResultParam; import ai.chat2db.server.domain.api.service.DlTemplateService; import ai.chat2db.server.tools.base.wrapper.result.DataResult; import ai.chat2db.server.tools.base.wrapper.result.ListResult; @@ -11,6 +12,7 @@ import ai.chat2db.server.web.api.aspect.ConnectionInfoAspect; import ai.chat2db.server.web.api.controller.rdb.converter.RdbWebConverter; import ai.chat2db.server.web.api.controller.rdb.request.DdlCountRequest; import ai.chat2db.server.web.api.controller.rdb.request.DmlRequest; +import ai.chat2db.server.web.api.controller.rdb.request.SelectResultUpdateRequest; import ai.chat2db.server.web.api.controller.rdb.vo.ExecuteResultVO; import ai.chat2db.spi.model.ExecuteResult; import ai.chat2db.spi.sql.Chat2DBContext; @@ -54,6 +56,20 @@ public class RdbDmlController { } + /** + * update 查询结果 + * + * @param request + * @return + */ + @RequestMapping(value = "/execute_update", method = {RequestMethod.POST, RequestMethod.PUT}) + public DataResult executeUpdate(@RequestBody SelectResultUpdateRequest request) { + UpdateSelectResultParam param = rdbWebConverter.request2param(request); + return dlTemplateService.updateSelectResult(param); + + } + + /** * 增删改查等数据运维 * diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/TableController.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/TableController.java index bcbcca69..08074344 100644 --- a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/TableController.java +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/TableController.java @@ -174,11 +174,13 @@ public class TableController { tableIndex.setTableName(table.getName()); tableIndex.setDatabaseName(request.getDatabaseName()); } + return tableService.buildSql(rdbWebConverter.tableRequest2param(request.getOldTable()),table) .map(rdbWebConverter::dto2vo); } + /** * 数据库支持的数据类型 * diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/converter/RdbWebConverter.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/converter/RdbWebConverter.java index 872e03fb..9dd847fd 100644 --- a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/converter/RdbWebConverter.java +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/converter/RdbWebConverter.java @@ -2,22 +2,9 @@ package ai.chat2db.server.web.api.controller.rdb.converter; import java.util.List; -import ai.chat2db.server.domain.api.param.DlCountParam; -import ai.chat2db.server.domain.api.param.DlExecuteParam; -import ai.chat2db.server.domain.api.param.DropParam; -import ai.chat2db.server.domain.api.param.ShowCreateTableParam; -import ai.chat2db.server.domain.api.param.TablePageQueryParam; -import ai.chat2db.server.domain.api.param.TableQueryParam; +import ai.chat2db.server.domain.api.param.*; import ai.chat2db.server.web.api.controller.data.source.vo.DatabaseVO; -import ai.chat2db.server.web.api.controller.rdb.request.DataExportRequest; -import ai.chat2db.server.web.api.controller.rdb.request.DdlCountRequest; -import ai.chat2db.server.web.api.controller.rdb.request.DdlExportRequest; -import ai.chat2db.server.web.api.controller.rdb.request.DdlRequest; -import ai.chat2db.server.web.api.controller.rdb.request.DmlRequest; -import ai.chat2db.server.web.api.controller.rdb.request.TableBriefQueryRequest; -import ai.chat2db.server.web.api.controller.rdb.request.TableDeleteRequest; -import ai.chat2db.server.web.api.controller.rdb.request.TableDetailQueryRequest; -import ai.chat2db.server.web.api.controller.rdb.request.TableRequest; +import ai.chat2db.server.web.api.controller.rdb.request.*; import ai.chat2db.server.web.api.controller.rdb.vo.ColumnVO; import ai.chat2db.server.web.api.controller.rdb.vo.ExecuteResultVO; import ai.chat2db.server.web.api.controller.rdb.vo.IndexVO; @@ -234,4 +221,7 @@ public abstract class RdbWebConverter { public abstract List databaseDto2vo(List dto); public abstract MetaSchemaVO metaSchemaDto2vo(MetaSchema data); + + + public abstract UpdateSelectResultParam request2param(SelectResultUpdateRequest request); } diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/SelectResultUpdateRequest.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/SelectResultUpdateRequest.java new file mode 100644 index 00000000..164a0ce4 --- /dev/null +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/SelectResultUpdateRequest.java @@ -0,0 +1,44 @@ +package ai.chat2db.server.web.api.controller.rdb.request; + +import ai.chat2db.server.web.api.controller.data.source.request.DataSourceBaseRequest; +import ai.chat2db.server.web.api.controller.data.source.request.DataSourceConsoleRequestInfo; +import ai.chat2db.server.web.api.controller.rdb.vo.HeaderVO; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +@Data +public class SelectResultUpdateRequest extends DataSourceBaseRequest implements DataSourceConsoleRequestInfo { + + /** + * 展示头的列表 + */ + private List headerList; + + /** + * 修改后数据的列表 + */ + private List> dataList; + + /** + * 数据的列表 + */ + private List> oldDataList; + + /** + * 表名 + */ + private String tableName; + + /** + * 控制台id + */ + @NotNull + private Long consoleId; + @Override + public Long getConsoleId() { + return consoleId; + } + +} diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/MetaData.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/MetaData.java index abba4689..9aa1c09b 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/MetaData.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/MetaData.java @@ -39,7 +39,7 @@ public interface MetaData { * @return */ String tableDDL(Connection connection, @NotEmpty String databaseName, String schemaName, - @NotEmpty String tableName); + @NotEmpty String tableName); /** * Querying all table under a schema. @@ -114,7 +114,7 @@ public interface MetaData { * @return */ List columns(Connection connection, @NotEmpty String databaseName, String schemaName, - @NotEmpty String tableName); + @NotEmpty String tableName); /** * Querying all columns under a table. @@ -127,7 +127,7 @@ public interface MetaData { * @return */ List columns(Connection connection, @NotEmpty String databaseName, String schemaName, String tableName, - String columnName); + String columnName); /** * Querying all indexes under a table. @@ -138,7 +138,7 @@ public interface MetaData { * @return */ List indexes(Connection connection, @NotEmpty String databaseName, String schemaName, - @NotEmpty String tableName); + @NotEmpty String tableName); /** * Querying function detail under a schema. @@ -171,11 +171,10 @@ public interface MetaData { * @param procedureName * @return */ - Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName,String procedureName); + Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName, String procedureName); /** - * * @param connection * @return */ @@ -184,17 +183,28 @@ public interface MetaData { /** * Get sql builder. + * * @return */ SqlBuilder getSqlBuilder(); /** - * * @param databaseName * @param schemaName * @param tableName * @return */ - TableMeta getTableMeta( String databaseName, String schemaName, String tableName); + TableMeta getTableMeta(String databaseName, String schemaName, String tableName); + + + /** + * Get meta data name. + * + * @param names + * @return + */ + String getMetaDataName(String ...names); + + } \ No newline at end of file diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/TableColumn.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/TableColumn.java index 91ede341..053b2427 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/TableColumn.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/model/TableColumn.java @@ -16,6 +16,11 @@ import lombok.experimental.SuperBuilder; @NoArgsConstructor @AllArgsConstructor public class TableColumn { + + /** + * Old column, when modifying a column, you need this parameter + */ + private TableColumn oldColumn; /** * 旧的列名,在修改列的时候需要这个参数 * 在返回的时候oldName=name @@ -58,6 +63,8 @@ public class TableColumn { @JsonAlias({"COLUMN_DEF"}) private String defaultValue; + + /** * 是否自增 * 为空 代表没有值 数据库的实际语义是 false @@ -88,7 +95,7 @@ public class TableColumn { private String databaseName; /** - * Data source dependent type name, for a UDT the type name is fully qualified + * Data source dependent type name, for a UDT the type name is fully qualified */ private String typeName; @@ -151,8 +158,8 @@ public class TableColumn { /** * String => Indicates whether this is a generated column - * * YES --- if this a generated column - * * NO --- if this not a generated column + * * YES --- if this a generated column + * * NO --- if this not a generated column */ private Boolean generatedColumn; @@ -166,9 +173,15 @@ public class TableColumn { private String collationName; + //Mysql private String value; - + //ORACLE private String unit; + // sqlserver + private Boolean sparse; + + // sqlserver + private String defaultConstraintName; } diff --git a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/SqlUtils.java b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/SqlUtils.java index 851dc75b..f40311fe 100644 --- a/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/SqlUtils.java +++ b/chat2db-server/chat2db-spi/src/main/java/ai/chat2db/spi/util/SqlUtils.java @@ -9,6 +9,7 @@ import java.util.Set; import java.util.stream.Collectors; import ai.chat2db.server.tools.common.util.EasyIntegerUtils; +import ai.chat2db.spi.enums.DataTypeEnum; import com.alibaba.druid.DbType; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLDataTypeImpl; @@ -57,6 +58,10 @@ import ai.chat2db.spi.model.TableIndexColumn; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.Statements; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.Select; +import net.sf.jsqlparser.statement.select.SelectExpressionItem; +import net.sf.jsqlparser.statement.select.SelectItem; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -69,6 +74,31 @@ public class SqlUtils { public static final String DEFAULT_TABLE_NAME = "table1"; + + public static boolean canEdit(String sql) { + try { + Statement statement = CCJSqlParserUtil.parse(sql); + if (statement instanceof Select) { + Select select = (Select) statement; + PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); + if (plainSelect.getJoins() == null && plainSelect.getFromItem() != null) { + for (SelectItem item : plainSelect.getSelectItems()) { + if (item instanceof SelectExpressionItem) { + SelectExpressionItem expressionItem = (SelectExpressionItem) item; + if (expressionItem.getAlias() != null) { + return false; // 找到了一个别名 + } + } + } + return true; + } + } + } catch (Exception e) { + return false; + } + return false; + } + public static List buildSql(Table oldTable, Table newTable) { List sqlList = new ArrayList<>(); // 创建表 @@ -86,7 +116,7 @@ public class SqlUtils { mySqlCreateTableStatement.addColumn(sqlColumnDefinition); sqlColumnDefinition.setName(tableColumn.getName()); sqlColumnDefinition.setDataType(new SQLDataTypeImpl(tableColumn.getColumnType())); - if (tableColumn.getNullable()==1) { + if (tableColumn.getNullable() == 1) { sqlColumnDefinition.addConstraint(new SQLNullConstraint()); } else { sqlColumnDefinition.addConstraint(new SQLNotNullConstraint()); @@ -130,7 +160,7 @@ public class SqlUtils { SQLSelectOrderByItem sqlSelectOrderByItem = new SQLSelectOrderByItem(); sqlSelectOrderByItem.setExpr(new SQLIdentifierExpr(tableIndexColumn.getColumnName())); CollationEnum collation = EasyEnumUtils.getEnum(CollationEnum.class, - tableIndexColumn.getCollation()); + tableIndexColumn.getCollation()); if (collation != null) { sqlSelectOrderByItem.setType(collation.getSqlOrderingSpecification()); } @@ -147,7 +177,7 @@ public class SqlUtils { SQLSelectOrderByItem sqlSelectOrderByItem = new SQLSelectOrderByItem(); sqlSelectOrderByItem.setExpr(new SQLIdentifierExpr(tableIndexColumn.getColumnName())); CollationEnum collation = EasyEnumUtils.getEnum(CollationEnum.class, - tableIndexColumn.getCollation()); + tableIndexColumn.getCollation()); if (collation != null) { sqlSelectOrderByItem.setType(collation.getSqlOrderingSpecification()); } @@ -193,19 +223,19 @@ public class SqlUtils { private static void modifyColumn(List sqlList, Table oldTable, Table newTable) { Map oldColumnMap = EasyCollectionUtils.toIdentityMap(oldTable.getColumnList(), - tableColumn -> { - if (tableColumn.getOldName() != null) { - return tableColumn.getOldName(); - } - return tableColumn.getName(); - }); + tableColumn -> { + if (tableColumn.getOldName() != null) { + return tableColumn.getOldName(); + } + return tableColumn.getName(); + }); Map newColumnMap = EasyCollectionUtils.toIdentityMap(newTable.getColumnList(), - tableColumn -> { - if (tableColumn.getOldName() != null) { - return tableColumn.getOldName(); - } - return tableColumn.getName(); - }); + tableColumn -> { + if (tableColumn.getOldName() != null) { + return tableColumn.getOldName(); + } + return tableColumn.getName(); + }); SQLAlterTableStatement sqlAlterTableStatement = new SQLAlterTableStatement(); sqlAlterTableStatement.setDbType(DbType.mysql); @@ -222,7 +252,7 @@ public class SqlUtils { sqlAlterTableAddColumn.addColumn(sqlColumnDefinition); sqlColumnDefinition.setName(newTableColumn.getName()); sqlColumnDefinition.setDataType(new SQLDataTypeImpl(newTableColumn.getColumnType())); - if (newTableColumn.getNullable()!=1) { + if (newTableColumn.getNullable() != 1) { sqlColumnDefinition.addConstraint(new SQLNotNullConstraint()); } if (!Objects.isNull(newTableColumn.getDefaultValue())) { @@ -236,12 +266,12 @@ public class SqlUtils { } // 代表可能修改字段 或者没变 boolean hasChange = !StringUtils.equals(oldTableColumn.getName(), newTableColumn.getName()) - || !StringUtils.equals(oldTableColumn.getColumnType(), newTableColumn.getColumnType()) - || !EasyIntegerUtils.equals(oldTableColumn.getNullable(), newTableColumn.getNullable(), 1) - || !StringUtils.equals(oldTableColumn.getDefaultValue(), newTableColumn.getDefaultValue()) - || !EasyBooleanUtils.equals(oldTableColumn.getAutoIncrement(), newTableColumn.getAutoIncrement(), - Boolean.FALSE) - || !StringUtils.equals(oldTableColumn.getComment(), newTableColumn.getComment()); + || !StringUtils.equals(oldTableColumn.getColumnType(), newTableColumn.getColumnType()) + || !EasyIntegerUtils.equals(oldTableColumn.getNullable(), newTableColumn.getNullable(), 1) + || !StringUtils.equals(oldTableColumn.getDefaultValue(), newTableColumn.getDefaultValue()) + || !EasyBooleanUtils.equals(oldTableColumn.getAutoIncrement(), newTableColumn.getAutoIncrement(), + Boolean.FALSE) + || !StringUtils.equals(oldTableColumn.getComment(), newTableColumn.getComment()); // 没有修改字段 if (!hasChange) { @@ -257,7 +287,7 @@ public class SqlUtils { mySqlAlterTableChangeColumn.setNewColumnDefinition(sqlColumnDefinition); sqlColumnDefinition.setName(newTableColumn.getName()); sqlColumnDefinition.setDataType(new SQLDataTypeImpl(newTableColumn.getColumnType())); - if (newTableColumn.getNullable()!=1) { + if (newTableColumn.getNullable() != 1) { sqlColumnDefinition.addConstraint(new SQLNotNullConstraint()); } if (!Objects.isNull(newTableColumn.getDefaultValue())) { @@ -275,7 +305,7 @@ public class SqlUtils { mySqlAlterTableModifyColumn.setNewColumnDefinition(sqlColumnDefinition); sqlColumnDefinition.setName(newTableColumn.getName()); sqlColumnDefinition.setDataType(new SQLDataTypeImpl(newTableColumn.getColumnType())); - if (newTableColumn.getNullable()!=1) { + if (newTableColumn.getNullable() != 1) { sqlColumnDefinition.addConstraint(new SQLNotNullConstraint()); } if (!Objects.isNull(newTableColumn.getDefaultValue())) { @@ -301,17 +331,17 @@ public class SqlUtils { // 比较主键是否有修改 // 主键 Set oldPrimaryKeySet = EasyCollectionUtils.stream(oldTable.getColumnList()) - .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) - .map(TableColumn::getName) - .collect(Collectors.toSet()); + .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) + .map(TableColumn::getName) + .collect(Collectors.toSet()); Set newPrimaryKeySet = EasyCollectionUtils.stream(newTable.getColumnList()) - .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) - .map(TableColumn::getName) - .collect(Collectors.toSet()); + .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) + .map(TableColumn::getName) + .collect(Collectors.toSet()); boolean primaryKeyChange = oldPrimaryKeySet.stream() - .anyMatch(oldPrimaryKey -> !newPrimaryKeySet.contains(oldPrimaryKey)) - || newPrimaryKeySet.stream() - .anyMatch(newPrimaryKey -> !oldPrimaryKeySet.contains(newPrimaryKey)); + .anyMatch(oldPrimaryKey -> !newPrimaryKeySet.contains(oldPrimaryKey)) + || newPrimaryKeySet.stream() + .anyMatch(newPrimaryKey -> !oldPrimaryKeySet.contains(newPrimaryKey)); if (primaryKeyChange) { sqlAlterTableStatement.addItem(new SQLAlterTableDropPrimaryKey()); SQLAlterTableAddConstraint sqlAlterTableAddConstraint = new SQLAlterTableAddConstraint(); @@ -321,10 +351,10 @@ public class SqlUtils { mySqlPrimaryKey.setIndexType("PRIMARY"); // 排序 EasyCollectionUtils.stream(newTable.getColumnList()) - .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) - .map(TableColumn::getName) - .forEach(tableColumnName -> mySqlPrimaryKey.addColumn( - new SQLSelectOrderByItem(new SQLIdentifierExpr(tableColumnName)))); + .filter(tableColumn -> BooleanUtils.isTrue(tableColumn.getPrimaryKey())) + .map(TableColumn::getName) + .forEach(tableColumnName -> mySqlPrimaryKey.addColumn( + new SQLSelectOrderByItem(new SQLIdentifierExpr(tableColumnName)))); } if (CollectionUtils.isNotEmpty(sqlAlterTableStatement.getItems())) { @@ -334,9 +364,9 @@ public class SqlUtils { private static void modifyIndex(List sqlList, Table oldTable, Table newTable) { Map oldIndexMap = EasyCollectionUtils.toIdentityMap(oldTable.getIndexList(), - TableIndex::getName); + TableIndex::getName); Map newIndexMap = EasyCollectionUtils.toIdentityMap(newTable.getIndexList(), - TableIndex::getName); + TableIndex::getName); newIndexMap.forEach((newTableIndexName, newTableIndex) -> { TableIndex oldTableIndex = oldIndexMap.get(newTableIndexName); // 代表新增索引 @@ -352,7 +382,7 @@ public class SqlUtils { SQLSelectOrderByItem sqlSelectOrderByItem = new SQLSelectOrderByItem(); sqlSelectOrderByItem.setExpr(new SQLIdentifierExpr(tableIndexColumn.getColumnName())); CollationEnum collation = EasyEnumUtils.getEnum(CollationEnum.class, - tableIndexColumn.getCollation()); + tableIndexColumn.getCollation()); if (collation != null) { sqlSelectOrderByItem.setType(collation.getSqlOrderingSpecification()); } @@ -364,34 +394,34 @@ public class SqlUtils { } // 代表可能修改索引 或者没变 boolean hasChange = !StringUtils.equals(oldTableIndex.getName(), newTableIndex.getName()) - || !StringUtils.equals(oldTableIndex.getComment(), newTableIndex.getComment()) - || !Objects.equals(oldTableIndex.getUnique(), newTableIndex.getUnique()); + || !StringUtils.equals(oldTableIndex.getComment(), newTableIndex.getComment()) + || !Objects.equals(oldTableIndex.getUnique(), newTableIndex.getUnique()); if (!hasChange) { Map oldTableIndexColumnMap = EasyCollectionUtils.toIdentityMap( - oldTableIndex.getColumnList(), TableIndexColumn::getColumnName); + oldTableIndex.getColumnList(), TableIndexColumn::getColumnName); Map newTableIndexColumnMap = EasyCollectionUtils.toIdentityMap( - newTableIndex.getColumnList(), TableIndexColumn::getColumnName); + newTableIndex.getColumnList(), TableIndexColumn::getColumnName); hasChange = oldTableIndexColumnMap.entrySet() - .stream() - .anyMatch(oldTableIndexColumnEntry -> { - TableIndexColumn newTableIndexColumn = newTableIndexColumnMap.get( - oldTableIndexColumnEntry.getKey()); - if (newTableIndexColumn == null) { - return true; - } - TableIndexColumn oldTableIndexColumn = oldTableIndexColumnEntry.getValue(); - return !StringUtils.equals(oldTableIndexColumn.getColumnName(), - newTableIndexColumn.getColumnName()) - || !CollationEnum.equals(oldTableIndexColumn.getCollation(), - newTableIndexColumn.getCollation()); - }) - || newTableIndexColumnMap.entrySet() - .stream() - .anyMatch(newTableIndexColumnEntry -> { - TableIndexColumn oldTableIndexColumn = oldTableIndexColumnMap.get( - newTableIndexColumnEntry.getKey()); - return oldTableIndexColumn == null; - }); + .stream() + .anyMatch(oldTableIndexColumnEntry -> { + TableIndexColumn newTableIndexColumn = newTableIndexColumnMap.get( + oldTableIndexColumnEntry.getKey()); + if (newTableIndexColumn == null) { + return true; + } + TableIndexColumn oldTableIndexColumn = oldTableIndexColumnEntry.getValue(); + return !StringUtils.equals(oldTableIndexColumn.getColumnName(), + newTableIndexColumn.getColumnName()) + || !CollationEnum.equals(oldTableIndexColumn.getCollation(), + newTableIndexColumn.getCollation()); + }) + || newTableIndexColumnMap.entrySet() + .stream() + .anyMatch(newTableIndexColumnEntry -> { + TableIndexColumn oldTableIndexColumn = oldTableIndexColumnMap.get( + newTableIndexColumnEntry.getKey()); + return oldTableIndexColumn == null; + }); } // 没有修改索引 @@ -417,7 +447,7 @@ public class SqlUtils { SQLSelectOrderByItem sqlSelectOrderByItem = new SQLSelectOrderByItem(); sqlSelectOrderByItem.setExpr(new SQLIdentifierExpr(tableIndexColumn.getColumnName())); CollationEnum collation = EasyEnumUtils.getEnum(CollationEnum.class, - tableIndexColumn.getCollation()); + tableIndexColumn.getCollation()); if (collation != null) { sqlSelectOrderByItem.setType(collation.getSqlOrderingSpecification()); } @@ -449,8 +479,8 @@ public class SqlUtils { if (!(sqlStatement instanceof SQLSelectStatement sqlSelectStatement)) { throw new BusinessException("dataSource.sqlAnalysisError"); } - SQLExprTableSource sqlExprTableSource = (SQLExprTableSource)getSQLExprTableSource( - sqlSelectStatement.getSelect().getFirstQueryBlock().getFrom()); + SQLExprTableSource sqlExprTableSource = (SQLExprTableSource) getSQLExprTableSource( + sqlSelectStatement.getSelect().getFirstQueryBlock().getFrom()); if (sqlExprTableSource == null) { return DEFAULT_TABLE_NAME; } @@ -466,7 +496,7 @@ public class SqlUtils { return null; } - public static List parse(String sql,DbType dbType) { + public static List parse(String sql, DbType dbType) { List list = new ArrayList<>(); try { Statements statements = CCJSqlParserUtil.parseStatements(sql); @@ -480,4 +510,11 @@ public class SqlUtils { return list; } + public static String getSqlValue(String value, String dataType) { + if(value == null){ + return null; + } + DataTypeEnum dataTypeEnum = DataTypeEnum.getByCode(dataType); + return dataTypeEnum.getSqlValue(value); + } } \ No newline at end of file