mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-29 10:43:06 +08:00
Merge branch 'dev' of github.com:chat2db/Chat2DB into dev
This commit is contained in:
@ -4,10 +4,59 @@ import java.sql.Connection;
|
||||
|
||||
import ai.chat2db.spi.DBManage;
|
||||
import ai.chat2db.spi.jdbc.DefaultDBManage;
|
||||
import ai.chat2db.spi.sql.Chat2DBContext;
|
||||
import ai.chat2db.spi.sql.ConnectInfo;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class KingBaseDBManage extends DefaultDBManage implements DBManage {
|
||||
|
||||
@Override
|
||||
public void connectDatabase(Connection connection, String database) {
|
||||
try {
|
||||
ConnectInfo connectInfo = Chat2DBContext.getConnectInfo();
|
||||
if (!StringUtils.isEmpty(connectInfo.getSchemaName())) {
|
||||
SQLExecutor.getInstance().execute(connection, "SET search_path TO \"" + connectInfo.getSchemaName() + "\"");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(ConnectInfo connectInfo) {
|
||||
String url = connectInfo.getUrl();
|
||||
String database = connectInfo.getDatabaseName();
|
||||
if (database != null && !database.isEmpty()) {
|
||||
url = replaceDatabaseInJdbcUrl(url, database);
|
||||
}
|
||||
connectInfo.setUrl(url);
|
||||
|
||||
return super.getConnection(connectInfo);
|
||||
}
|
||||
|
||||
|
||||
public String replaceDatabaseInJdbcUrl(String url, String newDatabase) {
|
||||
// 先在"?"字符处分割字符串,处理查询参数
|
||||
String[] urlAndParams = url.split("\\?");
|
||||
String urlWithoutParams = urlAndParams[0];
|
||||
|
||||
// 在URL中的"/"字符处分割字符串
|
||||
String[] parts = urlWithoutParams.split("/");
|
||||
|
||||
// 取最后一部分,即数据库名,并替换为新的数据库名
|
||||
parts[parts.length - 1] = newDatabase;
|
||||
|
||||
// 将修改后的部分重新组合成URL
|
||||
String newUrlWithoutParams = String.join("/", parts);
|
||||
|
||||
// 如果存在查询参数,重新添加
|
||||
String newUrl = urlAndParams.length > 1 ? newUrlWithoutParams + "?" + urlAndParams[1] : newUrlWithoutParams;
|
||||
|
||||
return newUrl;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dropTable(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = "drop table if exists " +tableName;
|
||||
|
@ -1,7 +1,192 @@
|
||||
package ai.chat2db.plugin.kingbase;
|
||||
|
||||
import ai.chat2db.plugin.kingbase.builder.KingBaseSqlBuilder;
|
||||
import ai.chat2db.plugin.kingbase.type.KingBaseColumnTypeEnum;
|
||||
import ai.chat2db.plugin.kingbase.type.KingBaseIndexTypeEnum;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
||||
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;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ai.chat2db.spi.util.SortUtils.sortDatabase;
|
||||
|
||||
public class KingBaseMetaData extends DefaultMetaService implements MetaData {
|
||||
|
||||
|
||||
private static final String SELECT_KEY_INDEX = "SELECT ccu.table_schema AS Foreign_schema_name, ccu.table_name AS Foreign_table_name, ccu.column_name AS Foreign_column_name, constraint_type AS Constraint_type, tc.CONSTRAINT_NAME AS Key_name, tc.TABLE_NAME, kcu.Column_name, tc.is_deferrable, tc.initially_deferred FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name WHERE tc.TABLE_SCHEMA = '%s' AND tc.TABLE_NAME = '%s';";
|
||||
|
||||
|
||||
private List<String> systemDatabases = Arrays.asList("SAMPLES", "SECURITY");
|
||||
|
||||
@Override
|
||||
public List<Database> databases(Connection connection) {
|
||||
List<Database> list = SQLExecutor.getInstance().executeSql(connection, "SELECT datname FROM sys_database", resultSet -> {
|
||||
List<Database> databases = new ArrayList<>();
|
||||
try {
|
||||
while (resultSet.next()) {
|
||||
String dbName = resultSet.getString("datname");
|
||||
if ("template0".equalsIgnoreCase(dbName) || "template1".equalsIgnoreCase(dbName) ||
|
||||
"template2".equalsIgnoreCase(dbName)) {
|
||||
continue;
|
||||
}
|
||||
Database database = new Database();
|
||||
database.setName(dbName);
|
||||
databases.add(database);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return databases;
|
||||
});
|
||||
return sortDatabase(list, systemDatabases, connection);
|
||||
}
|
||||
|
||||
private static final String SELECT_TABLE_INDEX = "SELECT tmp.INDISPRIMARY AS Index_primary, tmp.TABLE_SCHEM, tmp.TABLE_NAME, tmp.NON_UNIQUE, tmp.INDEX_QUALIFIER, tmp.INDEX_NAME AS Key_name, tmp.indisclustered, tmp.ORDINAL_POSITION AS Seq_in_index, trim(BOTH '\"' FROM sys_get_indexdef( tmp.CI_OID, tmp.ORDINAL_POSITION, FALSE) ) AS Column_name, CASE tmp.AM_NAME WHEN 'btree' THEN CASE tmp.I_INDOPTION [ tmp.ORDINAL_POSITION - 1 ] & 1 :: SMALLINT WHEN 1 THEN 'D' ELSE'A' END ELSE NULL END AS Collation, tmp.CARDINALITY, tmp.PAGES, tmp.FILTER_CONDITION , tmp.AM_NAME AS Index_method, tmp.DESCRIPTION AS Index_comment FROM ( SELECT n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, i.INDISPRIMARY , i.indisclustered , ( information_schema._sys_expandarray ( i.indkey ) ).n AS ORDINAL_POSITION, ci.reltuples AS CARDINALITY, ci.relpages AS PAGES, sys_get_expr ( i.indpred, i.indrelid ) AS FILTER_CONDITION, ci.OID AS CI_OID, i.indoption AS I_INDOPTION, am.amname AS AM_NAME , d.description FROM sys_class ct JOIN sys_namespace n ON ( ct.relnamespace = n.OID ) JOIN sys_index i ON ( ct.OID = i.indrelid ) JOIN sys_class ci ON ( ci.OID = i.indexrelid ) JOIN sys_am am ON ( ci.relam = am.OID ) left outer join sys_description d on i.indexrelid = d.objoid WHERE n.nspname = '%s' AND ct.relname = '%s' ) AS tmp";
|
||||
|
||||
@Override
|
||||
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
|
||||
String constraintSql = String.format(SELECT_KEY_INDEX, schemaName, tableName);
|
||||
Map<String, String> constraintMap = new HashMap();
|
||||
LinkedHashMap<String, TableIndex> foreignMap = new LinkedHashMap();
|
||||
SQLExecutor.getInstance().execute(connection, constraintSql, resultSet -> {
|
||||
while (resultSet.next()) {
|
||||
String keyName = resultSet.getString("Key_name");
|
||||
String constraintType = resultSet.getString("Constraint_type");
|
||||
constraintMap.put(keyName, constraintType);
|
||||
if (StringUtils.equalsIgnoreCase(constraintType, KingBaseIndexTypeEnum.FOREIGN.getKeyword())) {
|
||||
TableIndex tableIndex = foreignMap.get(keyName);
|
||||
String columnName = resultSet.getString("Column_name");
|
||||
if (tableIndex == null) {
|
||||
tableIndex = new TableIndex();
|
||||
tableIndex.setDatabaseName(databaseName);
|
||||
tableIndex.setSchemaName(schemaName);
|
||||
tableIndex.setTableName(tableName);
|
||||
tableIndex.setName(keyName);
|
||||
tableIndex.setForeignSchemaName(resultSet.getString("Foreign_schema_name"));
|
||||
tableIndex.setForeignTableName(resultSet.getString("Foreign_table_name"));
|
||||
tableIndex.setForeignColumnNamelist(Lists.newArrayList(columnName));
|
||||
tableIndex.setType(KingBaseIndexTypeEnum.FOREIGN.getName());
|
||||
foreignMap.put(keyName, tableIndex);
|
||||
} else {
|
||||
tableIndex.getForeignColumnNamelist().add(columnName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
String sql = String.format(SELECT_TABLE_INDEX, schemaName, tableName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
LinkedHashMap<String, TableIndex> map = new LinkedHashMap(foreignMap);
|
||||
|
||||
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(!StringUtils.equals("t", resultSet.getString("NON_UNIQUE")));
|
||||
index.setMethod(resultSet.getString("Index_method"));
|
||||
index.setComment(resultSet.getString("Index_comment"));
|
||||
List<TableIndexColumn> tableIndexColumns = new ArrayList<>();
|
||||
tableIndexColumns.add(getTableIndexColumn(resultSet));
|
||||
index.setColumnList(tableIndexColumns);
|
||||
String constraintType = constraintMap.get(keyName);
|
||||
if (StringUtils.equals("t", resultSet.getString("Index_primary"))) {
|
||||
index.setType(KingBaseIndexTypeEnum.PRIMARY.getName());
|
||||
} else if (StringUtils.equalsIgnoreCase(constraintType, KingBaseIndexTypeEnum.UNIQUE.getName())) {
|
||||
index.setType(KingBaseIndexTypeEnum.UNIQUE.getName());
|
||||
} else {
|
||||
index.setType(KingBaseIndexTypeEnum.NORMAL.getName());
|
||||
}
|
||||
map.put(keyName, index);
|
||||
}
|
||||
}
|
||||
return map.values().stream().collect(Collectors.toList());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private TableIndexColumn getTableIndexColumn(ResultSet resultSet) throws SQLException {
|
||||
TableIndexColumn tableIndexColumn = new TableIndexColumn();
|
||||
tableIndexColumn.setColumnName(resultSet.getString("Column_name"));
|
||||
tableIndexColumn.setOrdinalPosition(resultSet.getShort("Seq_in_index"));
|
||||
tableIndexColumn.setCollation(resultSet.getString("Collation"));
|
||||
tableIndexColumn.setAscOrDesc(resultSet.getString("Collation"));
|
||||
return tableIndexColumn;
|
||||
}
|
||||
|
||||
private static String ROUTINES_SQL = " SELECT p.proname, p.prokind, sys_catalog.sys_get_functiondef(p.oid) as \"code\" FROM sys_catalog.sys_proc p where p.proname='%s'";
|
||||
|
||||
@Override
|
||||
public Function function(Connection connection, @NotEmpty String databaseName, String schemaName,
|
||||
String functionName) {
|
||||
|
||||
String sql = String.format(ROUTINES_SQL, "f", 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.setFunctionBody(resultSet.getString("code"));
|
||||
}
|
||||
return function;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Procedure procedure(Connection connection, @NotEmpty String databaseName, String schemaName,
|
||||
String procedureName) {
|
||||
String sql = String.format(ROUTINES_SQL, 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.setProcedureBody(resultSet.getString("code"));
|
||||
}
|
||||
return procedure;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlBuilder getSqlBuilder() {
|
||||
return new KingBaseSqlBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableMeta getTableMeta(String databaseName, String schemaName, String tableName) {
|
||||
return TableMeta.builder()
|
||||
.columnTypes(KingBaseColumnTypeEnum.getTypes())
|
||||
//.charsets(PostgreSQLCharsetEnum.getCharsets())
|
||||
//.collations(PostgreSQLCollationEnum.getCollations())
|
||||
.indexTypes(KingBaseIndexTypeEnum.getIndexTypes())
|
||||
.build();
|
||||
}
|
||||
@Override
|
||||
public String getMetaDataName(String... names) {
|
||||
return Arrays.stream(names).filter(name -> StringUtils.isNotBlank(name)).map(name -> "\"" + name + "\"").collect(Collectors.joining("."));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,209 @@
|
||||
package ai.chat2db.plugin.kingbase.builder;
|
||||
|
||||
import ai.chat2db.plugin.kingbase.type.KingBaseColumnTypeEnum;
|
||||
import ai.chat2db.plugin.kingbase.type.KingBaseIndexTypeEnum;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class KingBaseSqlBuilder extends DefaultSqlBuilder implements SqlBuilder {
|
||||
@Override
|
||||
public String buildCreateTableSql(Table table) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append("CREATE TABLE ");
|
||||
script.append("\"").append(table.getName()).append("\"").append(" (").append(" ").append("\n");
|
||||
// append column
|
||||
for (TableColumn column : table.getColumnList()) {
|
||||
if (StringUtils.isBlank(column.getName()) || StringUtils.isBlank(column.getColumnType())) {
|
||||
continue;
|
||||
}
|
||||
KingBaseColumnTypeEnum typeEnum = KingBaseColumnTypeEnum.getByType(column.getColumnType());
|
||||
script.append("\t").append(typeEnum.buildCreateColumnSql(column)).append(",\n");
|
||||
}
|
||||
Map<Boolean, List<TableIndex>> tableIndexMap = table.getIndexList().stream()
|
||||
.collect(Collectors.partitioningBy(v -> KingBaseIndexTypeEnum.NORMAL.getName().equals(v.getType())));
|
||||
// append constraint key
|
||||
List<TableIndex> constraintList = tableIndexMap.get(Boolean.FALSE);
|
||||
if (CollectionUtils.isNotEmpty(constraintList)) {
|
||||
for (TableIndex index : constraintList) {
|
||||
if (StringUtils.isBlank(index.getName()) || StringUtils.isBlank(index.getType())) {
|
||||
continue;
|
||||
}
|
||||
KingBaseIndexTypeEnum indexTypeEnum = KingBaseIndexTypeEnum.getByType(index.getType());
|
||||
script.append("\t").append("").append(indexTypeEnum.buildIndexScript(index));
|
||||
script.append(",\n");
|
||||
}
|
||||
|
||||
}
|
||||
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||
script.append("\n)");
|
||||
if(StringUtils.isNotBlank(table.getTablespace())){
|
||||
script.append(" TABLESPACE \"").append(table.getTablespace()).append("\";");
|
||||
}else {
|
||||
script.append(" TABLESPACE \"SYS_DEFAULT\";");
|
||||
}
|
||||
// append index
|
||||
List<TableIndex> tableIndexList = tableIndexMap.get(Boolean.TRUE);
|
||||
for (TableIndex tableIndex : tableIndexList) {
|
||||
if (StringUtils.isBlank(tableIndex.getName()) || StringUtils.isBlank(tableIndex.getType())) {
|
||||
continue;
|
||||
}
|
||||
script.append("\n");
|
||||
KingBaseIndexTypeEnum indexTypeEnum = KingBaseIndexTypeEnum.getByType(tableIndex.getType());
|
||||
script.append("").append(indexTypeEnum.buildIndexScript(tableIndex)).append(";");
|
||||
}
|
||||
|
||||
// append comment
|
||||
if (StringUtils.isNotBlank(table.getComment())) {
|
||||
script.append("\n");
|
||||
script.append("COMMENT ON TABLE").append(" ").append("\"").append(table.getName()).append("\" IS '")
|
||||
.append(table.getComment()).append("';\n");
|
||||
}
|
||||
List<TableColumn> tableColumnList = table.getColumnList().stream().filter(v -> StringUtils.isNotBlank(v.getComment())).toList();
|
||||
for (TableColumn tableColumn : tableColumnList) {
|
||||
KingBaseColumnTypeEnum typeEnum = KingBaseColumnTypeEnum.getByType(tableColumn.getColumnType());
|
||||
script.append(typeEnum.buildComment(tableColumn, typeEnum)).append("\n");
|
||||
;
|
||||
}
|
||||
List<TableIndex> indexList = table.getIndexList().stream().filter(v -> StringUtils.isNotBlank(v.getComment())).toList();
|
||||
for (TableIndex index : indexList) {
|
||||
KingBaseIndexTypeEnum indexEnum = KingBaseIndexTypeEnum.getByType(index.getType());
|
||||
script.append(indexEnum.buildIndexComment(index)).append("\n");
|
||||
}
|
||||
|
||||
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.getName()).append("\"");
|
||||
script.append("\t").append("RENAME TO ").append("\"").append(newTable.getName()).append("\"").append(";\n");
|
||||
|
||||
}
|
||||
newTable.setColumnList(newTable.getColumnList().stream().filter(v -> StringUtils.isNotBlank(v.getEditStatus())).toList());
|
||||
newTable.setIndexList(newTable.getIndexList().stream().filter(v -> StringUtils.isNotBlank(v.getEditStatus())).toList());
|
||||
|
||||
//update name
|
||||
List<TableColumn> columnNameList = newTable.getColumnList().stream().filter(v ->
|
||||
v.getOldName() != null && !StringUtils.equals(v.getOldName(), v.getName())).toList();
|
||||
for (TableColumn tableColumn : columnNameList) {
|
||||
script.append("ALTER TABLE ").append("\"").append(newTable.getName()).append("\" ").append("RENAME COLUMN \"")
|
||||
.append(tableColumn.getOldName()).append("\" TO \"").append(tableColumn.getName()).append("\";\n");
|
||||
}
|
||||
|
||||
Map<Boolean, List<TableIndex>> tableIndexMap = newTable.getIndexList().stream()
|
||||
.collect(Collectors.partitioningBy(v -> KingBaseIndexTypeEnum.NORMAL.getName().equals(v.getType())));
|
||||
StringBuilder scriptModify = new StringBuilder();
|
||||
Boolean modify = false;
|
||||
scriptModify.append("ALTER TABLE ").append("\"").append(newTable.getName()).append("\" \n");
|
||||
// append modify column
|
||||
for (TableColumn tableColumn : newTable.getColumnList()) {
|
||||
KingBaseColumnTypeEnum typeEnum = KingBaseColumnTypeEnum.getByType(tableColumn.getColumnType());
|
||||
scriptModify.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(",\n");
|
||||
modify = true;
|
||||
|
||||
}
|
||||
|
||||
// append modify constraint
|
||||
for (TableIndex tableIndex : tableIndexMap.get(Boolean.FALSE)) {
|
||||
if (StringUtils.isNotBlank(tableIndex.getType())) {
|
||||
KingBaseIndexTypeEnum indexTypeEnum = KingBaseIndexTypeEnum.getByType(tableIndex.getType());
|
||||
scriptModify.append("\t").append(indexTypeEnum.buildModifyIndex(tableIndex)).append(",\n");
|
||||
modify = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (BooleanUtils.isTrue(modify)) {
|
||||
script.append(scriptModify);
|
||||
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||
script.append(";\n");
|
||||
}
|
||||
|
||||
// append modify index
|
||||
for (TableIndex tableIndex : tableIndexMap.get(Boolean.TRUE)) {
|
||||
if (StringUtils.isNotBlank(tableIndex.getEditStatus()) && StringUtils.isNotBlank(tableIndex.getType())) {
|
||||
KingBaseIndexTypeEnum indexTypeEnum = KingBaseIndexTypeEnum.getByType(tableIndex.getType());
|
||||
script.append(indexTypeEnum.buildModifyIndex(tableIndex)).append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
// append comment
|
||||
if (!StringUtils.equals(oldTable.getComment(), newTable.getComment())) {
|
||||
script.append("\n");
|
||||
script.append("COMMENT ON TABLE").append(" ").append("\"").append(newTable.getName()).append("\" IS '")
|
||||
.append(newTable.getComment()).append("';\n");
|
||||
}
|
||||
for (TableColumn tableColumn : newTable.getColumnList()) {
|
||||
KingBaseColumnTypeEnum typeEnum = KingBaseColumnTypeEnum.getByType(tableColumn.getColumnType());
|
||||
script.append(typeEnum.buildComment(tableColumn, typeEnum)).append("\n");
|
||||
;
|
||||
}
|
||||
List<TableIndex> indexList = newTable.getIndexList().stream().filter(v -> StringUtils.isNotBlank(v.getComment())).toList();
|
||||
for (TableIndex index : indexList) {
|
||||
KingBaseIndexTypeEnum indexEnum = KingBaseIndexTypeEnum.getByType(index.getType());
|
||||
script.append(indexEnum.buildIndexComment(index)).append("\n");
|
||||
}
|
||||
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pageLimit(String sql, int offset, int pageNo, int pageSize) {
|
||||
StringBuilder sqlStr = new StringBuilder(sql.length() + 17);
|
||||
sqlStr.append(sql);
|
||||
if (offset == 0) {
|
||||
sqlStr.append(" LIMIT ");
|
||||
sqlStr.append(pageSize);
|
||||
} else {
|
||||
sqlStr.append(" LIMIT ");
|
||||
sqlStr.append(pageSize);
|
||||
sqlStr.append(" OFFSET ");
|
||||
sqlStr.append(offset);
|
||||
}
|
||||
return sqlStr.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildCreateDatabaseSql(Database database) {
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("CREATE DATABASE "+database.getName());
|
||||
String owner = database.getOwner();
|
||||
if (StringUtils.isBlank(owner)) {
|
||||
owner = "SYSTEM";
|
||||
}
|
||||
sqlBuilder.append(" WITH OWNER = \"").append(owner).append("\"");
|
||||
if (StringUtils.isNotBlank(database.getCharset())) {
|
||||
sqlBuilder.append(" ENCODING ").append(database.getCharset()).append("");
|
||||
}
|
||||
sqlBuilder.append(";\n");
|
||||
|
||||
if (StringUtils.isNotBlank(database.getComment())) {
|
||||
sqlBuilder.append("COMMENT ON DATABASE ").append(database.getName()).append(" IS '").append(database.getComment()).append("';");
|
||||
}
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String buildCreateSchemaSql(Schema schema){
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("CREATE SCHEMA "+schema.getName()+"");
|
||||
String owner = schema.getOwner();
|
||||
if(StringUtils.isBlank(schema.getOwner())){
|
||||
owner = "SYSTEM";
|
||||
}
|
||||
sqlBuilder.append(" AUTHORIZATION \"").append(owner).append("\"");
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,244 @@
|
||||
package ai.chat2db.plugin.kingbase.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 KingBaseColumnTypeEnum implements ColumnBuilder {
|
||||
|
||||
BIGSERIAL("BIGSERIAL", false, false, true, false, false, false, true, true, false, false),
|
||||
BIT("BIT", true, false, true, false, false, false, true, true, false, false),
|
||||
BOOL("BOOL", false, false, true, false, false, false, true, true, false, false),
|
||||
BOX("BOX", false, false, true, false, false, false, true, true, false, false),
|
||||
BYTEA("BYTEA", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
CHARACTER("CHARACTER", true, false, true, false, false, true, true, true, false, false),
|
||||
|
||||
CHARACTER_VARYING("CHARACTER VARYING", true, false, true, false, false, true, true, true, false, false),
|
||||
CHAR("CHAR", true, false, true, false, false, true, true, true, false, false),
|
||||
|
||||
CID("CID", false, false, true, false, false, false, true, true, false, false),
|
||||
CIDR("CIDR", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
CIRCLE("CIRCLE", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
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, false, true, false, false, false, true, true, false, false),
|
||||
FLOAT4("FLOAT4", false, false, true, false, false, false, true, true, false, false),
|
||||
FLOAT8("FLOAT8", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
INTEGER("INTEGER", false, false, true, false, false, false, true, true, false, false),
|
||||
INET("INET", false, false, true, false, false, false, true, true, false, false),
|
||||
INT2("INT2", false, false, true, false, false, false, true, true, false, false),
|
||||
INT4("INT4", false, false, true, false, false, false, true, true, false, false),
|
||||
INT8("INT8", false, false, true, false, false, false, true, true, false, false),
|
||||
INTERVAL("INTERVAL", false, false, true, false, false, false, true, true, false, false),
|
||||
JSON("JSON", false, false, true, false, false, false, true, true, false, false),
|
||||
JSONB("JSONB", false, false, true, false, false, false, true, true, false, false),
|
||||
LINE("LINE", false, false, true, false, false, false, true, true, false, false),
|
||||
LSEG("LSEG", false, false, true, false, false, false, true, true, false, false),
|
||||
MACADDR("MACADDR", false, false, true, false, false, false, true, true, false, false),
|
||||
MONEY("MONEY", false, false, true, false, false, false, true, true, false, false),
|
||||
NUMERIC("NUMERIC", true, false, true, false, false, false, true, true, false, false),
|
||||
PATH("PATH", false, false, true, false, false, false, true, true, false, false),
|
||||
POINT("POINT", false, false, true, false, false, false, true, true, false, false),
|
||||
POLYGON("POLYGON", false, false, true, false, false, false, true, true, false, false),
|
||||
SERIAL("SERIAL", false, false, true, false, false, false, true, true, false, false),
|
||||
SERIAL2("SERIAL2", false, false, true, false, false, false, true, true, false, false),
|
||||
SERIAL4("SERIAL4", false, false, true, false, false, false, true, true, false, false),
|
||||
SERIAL8("SERIAL8", false, false, true, false, false, false, true, true, false, false),
|
||||
SMALLSERIAL("SMALLSERIAL", false, false, true, false, false, false, true, true, false, false),
|
||||
TEXT("TEXT", false, false, true, false, false, true, true, true, false, false),
|
||||
TIME("TIME", true, false, true, false, false, false, true, true, false, false),
|
||||
TIMESTAMP("TIMESTAMP", true, false, true, false, false, false, true, true, false, false),
|
||||
TIMESTAMPTZ("TIMESTAMPTZ", true, false, true, false, false, false, true, true, false, false),
|
||||
TIMETZ("TIMETZ", true, false, true, false, false, false, true, true, false, false),
|
||||
TSQUERY("TSQUERY", false, false, true, false, false, false, true, true, false, false),
|
||||
TSVECTOR("TSVECTOR", false, false, true, false, false, false, true, true, false, false),
|
||||
TXID_SNAPSHOT("TXID_SNAPSHOT", false, false, true, false, false, false, true, true, false, false),
|
||||
UUID("UUID", false, false, true, false, false, false, true, true, false, false),
|
||||
VARBIT("VARBIT", true, false, true, false, false, false, true, true, false, false),
|
||||
VARCHAR("VARCHAR", true, false, true, false, false, true, true, true, false, false),
|
||||
XML("XML", false, false, true, false, false, false, true, true, false, false),
|
||||
|
||||
;
|
||||
|
||||
private static Map<String, KingBaseColumnTypeEnum> COLUMN_TYPE_MAP = Maps.newHashMap();
|
||||
|
||||
static {
|
||||
for (KingBaseColumnTypeEnum value : KingBaseColumnTypeEnum.values()) {
|
||||
COLUMN_TYPE_MAP.put(value.getColumnType().getTypeName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
private ColumnType columnType;
|
||||
|
||||
|
||||
KingBaseColumnTypeEnum(String dataTypeName, boolean supportLength, boolean supportScale, boolean supportNullable, boolean supportAutoIncrement, boolean supportCharset, boolean supportCollation, boolean supportComments, boolean supportDefaultValue, boolean supportExtent, boolean supportValue) {
|
||||
this.columnType = new ColumnType(dataTypeName, supportLength, supportScale, supportNullable, supportAutoIncrement, supportCharset, supportCollation, supportComments, supportDefaultValue, supportExtent, supportValue, false);
|
||||
}
|
||||
|
||||
public static KingBaseColumnTypeEnum getByType(String dataType) {
|
||||
return COLUMN_TYPE_MAP.get(dataType.toUpperCase());
|
||||
}
|
||||
|
||||
public static List<ColumnType> getTypes() {
|
||||
return Arrays.stream(KingBaseColumnTypeEnum.values()).map(columnTypeEnum ->
|
||||
columnTypeEnum.getColumnType()
|
||||
).toList();
|
||||
}
|
||||
|
||||
public ColumnType getColumnType() {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildCreateColumnSql(TableColumn column) {
|
||||
KingBaseColumnTypeEnum 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(buildCollation(column, type)).append(" ");
|
||||
|
||||
script.append(buildNullable(column, type)).append(" ");
|
||||
|
||||
script.append(buildDefaultValue(column, type)).append(" ");
|
||||
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private String buildCollation(TableColumn column, KingBaseColumnTypeEnum type) {
|
||||
if (!type.getColumnType().isSupportCollation() || StringUtils.isEmpty(column.getCollationName())) {
|
||||
return "";
|
||||
}
|
||||
return StringUtils.join("\"", column.getCollationName(), "\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildModifyColumn(TableColumn column) {
|
||||
|
||||
if (EditStatus.DELETE.name().equals(column.getEditStatus())) {
|
||||
return StringUtils.join("DROP COLUMN `", column.getName() + "`");
|
||||
}
|
||||
if (EditStatus.ADD.name().equals(column.getEditStatus())) {
|
||||
return StringUtils.join("ADD COLUMN ", buildCreateColumnSql(column));
|
||||
}
|
||||
if (EditStatus.MODIFY.name().equals(column.getEditStatus())) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append("ALTER COLUMN \"").append(column.getName()).append("\" TYPE ").append(buildDataType(column, this)).append(",\n");
|
||||
if (column.getNullable() != null && 1 == column.getNullable()) {
|
||||
script.append("\t").append("ALTER COLUMN \"").append(column.getName()).append("\" DROP NOT NULL ,\n");
|
||||
} else {
|
||||
script.append("\t").append("ALTER COLUMN \"").append(column.getName()).append("\" SET NOT NULL ,\n");
|
||||
|
||||
}
|
||||
String defaultValue = buildDefaultValue(column, this);
|
||||
if (StringUtils.isNotBlank(defaultValue)) {
|
||||
script.append("ALTER COLUMN \"").append(column.getName()).append("\" SET ").append(defaultValue).append(",\n");
|
||||
}
|
||||
script = new StringBuilder(script.substring(0, script.length() - 2));
|
||||
return script.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String buildComment(TableColumn column, KingBaseColumnTypeEnum type) {
|
||||
if (!this.columnType.isSupportComments() || column.getComment() == null
|
||||
|| EditStatus.DELETE.name().equals(column.getEditStatus())) {
|
||||
return "";
|
||||
}
|
||||
return StringUtils.join("COMMENT ON COLUMN", " \"", column.getTableName(),
|
||||
"\".\"", column.getName(), "\" IS '", column.getComment(), "';");
|
||||
}
|
||||
|
||||
private String buildDefaultValue(TableColumn column, KingBaseColumnTypeEnum 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");
|
||||
}
|
||||
|
||||
if (Arrays.asList(CHAR, VARCHAR).contains(type)) {
|
||||
return StringUtils.join("DEFAULT '", column.getDefaultValue(), "'");
|
||||
}
|
||||
|
||||
if (Arrays.asList(TIMESTAMP, TIME, TIMETZ, TIMESTAMPTZ, DATE).contains(type)) {
|
||||
if ("CURRENT_TIMESTAMP".equalsIgnoreCase(column.getDefaultValue().trim())) {
|
||||
return StringUtils.join("DEFAULT ", column.getDefaultValue());
|
||||
}
|
||||
return StringUtils.join("DEFAULT '", column.getDefaultValue(), "'");
|
||||
}
|
||||
|
||||
return StringUtils.join("DEFAULT ", column.getDefaultValue());
|
||||
}
|
||||
|
||||
private String buildNullable(TableColumn column, KingBaseColumnTypeEnum type) {
|
||||
if (!type.getColumnType().isSupportNullable()) {
|
||||
return "";
|
||||
}
|
||||
if (column.getNullable() != null && 1 == column.getNullable()) {
|
||||
return "NULL";
|
||||
} else {
|
||||
return "NOT NULL";
|
||||
}
|
||||
}
|
||||
|
||||
private String buildDataType(TableColumn column, KingBaseColumnTypeEnum type) {
|
||||
String columnType = type.columnType.getTypeName();
|
||||
if (Arrays.asList(VARCHAR, CHAR,CHARACTER).contains(type)) {
|
||||
if (column.getColumnSize() == null ) {
|
||||
return columnType;
|
||||
}
|
||||
return StringUtils.join(columnType, "(", column.getColumnSize(), ")");
|
||||
}
|
||||
|
||||
if (Arrays.asList(VARBIT, BIT).contains(type)) {
|
||||
if (column.getColumnSize() == null ) {
|
||||
return columnType;
|
||||
}
|
||||
return StringUtils.join(columnType, "(", column.getColumnSize(), ")");
|
||||
}
|
||||
|
||||
if (Arrays.asList(TIME, TIMETZ, TIMESTAMPTZ, TIMESTAMP).contains(type)) {
|
||||
if (column.getColumnSize() == null || column.getColumnSize() == 0) {
|
||||
return columnType;
|
||||
} else {
|
||||
return StringUtils.join(columnType, "(", column.getColumnSize(), ")");
|
||||
}
|
||||
}
|
||||
|
||||
if (Arrays.asList(DECIMAL, NUMERIC).contains(type)) {
|
||||
if (column.getColumnSize() == null && column.getDecimalDigits() == null) {
|
||||
return columnType;
|
||||
}
|
||||
if (column.getColumnSize() != null && column.getDecimalDigits() == null) {
|
||||
return StringUtils.join(columnType, "(", column.getColumnSize() + ")");
|
||||
} else {
|
||||
return StringUtils.join(columnType, "(", column.getColumnSize() + "," + column.getDecimalDigits() + ")");
|
||||
}
|
||||
}
|
||||
return columnType;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
package ai.chat2db.plugin.kingbase.type;
|
||||
|
||||
import ai.chat2db.spi.enums.EditStatus;
|
||||
import ai.chat2db.spi.model.IndexType;
|
||||
import ai.chat2db.spi.model.TableIndex;
|
||||
import ai.chat2db.spi.model.TableIndexColumn;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public enum KingBaseIndexTypeEnum {
|
||||
|
||||
PRIMARY("Primary", "PRIMARY KEY"),
|
||||
|
||||
FOREIGN("Foreign", "FOREIGN KEY"),
|
||||
|
||||
NORMAL("Normal", "INDEX"),
|
||||
|
||||
UNIQUE("Unique", "UNIQUE"),
|
||||
;
|
||||
|
||||
private String name;
|
||||
private String keyword;
|
||||
|
||||
private IndexType indexType;
|
||||
|
||||
|
||||
KingBaseIndexTypeEnum(String name, String keyword) {
|
||||
this.name = name;
|
||||
this.keyword = keyword;
|
||||
this.indexType =new IndexType(name);
|
||||
}
|
||||
|
||||
public static KingBaseIndexTypeEnum getByType(String type) {
|
||||
for (KingBaseIndexTypeEnum value : KingBaseIndexTypeEnum.values()) {
|
||||
if (value.name.equalsIgnoreCase(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<IndexType> getIndexTypes() {
|
||||
return Arrays.asList(KingBaseIndexTypeEnum.values()).stream().map(KingBaseIndexTypeEnum::getIndexType).collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
public IndexType getIndexType() {
|
||||
return indexType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getKeyword() {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
public String buildIndexScript(TableIndex tableIndex) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
if (NORMAL.equals(this)) {
|
||||
script.append("CREATE").append(" ");
|
||||
script.append(buildIndexUnique(tableIndex)).append(" ");
|
||||
script.append(buildIndexConcurrently(tableIndex)).append(" ");
|
||||
script.append(buildIndexName(tableIndex)).append(" ");
|
||||
script.append("ON ").append("\"").append(tableIndex.getTableName()).append("\"").append(" ");
|
||||
script.append(buildIndexMethod(tableIndex)).append(" ");
|
||||
script.append(buildIndexColumn(tableIndex));
|
||||
} else {
|
||||
script.append("CONSTRAINT").append(" ");
|
||||
script.append(buildIndexName(tableIndex)).append(" ");
|
||||
script.append(keyword).append(" ");
|
||||
script.append(buildIndexColumn(tableIndex));
|
||||
script.append(buildForeignColum(tableIndex));
|
||||
}
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private String buildForeignColum(TableIndex tableIndex) {
|
||||
if (FOREIGN.equals(this)) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append(" REFERENCES ");
|
||||
if (StringUtils.isNotBlank(tableIndex.getForeignSchemaName())) {
|
||||
script.append(tableIndex.getForeignSchemaName()).append(".");
|
||||
}
|
||||
if (StringUtils.isNotBlank(tableIndex.getForeignTableName())) {
|
||||
script.append(tableIndex.getForeignTableName()).append(" ");
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(tableIndex.getForeignColumnNamelist())) {
|
||||
script.append("(");
|
||||
for (String column : tableIndex.getForeignColumnNamelist()) {
|
||||
if (StringUtils.isNotBlank(column)) {
|
||||
script.append("\"").append(column).append("\"").append(",");
|
||||
}
|
||||
}
|
||||
script.deleteCharAt(script.length() - 1);
|
||||
script.append(")");
|
||||
}
|
||||
return script.toString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String buildIndexMethod(TableIndex tableIndex) {
|
||||
if (StringUtils.isNotBlank(tableIndex.getMethod())) {
|
||||
return "USING " + tableIndex.getMethod();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String buildIndexConcurrently(TableIndex tableIndex) {
|
||||
if (BooleanUtils.isTrue(tableIndex.getConcurrently())) {
|
||||
return "CONCURRENTLY";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String buildIndexUnique(TableIndex tableIndex) {
|
||||
if (BooleanUtils.isTrue(tableIndex.getUnique())) {
|
||||
return "UNIQUE " + keyword;
|
||||
} else {
|
||||
return keyword;
|
||||
}
|
||||
}
|
||||
|
||||
public String buildIndexComment(TableIndex tableIndex) {
|
||||
if (StringUtils.isBlank(tableIndex.getComment()) || EditStatus.DELETE.name().equals(tableIndex.getEditStatus())) {
|
||||
return "";
|
||||
} else if (NORMAL.equals(this)) {
|
||||
return StringUtils.join("COMMENT ON INDEX", " ",
|
||||
"\"", tableIndex.getName(), "\" IS '", tableIndex.getComment(), "';");
|
||||
} else {
|
||||
return StringUtils.join("COMMENT ON CONSTRAINT", " \"", tableIndex.getName(), "\" ON \"", tableIndex.getSchemaName(),
|
||||
"\".\"", tableIndex.getTableName(), "\" IS '", tableIndex.getComment(), "';");
|
||||
}
|
||||
}
|
||||
|
||||
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("\"").append(",");
|
||||
}
|
||||
}
|
||||
script.deleteCharAt(script.length() - 1);
|
||||
script.append(")");
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private String buildIndexName(TableIndex tableIndex) {
|
||||
return "\"" + tableIndex.getName() + "\"";
|
||||
}
|
||||
|
||||
public String buildModifyIndex(TableIndex tableIndex) {
|
||||
boolean isNormal = NORMAL.equals(this);
|
||||
if (EditStatus.DELETE.name().equals(tableIndex.getEditStatus())) {
|
||||
return buildDropIndex(tableIndex);
|
||||
}
|
||||
if (EditStatus.MODIFY.name().equals(tableIndex.getEditStatus())) {
|
||||
return StringUtils.join(buildDropIndex(tableIndex), isNormal ? ";\n" : ",\n\tADD ", buildIndexScript(tableIndex));
|
||||
}
|
||||
if (EditStatus.ADD.name().equals(tableIndex.getEditStatus())) {
|
||||
return StringUtils.join(isNormal ? "" : "ADD ", buildIndexScript(tableIndex));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String buildDropIndex(TableIndex tableIndex) {
|
||||
if (NORMAL.equals(this)) {
|
||||
return StringUtils.join("DROP INDEX \"", tableIndex.getOldName(), "\"");
|
||||
}
|
||||
return StringUtils.join("DROP CONSTRAINT \"", tableIndex.getOldName(), "\"");
|
||||
}
|
||||
}
|
@ -75,9 +75,7 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData {
|
||||
|
||||
|
||||
private static final String SELECT_TABLE_INDEX = "SELECT tmp.INDISPRIMARY AS Index_primary, tmp.TABLE_SCHEM, tmp.TABLE_NAME, tmp.NON_UNIQUE, tmp.INDEX_QUALIFIER, tmp.INDEX_NAME AS Key_name, tmp.indisclustered, tmp.ORDINAL_POSITION AS Seq_in_index, TRIM ( BOTH '\"' FROM pg_get_indexdef ( tmp.CI_OID, tmp.ORDINAL_POSITION, FALSE ) ) AS Column_name,CASE tmp.AM_NAME WHEN 'btree' THEN CASE tmp.I_INDOPTION [ tmp.ORDINAL_POSITION - 1 ] & 1 :: SMALLINT WHEN 1 THEN 'D' ELSE'A' END ELSE NULL END AS Collation, tmp.CARDINALITY, tmp.PAGES, tmp.FILTER_CONDITION , tmp.AM_NAME AS Index_method, tmp.DESCRIPTION AS Index_comment FROM ( SELECT n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME,i.INDISPRIMARY , i.indisclustered , ( information_schema._pg_expandarray ( i.indkey ) ).n AS ORDINAL_POSITION, ci.reltuples AS CARDINALITY, ci.relpages AS PAGES, pg_get_expr ( i.indpred, i.indrelid ) AS FILTER_CONDITION, ci.OID AS CI_OID, i.indoption AS I_INDOPTION, am.amname AS AM_NAME , d.description FROM pg_class ct JOIN pg_namespace n ON ( ct.relnamespace = n.OID ) JOIN pg_index i ON ( ct.OID = i.indrelid ) JOIN pg_class ci ON ( ci.OID = i.indexrelid ) JOIN pg_am am ON ( ci.relam = am.OID ) left outer join pg_description d on i.indexrelid = d.objoid WHERE n.nspname = '%s' AND ct.relname = '%s' ) AS tmp ;";
|
||||
private static String ROUTINES_SQL
|
||||
= " SELECT p.proname, p.prokind, pg_catalog.pg_get_functiondef(p.oid) as \"code\" FROM pg_catalog.pg_proc p "
|
||||
+ "where p.prokind = '%s' and p.proname='%s';";
|
||||
private static String ROUTINES_SQL = "SELECT p.proname, p.prokind, pg_catalog.pg_get_functiondef(p.oid) as \"code\" FROM pg_catalog.pg_proc p where p.prokind = '%s' and p.proname='%s'";
|
||||
private static String TRIGGER_SQL
|
||||
= "SELECT n.nspname AS \"schema\", c.relname AS \"table_name\", t.tgname AS \"trigger_name\", t.tgenabled AS "
|
||||
+ "\"enabled\", pg_get_triggerdef(t.oid) AS \"trigger_body\" FROM pg_trigger t JOIN pg_class c ON c.oid = t"
|
||||
@ -301,4 +299,5 @@ public class PostgreSQLMetaData extends DefaultMetaService implements MetaData {
|
||||
.indexTypes(PostgreSQLIndexTypeEnum.getIndexTypes())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,6 +36,12 @@ public class DlExecuteParam {
|
||||
@NotNull
|
||||
private String databaseName;
|
||||
|
||||
|
||||
/**
|
||||
* schema名称
|
||||
*/
|
||||
private String schemaName;
|
||||
|
||||
/**
|
||||
* 分页编码
|
||||
* 只有select语句才有
|
||||
|
@ -2,15 +2,16 @@ package ai.chat2db.server.domain.core.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ai.chat2db.server.domain.api.param.*;
|
||||
import ai.chat2db.server.domain.api.param.operation.OperationLogCreateParam;
|
||||
import ai.chat2db.server.domain.api.service.OperationLogService;
|
||||
import ai.chat2db.server.domain.api.service.TableService;
|
||||
import ai.chat2db.server.domain.core.util.MetaNameUtils;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import ai.chat2db.spi.sql.ConnectInfo;
|
||||
import com.alibaba.druid.DbType;
|
||||
import com.alibaba.druid.sql.PagerUtils;
|
||||
@ -28,8 +29,6 @@ import ai.chat2db.server.tools.common.util.EasyCollectionUtils;
|
||||
import ai.chat2db.server.tools.common.util.I18nUtils;
|
||||
import ai.chat2db.spi.enums.DataTypeEnum;
|
||||
import ai.chat2db.spi.enums.SqlTypeEnum;
|
||||
import ai.chat2db.spi.model.ExecuteResult;
|
||||
import ai.chat2db.spi.model.Header;
|
||||
import ai.chat2db.spi.sql.Chat2DBContext;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
import ai.chat2db.spi.util.JdbcUtils;
|
||||
@ -37,6 +36,8 @@ import ai.chat2db.spi.util.SqlUtils;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -53,6 +54,9 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
@Autowired
|
||||
private OperationLogService operationLogService;
|
||||
|
||||
@Autowired
|
||||
private TableService tableService;
|
||||
|
||||
@Override
|
||||
public ListResult<ExecuteResult> execute(DlExecuteParam param) {
|
||||
if (StringUtils.isBlank(param.getSql())) {
|
||||
@ -147,9 +151,9 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
log.warn("解析sql失败:{}", originalSql, e);
|
||||
}
|
||||
ExecuteResult executeResult = null;
|
||||
if (SqlTypeEnum.SELECT.getCode().equals(sqlType) && !SqlUtils.hasPageLimit(originalSql,dbType)) {
|
||||
if (SqlTypeEnum.SELECT.getCode().equals(sqlType) && !SqlUtils.hasPageLimit(originalSql, dbType)) {
|
||||
String pageLimit = Chat2DBContext.getSqlBuilder().pageLimit(originalSql, offset, pageNo, pageSize);
|
||||
if(StringUtils.isNotBlank(pageLimit)) {
|
||||
if (StringUtils.isNotBlank(pageLimit)) {
|
||||
executeResult = execute(pageLimit, 0, count);
|
||||
}
|
||||
}
|
||||
@ -176,16 +180,16 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
executeResult.setHasNextPage(Boolean.FALSE);
|
||||
}
|
||||
|
||||
// Splice row numbers
|
||||
List<Header> newHeaderList = new ArrayList<>();
|
||||
newHeaderList.add(Header.builder()
|
||||
List<Header> headers = executeResult.getHeaderList();
|
||||
if (executeResult.getSuccess() && executeResult.isCanEdit() && CollectionUtils.isNotEmpty(headers)){
|
||||
headers = setColumnInfo(headers, executeResult.getTableName(), param.getSchemaName(), param.getDatabaseName());
|
||||
}
|
||||
Header rowNumberHeader = Header.builder()
|
||||
.name(I18nUtils.getMessage("sqlResult.rowNumber"))
|
||||
.dataType(DataTypeEnum.CHAT2DB_ROW_NUMBER
|
||||
.getCode()).build());
|
||||
if (executeResult.getHeaderList() != null) {
|
||||
newHeaderList.addAll(executeResult.getHeaderList());
|
||||
}
|
||||
executeResult.setHeaderList(newHeaderList);
|
||||
.getCode()).build();
|
||||
|
||||
executeResult.setHeaderList(EasyCollectionUtils.union(Arrays.asList(rowNumberHeader), headers));
|
||||
if (executeResult.getDataList() != null) {
|
||||
int rowNumberIncrement = 1 + Math.max(pageNo - 1, 0) * pageSize;
|
||||
for (int i = 0; i < executeResult.getDataList().size(); i++) {
|
||||
@ -246,19 +250,20 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
public DataResult<String> updateSelectResult(UpdateSelectResultParam param) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
MetaData metaSchema = Chat2DBContext.getMetaData();
|
||||
List<String> keyColumns = getPrimaryColumns(param);
|
||||
for (int i = 0; i < param.getOperations().size(); i++) {
|
||||
SelectResultOperation operation = param.getOperations().get(i);
|
||||
|
||||
List<String> row = operation.getDataList();
|
||||
List<String> odlRow = operation.getOldDataList();
|
||||
String sql = "";
|
||||
if ("UPDATE".equalsIgnoreCase(operation.getType())) {
|
||||
sql = getUpdateSql(param, row, odlRow, metaSchema);
|
||||
sql = getUpdateSql(param, row, odlRow, metaSchema, keyColumns, false);
|
||||
} else if ("CREATE".equalsIgnoreCase(operation.getType())) {
|
||||
sql = getInsertSql(param, row, metaSchema);
|
||||
|
||||
} else if ("DELETE".equalsIgnoreCase(operation.getType())) {
|
||||
sql = getDeleteSql(param, odlRow, metaSchema);
|
||||
sql = getDeleteSql(param, odlRow, metaSchema, keyColumns);
|
||||
} else if ("UPDATE_COPY".equalsIgnoreCase(operation.getType())) {
|
||||
sql = getUpdateSql(param, row, row, metaSchema, keyColumns, true);
|
||||
}
|
||||
|
||||
stringBuilder.append(sql + ";\n");
|
||||
@ -266,38 +271,71 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
return DataResult.of(stringBuilder.toString());
|
||||
}
|
||||
|
||||
private String getDeleteSql(UpdateSelectResultParam param, List<String> row, MetaData metaSchema) {
|
||||
private List<String> getPrimaryColumns(UpdateSelectResultParam param) {
|
||||
List<Header> headerList = param.getHeaderList();
|
||||
if (CollectionUtils.isEmpty(headerList)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<String> keyColumns = Lists.newArrayList();
|
||||
for (Header header : headerList) {
|
||||
if (header.getPrimaryKey() != null && header.getPrimaryKey()) {
|
||||
keyColumns.add(header.getName());
|
||||
}
|
||||
}
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
private String getDeleteSql(UpdateSelectResultParam param, List<String> row, MetaData metaSchema, List<String> keyColumns) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append("DELETE FROM ").append(param.getTableName()).append("");
|
||||
|
||||
script.append(buildWhere(param.getHeaderList(), row, metaSchema));
|
||||
script.append(buildWhere(param.getHeaderList(), row, metaSchema, keyColumns));
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private String buildWhere(List<Header> headerList, List<String> row, MetaData metaSchema) {
|
||||
private String buildWhere(List<Header> headerList, List<String> row, MetaData metaSchema, List<String> keyColumns) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
script.append(" where ");
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
String oldValue = row.get(i);
|
||||
Header header = headerList.get(i);
|
||||
String value = SqlUtils.getSqlValue(oldValue, header.getDataType());
|
||||
if (value == null) {
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(" is null and ");
|
||||
} else {
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(" = ")
|
||||
.append(value)
|
||||
.append(" and ");
|
||||
if (CollectionUtils.isEmpty(keyColumns)) {
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
String oldValue = row.get(i);
|
||||
Header header = headerList.get(i);
|
||||
String value = SqlUtils.getSqlValue(oldValue, header.getDataType());
|
||||
if (value == null) {
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(" is null and ");
|
||||
} else {
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(" = ")
|
||||
.append(value)
|
||||
.append(" and ");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
String oldValue = row.get(i);
|
||||
Header header = headerList.get(i);
|
||||
String columnName = header.getName();
|
||||
if (keyColumns.contains(columnName)) {
|
||||
String value = SqlUtils.getSqlValue(oldValue, header.getDataType());
|
||||
if (value == null) {
|
||||
script.append(metaSchema.getMetaDataName(columnName))
|
||||
.append(" is null and ");
|
||||
} else {
|
||||
script.append(metaSchema.getMetaDataName(columnName))
|
||||
.append(" = ")
|
||||
.append(value)
|
||||
.append(" and ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script.delete(script.length() - 4, script.length());
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private String getInsertSql(UpdateSelectResultParam param, List<String> row, MetaData metaSchema) {
|
||||
if (CollectionUtils.isEmpty(row)) {
|
||||
if (CollectionUtils.isEmpty(row) || ObjectUtils.allNull(row.toArray())) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder script = new StringBuilder();
|
||||
@ -305,16 +343,21 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
.append(" (");
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
Header header = param.getHeaderList().get(i);
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(",");
|
||||
String newValue = row.get(i);
|
||||
if (newValue != null) {
|
||||
script.append(metaSchema.getMetaDataName(header.getName()))
|
||||
.append(",");
|
||||
}
|
||||
}
|
||||
script.deleteCharAt(script.length() - 1);
|
||||
script.append(") VALUES (");
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
String newValue = row.get(i);
|
||||
Header header = param.getHeaderList().get(i);
|
||||
script.append(SqlUtils.getSqlValue(newValue, header.getDataType()))
|
||||
.append(",");
|
||||
if (newValue != null) {
|
||||
Header header = param.getHeaderList().get(i);
|
||||
script.append(SqlUtils.getSqlValue(newValue, header.getDataType()))
|
||||
.append(",");
|
||||
}
|
||||
}
|
||||
script.deleteCharAt(script.length() - 1);
|
||||
script.append(")");
|
||||
@ -323,7 +366,8 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
}
|
||||
|
||||
|
||||
private String getUpdateSql(UpdateSelectResultParam param, List<String> row, List<String> odlRow, MetaData metaSchema) {
|
||||
private String getUpdateSql(UpdateSelectResultParam param, List<String> row, List<String> odlRow, MetaData metaSchema,
|
||||
List<String> keyColumns, boolean copy) {
|
||||
StringBuilder script = new StringBuilder();
|
||||
if (CollectionUtils.isEmpty(row) || CollectionUtils.isEmpty(odlRow)) {
|
||||
return "";
|
||||
@ -332,7 +376,7 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
for (int i = 1; i < row.size(); i++) {
|
||||
String newValue = row.get(i);
|
||||
String oldValue = odlRow.get(i);
|
||||
if (StringUtils.equals(newValue, oldValue)) {
|
||||
if (StringUtils.equals(newValue, oldValue) && !copy) {
|
||||
continue;
|
||||
}
|
||||
Header header = param.getHeaderList().get(i);
|
||||
@ -343,10 +387,52 @@ public class DlTemplateServiceImpl implements DlTemplateService {
|
||||
.append(",");
|
||||
}
|
||||
script.deleteCharAt(script.length() - 1);
|
||||
script.append(buildWhere(param.getHeaderList(), odlRow, metaSchema));
|
||||
script.append(buildWhere(param.getHeaderList(), odlRow, metaSchema, keyColumns));
|
||||
return script.toString();
|
||||
}
|
||||
|
||||
private List<Header> setColumnInfo(List<Header> headers, String tableName, String schemaName, String databaseName) {
|
||||
TableQueryParam tableQueryParam = new TableQueryParam();
|
||||
tableQueryParam.setTableName(MetaNameUtils.getMetaName(tableName));
|
||||
tableQueryParam.setSchemaName(schemaName);
|
||||
tableQueryParam.setDatabaseName(databaseName);
|
||||
tableQueryParam.setRefresh(true);
|
||||
List<TableColumn> columns = tableService.queryColumns(tableQueryParam);
|
||||
if (CollectionUtils.isEmpty(columns)) {
|
||||
return headers;
|
||||
}
|
||||
Map<String, TableColumn> columnMap = columns.stream().collect(Collectors.toMap(TableColumn::getName, tableColumn -> tableColumn));
|
||||
|
||||
List<TableIndex> tableIndices = tableService.queryIndexes(tableQueryParam);
|
||||
if (!CollectionUtils.isEmpty(tableIndices)) {
|
||||
for (TableIndex tableIndex : tableIndices) {
|
||||
if ("PRIMARY".equalsIgnoreCase(tableIndex.getType())) {
|
||||
List<TableIndexColumn> columnList = tableIndex.getColumnList();
|
||||
if (!CollectionUtils.isEmpty(columnList)) {
|
||||
for (TableIndexColumn tableIndexColumn : columnList) {
|
||||
TableColumn tableColumn = columnMap.get(tableIndexColumn.getColumnName());
|
||||
if (tableColumn != null) {
|
||||
tableColumn.setPrimaryKey(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Header header : headers) {
|
||||
TableColumn tableColumn = columnMap.get(header.getName());
|
||||
if (tableColumn != null) {
|
||||
header.setPrimaryKey(tableColumn.getPrimaryKey());
|
||||
header.setComment(tableColumn.getComment());
|
||||
header.setDefaultValue(tableColumn.getDefaultValue());
|
||||
header.setNullable(tableColumn.getNullable());
|
||||
header.setColumnSize(tableColumn.getColumnSize());
|
||||
header.setDecimalDigits(tableColumn.getDecimalDigits());
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private ExecuteResult execute(String sql, Integer offset, Integer count) {
|
||||
ExecuteResult executeResult;
|
||||
try {
|
||||
|
@ -0,0 +1,26 @@
|
||||
package ai.chat2db.server.domain.core.util;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class MetaNameUtils {
|
||||
|
||||
public static String getMetaName(String tableName) {
|
||||
if(StringUtils.isBlank(tableName)){
|
||||
return tableName;
|
||||
}
|
||||
if(tableName.startsWith("`") && tableName.endsWith("`")){
|
||||
return tableName.substring(1,tableName.length()-1);
|
||||
}
|
||||
if(tableName.startsWith("\"") && tableName.endsWith("\"")){
|
||||
return tableName.substring(1,tableName.length()-1);
|
||||
}
|
||||
if(tableName.startsWith("'") && tableName.endsWith("'")){
|
||||
return tableName.substring(1,tableName.length()-1);
|
||||
}
|
||||
if(tableName.startsWith("[") && tableName.endsWith("]")){
|
||||
return tableName.substring(1,tableName.length()-1);
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
}
|
@ -1,10 +1,6 @@
|
||||
package ai.chat2db.server.tools.common.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@ -189,4 +185,15 @@ public class EasyCollectionUtils {
|
||||
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
|
||||
}
|
||||
|
||||
public static <E> List<E> union(List<? extends E> list1, List<? extends E> list2) {
|
||||
ArrayList<E> result = new ArrayList();
|
||||
if(list1 != null && list1.size()>0) {
|
||||
result.addAll(list1);
|
||||
}
|
||||
if(list2!= null && list2.size()>0) {
|
||||
result.addAll(list2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import ai.chat2db.server.web.api.controller.rdb.request.TriggerDetailRequest;
|
||||
import ai.chat2db.server.web.api.controller.rdb.request.TriggerPageRequest;
|
||||
import ai.chat2db.spi.model.Trigger;
|
||||
import jakarta.validation.Valid;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -25,8 +26,9 @@ public class TriggerController {
|
||||
@GetMapping("/list")
|
||||
public WebPageResult<Trigger> list(@Valid TriggerPageRequest request) {
|
||||
ListResult<Trigger> listResult = triggerService.triggers(request.getDatabaseName(), request.getSchemaName());
|
||||
return WebPageResult.of(listResult.getData(), Long.valueOf(listResult.getData().size()), 1,
|
||||
listResult.getData().size());
|
||||
Long total = CollectionUtils.isNotEmpty(listResult.getData()) ? Long.valueOf(listResult.getData().size()) : 0L;
|
||||
return WebPageResult.of(listResult.getData(), total, 1,
|
||||
listResult.getData().size());
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
|
@ -3,7 +3,7 @@ package ai.chat2db.server.web.api.controller.rdb.request;
|
||||
import ai.chat2db.server.domain.api.param.SelectResultOperation;
|
||||
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 ai.chat2db.spi.model.Header;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
@ -16,7 +16,7 @@ public class SelectResultUpdateRequest extends DataSourceBaseRequest implements
|
||||
/**
|
||||
* 展示头的列表
|
||||
*/
|
||||
private List<HeaderVO> headerList;
|
||||
private List<Header> headerList;
|
||||
|
||||
/**
|
||||
* 修改后数据的列表
|
||||
|
@ -3,6 +3,7 @@ package ai.chat2db.server.web.api.controller.rdb.vo;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import ai.chat2db.spi.model.Header;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -46,7 +47,7 @@ public class ExecuteResultVO {
|
||||
/**
|
||||
* 展示头的列表
|
||||
*/
|
||||
private List<HeaderVO> headerList;
|
||||
private List<Header> headerList;
|
||||
|
||||
/**
|
||||
* 数据的列表
|
||||
|
@ -1,31 +0,0 @@
|
||||
package ai.chat2db.server.web.api.controller.rdb.vo;
|
||||
|
||||
import ai.chat2db.spi.enums.DataTypeEnum;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* 单元格头
|
||||
*
|
||||
* @author Jiaju Zhuang
|
||||
*/
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class HeaderVO {
|
||||
/**
|
||||
* 单元格类型
|
||||
*
|
||||
* @see DataTypeEnum
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
/**
|
||||
* 展示的名字
|
||||
*/
|
||||
private String name;
|
||||
}
|
@ -10,6 +10,7 @@ import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
@ -49,7 +50,11 @@ public class DefaultMetaService implements MetaData {
|
||||
|
||||
@Override
|
||||
public List<Function> functions(Connection connection, String databaseName, String schemaName) {
|
||||
return SQLExecutor.getInstance().functions(connection, StringUtils.isEmpty(databaseName) ? null : databaseName, StringUtils.isEmpty(schemaName) ? null : schemaName);
|
||||
List<Function> functions = SQLExecutor.getInstance().functions(connection, StringUtils.isEmpty(databaseName) ? null : databaseName, StringUtils.isEmpty(schemaName) ? null : schemaName);
|
||||
if(CollectionUtils.isEmpty(functions)){
|
||||
return functions;
|
||||
}
|
||||
return functions.stream().filter(function -> StringUtils.isNotBlank(function.getFunctionName())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -59,7 +64,12 @@ public class DefaultMetaService implements MetaData {
|
||||
|
||||
@Override
|
||||
public List<Procedure> procedures(Connection connection, String databaseName, String schemaName) {
|
||||
return SQLExecutor.getInstance().procedures(connection, StringUtils.isEmpty(databaseName) ? null : databaseName, StringUtils.isEmpty(schemaName) ? null : schemaName);
|
||||
List<Procedure> procedures = SQLExecutor.getInstance().procedures(connection, StringUtils.isEmpty(databaseName) ? null : databaseName, StringUtils.isEmpty(schemaName) ? null : schemaName);
|
||||
|
||||
if(CollectionUtils.isEmpty(procedures)){
|
||||
return procedures;
|
||||
}
|
||||
return procedures.stream().filter(function -> StringUtils.isNotBlank(function.getProcedureName())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,4 +38,6 @@ public class Database implements Serializable {
|
||||
private String charset;
|
||||
|
||||
private String collation;
|
||||
|
||||
private String owner;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import lombok.experimental.SuperBuilder;
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Header {
|
||||
public class Header{
|
||||
/**
|
||||
* 单元格类型
|
||||
*
|
||||
@ -27,4 +27,21 @@ public class Header {
|
||||
* 展示的名字
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
private Boolean primaryKey;
|
||||
|
||||
|
||||
private String comment;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
private Integer autoIncrement;
|
||||
|
||||
private Integer nullable;
|
||||
|
||||
private Integer columnSize;
|
||||
|
||||
private Integer decimalDigits;
|
||||
|
||||
}
|
||||
|
@ -86,8 +86,13 @@ public class Table {
|
||||
|
||||
private String collate;
|
||||
|
||||
|
||||
private Long incrementValue;
|
||||
|
||||
|
||||
private String partition;
|
||||
|
||||
|
||||
private String tablespace;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user