diff --git a/chat2db-client/src/assets/img/databaseImg/snowflake.png b/chat2db-client/src/assets/img/databaseImg/snowflake.png
new file mode 100644
index 000000000..b215e1cb2
Binary files /dev/null and b/chat2db-client/src/assets/img/databaseImg/snowflake.png differ
diff --git a/chat2db-client/src/components/ConnectionEdit/config/dataSource.ts b/chat2db-client/src/components/ConnectionEdit/config/dataSource.ts
index 115aa9403..9f87b9be5 100644
--- a/chat2db-client/src/components/ConnectionEdit/config/dataSource.ts
+++ b/chat2db-client/src/components/ConnectionEdit/config/dataSource.ts
@@ -2076,4 +2076,125 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
extendInfo: [],
type: DatabaseTypeCode.MONGODB
},
+ //SNOWFLAKE
+ {
+ baseInfo: {
+ items: [
+ {
+ defaultValue: '@localhost',
+ inputType: InputType.INPUT,
+ labelNameCN: '名称',
+ labelNameEN: 'Name',
+ name: 'alias',
+ required: true,
+ styles: {
+ width: '100%',
+ }
+ },
+ envItem,
+ {
+ defaultValue: '',
+ inputType: InputType.INPUT,
+ labelNameCN: '主机',
+ labelNameEN: 'Host',
+ name: 'host',
+ required: true,
+ styles: {
+ width: '70%',
+ }
+ },
+ {
+ defaultValue: '443',
+ inputType: InputType.INPUT,
+ labelNameCN: '端口',
+ labelNameEN: 'Port',
+ name: 'port',
+ labelTextAlign: 'right',
+ required: true,
+ styles: {
+ width: '30%',
+ labelWidthEN: '40px',
+ labelWidthCN: '40px',
+ labelAlign: 'right'
+ }
+ },
+ {
+ defaultValue: AuthenticationType.USERANDPASSWORD,
+ inputType: InputType.SELECT,
+ labelNameCN: '身份验证',
+ labelNameEN: 'Authentication',
+ name: 'authenticationType',
+ required: true,
+ selects: [
+ {
+ items: [
+ {
+ defaultValue: 'root',
+ inputType: InputType.INPUT,
+ labelNameCN: '用户名',
+ labelNameEN: 'User',
+ name: 'user',
+ required: true,
+ styles: {
+ width: '100%',
+ }
+ },
+ {
+ defaultValue: '',
+ inputType: InputType.PASSWORD,
+ labelNameCN: '密码',
+ labelNameEN: 'Password',
+ name: 'password',
+ required: true,
+ styles: {
+ width: '100%',
+ }
+ },
+ ],
+ label: 'User&Password',
+ value: AuthenticationType.USERANDPASSWORD,
+ },
+ {
+ label: 'NONE',
+ value: AuthenticationType.NONE,
+ items: [],
+
+ },
+ ],
+ styles: {
+ width: '50%',
+ }
+ },
+ {
+ defaultValue: '',
+ inputType: InputType.INPUT,
+ labelNameCN: '数据库',
+ labelNameEN: 'Database',
+ name: 'database',
+ required: false,
+ styles: {
+ width: '100%',
+ }
+ },
+ {
+ defaultValue: 'jdbc:snowflake://:443',
+ inputType: InputType.INPUT,
+ labelNameCN: 'URL',
+ labelNameEN: 'URL',
+ name: 'url',
+ required: true,
+ styles: {
+ width: '100%',
+ }
+ },
+
+ ],
+ pattern: /jdbc:snowflake:\/\/(.*):(\d+)(\/\?db=(\w+))?/,
+ template: 'jdbc:snowflake://{host}:{port}/?db={database}',
+ //excludes: [OperationColumn.ViewDDL, OperationColumn.CreateTable,OperationColumn.EditTable]
+ },
+ ssh: sshConfig,
+ extendInfo: [],
+ type: DatabaseTypeCode.SNOWFLAKE
+ },
];
diff --git a/chat2db-client/src/constants/common.ts b/chat2db-client/src/constants/common.ts
index b6f2339be..f847b4ffc 100644
--- a/chat2db-client/src/constants/common.ts
+++ b/chat2db-client/src/constants/common.ts
@@ -15,6 +15,7 @@ export enum DatabaseTypeCode {
PRESTO = "PRESTO",
HIVE = "HIVE",
KINGBASE = "KINGBASE",
+ SNOWFLAKE = "SNOWFLAKE",
}
export enum ConsoleStatus {
diff --git a/chat2db-client/src/constants/database.ts b/chat2db-client/src/constants/database.ts
index ba7c3c75c..6a01c22ff 100644
--- a/chat2db-client/src/constants/database.ts
+++ b/chat2db-client/src/constants/database.ts
@@ -2,6 +2,7 @@ import mysqlLogo from '@/assets/img/databaseImg/mysql.png';
import redisLogo from '@/assets/img/databaseImg/redis.png';
import h2Logo from '@/assets/img/databaseImg/h2.png';
import moreDBLogo from '@/assets/img/databaseImg/other.png';
+import snowflakeLogo from '@/assets/img/databaseImg/snowflake.png';
import { IDatabase } from '@/typings';
import { DatabaseTypeCode } from '@/constants'
@@ -118,6 +119,13 @@ export const databaseMap: {
// port: 27017,
icon: '\uec21',
},
+ [DatabaseTypeCode.SNOWFLAKE]: {
+ name: 'Snowflake',
+ img: snowflakeLogo,
+ code: DatabaseTypeCode.SNOWFLAKE,
+ // port: 443,
+ icon: '\uec21',
+ },
// [DatabaseTypeCode.REDIS]: {
// name: 'Redis',
// img: moreDBLogo,
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/pom.xml b/chat2db-server/chat2db-plugins/chat2db-snowflake/pom.xml
new file mode 100644
index 000000000..b45999537
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+
+ ai.chat2db
+ chat2db-plugins
+ ${revision}
+ ../pom.xml
+
+
+
+
+ ai.chat2db
+ chat2db-spi
+
+
+
+ chat2db-snowflake
+
+
+
+ src/main/java
+
+
+ **/*.json
+
+
+
+ src/main/resources
+
+
+
+
\ No newline at end of file
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeDBManage.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeDBManage.java
new file mode 100644
index 000000000..603a77ab4
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeDBManage.java
@@ -0,0 +1,73 @@
+package ai.chat2db.plugin.snowflake;
+
+import ai.chat2db.spi.DBManage;
+import ai.chat2db.spi.jdbc.DefaultDBManage;
+import ai.chat2db.spi.model.KeyValue;
+import ai.chat2db.spi.sql.Chat2DBContext;
+import ai.chat2db.spi.sql.ConnectInfo;
+import ai.chat2db.spi.sql.SQLExecutor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+public class SnowflakeDBManage extends DefaultDBManage implements DBManage {
+
+ @Override
+ public Connection getConnection(ConnectInfo connectInfo) {
+ List extendInfo = connectInfo.getExtendInfo();
+ if (StringUtils.isNotBlank(connectInfo.getDatabaseName())) {
+ KeyValue keyValue = new KeyValue();
+ keyValue.setKey("db");
+ keyValue.setValue(connectInfo.getDatabaseName());
+ extendInfo.add(keyValue);
+ }
+ if (StringUtils.isNotBlank(connectInfo.getSchemaName())) {
+ KeyValue keyValue = new KeyValue();
+ keyValue.setKey("schema");
+ keyValue.setValue(connectInfo.getSchemaName());
+ extendInfo.add(keyValue);
+ }
+ KeyValue keyValue = new KeyValue();
+ keyValue.setKey("JDBC_QUERY_RESULT_FORMAT");
+ keyValue.setValue("JSON");
+ extendInfo.add(keyValue);
+ connectInfo.setExtendInfo(extendInfo);
+ return super.getConnection(connectInfo);
+ }
+
+
+ @Override
+ public void connectDatabase(Connection connection, String database) {
+ if (StringUtils.isEmpty(database)) {
+ return;
+ }
+ ConnectInfo connectInfo = Chat2DBContext.getConnectInfo();
+ if (ObjectUtils.anyNull(connectInfo) || StringUtils.isEmpty(connectInfo.getSchemaName())) {
+ try {
+ SQLExecutor.getInstance().execute(connection, "USE DATABASE \"" + database + "\";");
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ try {
+ SQLExecutor.getInstance().execute(connection, "USE SCHEMA \"" + database + "\"." + connectInfo.getSchemaName() + ";");
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void dropTable(Connection connection, String databaseName, String schemaName, String tableName) {
+ String sql = "DROP TABLE "+ format(tableName);
+ SQLExecutor.getInstance().executeSql(connection,sql, resultSet -> null);
+ }
+
+ public static String format(String tableName) {
+ return "\"" + tableName + "\"";
+ }
+
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeMetaData.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeMetaData.java
new file mode 100644
index 000000000..5baa38e2d
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakeMetaData.java
@@ -0,0 +1,189 @@
+package ai.chat2db.plugin.snowflake;
+
+import ai.chat2db.plugin.snowflake.builder.SnowflakeSqlBuilder;
+import ai.chat2db.plugin.snowflake.type.*;
+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 ai.chat2db.spi.util.SortUtils;
+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;
+
+public class SnowflakeMetaData extends DefaultMetaService implements MetaData {
+
+
+ private List systemSchemas = Arrays.asList("INFORMATION_SCHEMA", "PUBLIC", "SCHEMA");
+
+ @Override
+ public List schemas(Connection connection, String databaseName) {
+ List schemas = SQLExecutor.getInstance().schemas(connection, databaseName, null);
+ return SortUtils.sortSchema(schemas, systemSchemas);
+ }
+
+ 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_CATALOG = '%s' AND 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, schemaName , 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").substring(resultSet.getString("DEFINITION").indexOf("as")+3));
+ }
+ return table;
+ });
+ }
+
+
+ @Override
+ public TableMeta getTableMeta(String databaseName, String schemaName, String tableName) {
+ return TableMeta.builder()
+ .columnTypes(SnowflakeColumnTypeEnum.getTypes())
+ .charsets(SnowflakeCharsetEnum.getCharsets())
+ .collations(SnowflakeCollationEnum.getCollations())
+ .indexTypes(SnowflakeIndexTypeEnum.getIndexTypes())
+ .defaultValues(SnowflakeDefaultValueEnum.getDefaultValues())
+ .build();
+ }
+
+ @Override
+ public SqlBuilder getSqlBuilder() {
+ return new SnowflakeSqlBuilder();
+ }
+
+ @Override
+ public String getMetaDataName(String... names) {
+ return Arrays.stream(names).filter(name -> StringUtils.isNotBlank(name)).map(name -> "\"" + name + "\"").collect(Collectors.joining("."));
+ }
+
+ @Override
+ public List indexes(Connection connection, String databaseName, String schemaName, String tableName) {
+ // 目前仅能查看主键
+ StringBuilder queryBuf = new StringBuilder("SHOW PRIMARY KEYS in ");
+ queryBuf.append("\"").append(tableName).append("\"");
+ return SQLExecutor.getInstance().execute(connection, queryBuf.toString(), resultSet -> {
+ LinkedHashMap map = new LinkedHashMap();
+ while (resultSet.next()) {
+ String keyName = resultSet.getString("constraint_name");
+ TableIndex tableIndex = map.get(keyName);
+ if (tableIndex != null) {
+ List 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(!resultSet.getBoolean("Non_unique"));
+ index.setType(SnowflakeIndexTypeEnum.PRIMARY_KEY.getName());
+ index.setComment(resultSet.getString("comment"));
+ List tableIndexColumns = new ArrayList<>();
+ tableIndexColumns.add(getTableIndexColumn(resultSet));
+ index.setColumnList(tableIndexColumns);
+ if ("PRIMARY".equalsIgnoreCase(keyName)) {
+ index.setType(SnowflakeIndexTypeEnum.PRIMARY_KEY.getName());
+ }
+ map.put(keyName, index);
+ }
+ }
+ return map.values().stream().collect(Collectors.toList());
+ });
+ }
+
+ private TableIndexColumn getTableIndexColumn(ResultSet resultSet) throws SQLException {
+ TableIndexColumn tableIndexColumn = new TableIndexColumn();
+ tableIndexColumn.setColumnName(resultSet.getString("column_name"));
+ tableIndexColumn.setOrdinalPosition(resultSet.getShort("key_sequence"));
+ //tableIndexColumn.setCollation(resultSet.getString("Collation"));
+ //tableIndexColumn.setCardinality(resultSet.getLong("Cardinality"));
+ //tableIndexColumn.setSubPart(resultSet.getLong("Sub_part"));
+ /*String collation = resultSet.getString("Collation");
+ if ("a".equalsIgnoreCase(collation)) {
+ tableIndexColumn.setAscOrDesc("ASC");
+ } else if ("d".equalsIgnoreCase(collation)) {
+ tableIndexColumn.setAscOrDesc("DESC");
+ }*/
+ return tableIndexColumn;
+ }
+
+ @Override
+ public String tableDDL(Connection connection, @NotEmpty String databaseName, String schemaName,
+ @NotEmpty String tableName) {
+ // 需要后续自己实现。目前没有办法直接获取建表语句。
+ return "";
+ /*String sql = "SHOW CREATE TABLE " + format(schemaName) + "."
+ + format(tableName);
+ return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
+ if (resultSet.next()) {
+ return resultSet.getString("Create Table");
+ }
+ return null;
+ });*/
+ }
+
+ private static String OBJECT_SQL
+ = "SHOW USER FUNCTIONS IN SCHEMA \"%s\"";
+
+ @Override
+ public List functions(Connection connection, String databaseName, String schemaName) {
+ List functions = new ArrayList<>();
+ String sql = String.format(OBJECT_SQL, schemaName);
+ return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
+ while (resultSet.next()) {
+ Function function = new Function();
+ function.setDatabaseName(databaseName);
+ function.setSchemaName(schemaName);
+ function.setFunctionName(resultSet.getString("name"));
+ functions.add(function);
+ }
+ return functions;
+ });
+ }
+
+ private static String ROUTINES_SQL
+ =
+ "SELECT FUNCTION_NAME, FUNCTION_DEFINITION, COMMENT " +
+ "FROM INFORMATION_SCHEMA.FUNCTIONS " +
+ "WHERE FUNCTION_SCHEMA = '%s' AND FUNCTION_NAME = '%s';";
+ @Override
+ public Function function(Connection connection, @NotEmpty String databaseName, String schemaName,
+ String functionName) {
+
+ String sql = String.format(ROUTINES_SQL, schemaName, 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("FUNCTION_NAME"));
+ function.setRemarks(resultSet.getString("COMMENT"));
+ function.setFunctionBody(resultSet.getString("FUNCTION_DEFINITION"));
+ }
+ return function;
+ });
+
+ }
+
+ public static String format(String tableName) {
+ return "\"" + tableName + "\"";
+ }
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakePlugin.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakePlugin.java
new file mode 100644
index 000000000..79af0449e
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/SnowflakePlugin.java
@@ -0,0 +1,25 @@
+package ai.chat2db.plugin.snowflake;
+
+import ai.chat2db.spi.DBManage;
+import ai.chat2db.spi.MetaData;
+
+import ai.chat2db.spi.Plugin;
+import ai.chat2db.spi.config.DBConfig;
+import ai.chat2db.spi.util.FileUtils;
+
+public class SnowflakePlugin implements Plugin {
+ @Override
+ public DBConfig getDBConfig() {
+ return FileUtils.readJsonValue(this.getClass(),"snowflake.json", DBConfig.class);
+ }
+
+ @Override
+ public MetaData getMetaData() {
+ return new SnowflakeMetaData();
+ }
+
+ @Override
+ public DBManage getDBManage() {
+ return new SnowflakeDBManage();
+ }
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/builder/SnowflakeSqlBuilder.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/builder/SnowflakeSqlBuilder.java
new file mode 100644
index 000000000..0bc6f301b
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/builder/SnowflakeSqlBuilder.java
@@ -0,0 +1,115 @@
+package ai.chat2db.plugin.snowflake.builder;
+import ai.chat2db.plugin.snowflake.type.SnowflakeColumnTypeEnum;
+import ai.chat2db.plugin.snowflake.type.SnowflakeIndexTypeEnum;
+import ai.chat2db.spi.SqlBuilder;
+import ai.chat2db.spi.jdbc.DefaultSqlBuilder;
+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 SnowflakeSqlBuilder extends DefaultSqlBuilder implements SqlBuilder {
+
+ @Override
+ public String buildCreateTableSql(Table table){
+ StringBuilder script = new StringBuilder();
+ script.append("CREATE TABLE ");
+ if (StringUtils.isNotBlank(table.getSchemaName())) {
+ script.append(table.getSchemaName()).append(".");
+ }
+ script.append("\"").append(table.getName()).append("\"").append(" (").append("\n");
+
+ // append column
+ for (TableColumn column : table.getColumnList()) {
+ if (StringUtils.isBlank(column.getName()) || StringUtils.isBlank(column.getColumnType())) {
+ continue;
+ }
+ SnowflakeColumnTypeEnum typeEnum = SnowflakeColumnTypeEnum.getByType(column.getColumnType());
+ script.append("\t").append(typeEnum.buildCreateColumnSql(column)).append(",\n");
+ }
+
+ // append primary key and index
+ for (TableIndex tableIndex : table.getIndexList()) {
+ if (StringUtils.isBlank(tableIndex.getName()) || StringUtils.isBlank(tableIndex.getType())) {
+ continue;
+ }
+ SnowflakeIndexTypeEnum mysqlIndexTypeEnum = SnowflakeIndexTypeEnum.getByType(tableIndex.getType());
+ script.append("\t").append("").append(mysqlIndexTypeEnum.buildIndexScript(tableIndex)).append(",\n");
+ }
+
+ script = new StringBuilder(script.substring(0, script.length() - 2));
+ script.append("\n)");
+
+
+ if (StringUtils.isNotBlank(table.getEngine())) {
+ script.append(" ENGINE=").append(table.getEngine());
+ }
+
+ if (StringUtils.isNotBlank(table.getCharset())) {
+ script.append(" DEFAULT CHARACTER SET=").append(table.getCharset());
+ }
+
+ if (StringUtils.isNotBlank(table.getCollate())) {
+ script.append(" COLLATE=").append(table.getCollate());
+ }
+
+ if (table.getIncrementValue() != null) {
+ script.append(" AUTO_INCREMENT=").append(table.getIncrementValue());
+ }
+
+ if (StringUtils.isNotBlank(table.getComment())) {
+ script.append(" COMMENT='").append(table.getComment()).append("'");
+ }
+
+ if (StringUtils.isNotBlank(table.getPartition())) {
+ script.append(" \n").append(table.getPartition());
+ }
+ script.append(";");
+
+ return script.toString();
+ }
+
+ @Override
+ public String buildModifyTaleSql(Table oldTable, Table newTable) {
+ StringBuilder script = new StringBuilder();
+ script.append("ALTER TABLE ");
+ script.append("\"").append(oldTable.getName()).append("\"").append("\n");
+ boolean isChangeTableName = false;
+ if (!StringUtils.equalsIgnoreCase(oldTable.getName(), newTable.getName())) {
+ script.append("RENAME TO ").append("\"").append(newTable.getName()).append("\"").append(";\n");
+ isChangeTableName = true;
+ }
+ if (!StringUtils.equalsIgnoreCase(oldTable.getComment(), newTable.getComment())) {
+ if (isChangeTableName) {
+ script.append("ALTER TABLE ");
+ script.append("\"").append(newTable.getName()).append("\"").append("\n");
+ script.append("\t").append("set COMMENT=").append("'").append(newTable.getComment()).append("'").append(",\n");
+ } else {
+ script.append("\t").append("set COMMENT=").append("'").append(newTable.getComment()).append("'").append(",\n");
+ }
+ }
+ if (oldTable.getIncrementValue() != newTable.getIncrementValue()) {
+ script.append("\t").append("AUTO_INCREMENT=").append(newTable.getIncrementValue()).append(",\n");
+ }
+
+ // append modify column
+ for (TableColumn tableColumn : newTable.getColumnList()) {
+ if (StringUtils.isNotBlank(tableColumn.getEditStatus()) && StringUtils.isNotBlank(tableColumn.getColumnType()) && StringUtils.isNotBlank(tableColumn.getName())) {
+ SnowflakeColumnTypeEnum typeEnum = SnowflakeColumnTypeEnum.getByType(tableColumn.getColumnType());
+ script.append("\t").append(typeEnum.buildModifyColumn(tableColumn)).append(",\n");
+ }
+ }
+
+ // append reorder column
+ //script.append(buildGenerateReorderColumnSql(oldTable, newTable));
+
+ if (script.length() > 2) {
+ script = new StringBuilder(script.substring(0, script.length() - 2));
+ script.append(";");
+ }
+
+ return script.toString();
+ }
+
+}
+
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/snowflake.json b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/snowflake.json
new file mode 100644
index 000000000..82aea66c0
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/snowflake.json
@@ -0,0 +1,18 @@
+{
+ "dbType": "SNOWFLAKE",
+ "supportDatabase": true,
+ "supportSchema": false,
+ "driverConfigList": [
+ {
+ "url": "jdbc:snowflake://localhost:443/",
+ "custom": false,
+ "defaultDriver": true,
+ "downloadJdbcDriverUrls": [
+ "https://oss.sqlgpt.cn/lib/snowflake-jdbc-3.15.0.jar"
+ ],
+ "jdbcDriver": "snowflake-jdbc-3.15.0.jar",
+ "jdbcDriverClass": "net.snowflake.client.jdbc.SnowflakeDriver"
+ }
+ ],
+ "name": "Snowflake"
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCharsetEnum.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCharsetEnum.java
new file mode 100644
index 000000000..71ef84870
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCharsetEnum.java
@@ -0,0 +1,26 @@
+package ai.chat2db.plugin.snowflake.type;
+
+import ai.chat2db.spi.model.Charset;
+
+import java.util.Arrays;
+import java.util.List;
+
+public enum SnowflakeCharsetEnum {
+
+ UTF8("utf8", "utf8_general_ci"),
+ ;
+
+ private Charset charset;
+ SnowflakeCharsetEnum(String charsetName, String defaultCollationName) {
+ this.charset = new Charset(charsetName, defaultCollationName);
+ }
+
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ public static List getCharsets() {
+ return Arrays.stream(SnowflakeCharsetEnum.values()).map(SnowflakeCharsetEnum::getCharset).collect(java.util.stream.Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCollationEnum.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCollationEnum.java
new file mode 100644
index 000000000..604378840
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeCollationEnum.java
@@ -0,0 +1,31 @@
+package ai.chat2db.plugin.snowflake.type;
+
+import ai.chat2db.spi.model.Collation;
+
+import java.util.Arrays;
+import java.util.List;
+
+public enum SnowflakeCollationEnum {
+
+ BINARY("BINARY"),
+
+ CASE_INSENSITIVE("CASE_INSENSITIVE"),
+
+ CASE_SENSITIVE("CASE_SENSITIVE"),
+ ;
+ private Collation collation;
+
+ SnowflakeCollationEnum(String collationName) {
+ this.collation = new Collation(collationName);
+ }
+
+ public Collation getCollation() {
+ return collation;
+ }
+
+
+ public static List getCollations() {
+ return Arrays.asList(SnowflakeCollationEnum.values()).stream().map(SnowflakeCollationEnum::getCollation).collect(java.util.stream.Collectors.toList());
+ }
+
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeColumnTypeEnum.java
new file mode 100644
index 000000000..0b12a09f3
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeColumnTypeEnum.java
@@ -0,0 +1,237 @@
+package ai.chat2db.plugin.snowflake.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 SnowflakeColumnTypeEnum implements ColumnBuilder {
+
+ NUMBER("NUMBER", true, true, true, true, false, false, true, true, false, false),
+ DECIMAL("DECIMAL", true, true, true, true, false, false, true, true, false, false),
+ NUMERIC("NUMERIC", true, true, true, true, false, false, true, true, false, false),
+ INT("INT", false, false, true, true, false, false, true, true, false, false),
+ INTEGER("INTEGER", false, false, true, true, false, false, true, true, false, false),
+ BIGINT("BIGINT", false, false, true, true, false, false, true, true, false, false),
+ SMALLINT("SMALLINT", false, false, true, true, false, false, true, true, false, false),
+ TINYINT("TINYINT", false, false, true, true, false, false, true, true, false, false),
+ BYTEINT("BYTEINT", false, false, true, true, false, false, true, true, false, false),
+ FLOAT("FLOAT", true, true, true, true, false, false, true, true, false, false),
+ DOUBLE("DOUBLE", true, true, true, true, false, false, true, true, false, false),
+
+ VARCHAR("VARCHAR", true, false, true, false, true, true, true, true, false, false),
+ CHAR("CHAR", true, false, true, false, true, true, true, true, false, false),
+ STRING("STRING", true, false, true, false, true, true, true, true, false, false),
+ TEXT("TEXT", true, false, true, false, true, true, true, true, false, false),
+ BINARY("BINARY", true, false, true, false, true, true, true, true, false, false),
+ VARBINARY("VARBINARY", true, false, true, false, true, true, true, true, false, false),
+
+ BOOLEAN("BOOLEAN", false, false, true, false, false, false, true, true, false, false),
+
+ DATE("DATE", false, false, true, false, false, false, true, true, false, false),
+ DATETIME("DATETIME", true, false, true, false, false, false, true, true, true, false),
+ TIME("TIME", true, false, true, false, false, false, true, true, false, false),
+ TIMESTAMP("TIMESTAMP", true, false, true, false, false, false, true, true, true, false),
+ TIMESTAMP_LTZ("TIMESTAMPLTZ", true, false, true, false, false, false, true, true, true, false),
+ TIMESTAMP_NTZ("TIMESTAMPNTZ", true, false, true, false, false, false, true, true, true, false),
+ TIMESTAMP_TZ("TIMESTAMPTZ", true, false, true, false, false, false, true, true, true, false),
+ VARIANT("VARIANT", true, false, true, false, false, false, true, true, false, false),
+ OBJECT("OBJECT", true, false, true, false, false, false, true, true, false, false),
+ ARRAY("ARRAY", true, false, true, false, false, false, true, true, false, false),
+ GEOGRAPHY("GEOGRAPHY", true, false, true, false, false, false, true, true, false, false),
+
+ ;
+
+ private ColumnType columnType;
+
+ public static SnowflakeColumnTypeEnum getByType(String dataType) {
+ return COLUMN_TYPE_MAP.get(dataType.toUpperCase());
+ }
+
+ public ColumnType getColumnType() {
+ return columnType;
+ }
+
+ SnowflakeColumnTypeEnum(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);
+ }
+
+ private static Map COLUMN_TYPE_MAP = Maps.newHashMap();
+
+ static {
+ for (SnowflakeColumnTypeEnum value : SnowflakeColumnTypeEnum.values()) {
+ COLUMN_TYPE_MAP.put(value.getColumnType().getTypeName(), value);
+ }
+ }
+ @Override
+ public String buildCreateColumnSql(TableColumn column) {
+
+ SnowflakeColumnTypeEnum 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(" ");
+
+ script.append(buildAutoIncrement(column,type)).append(" ");
+
+ script.append(buildComment(column,type)).append(" ");
+
+ return script.toString();
+ }
+
+ @Override
+ public String buildModifyColumn(TableColumn tableColumn) {
+ if (EditStatus.DELETE.name().equals(tableColumn.getEditStatus())) {
+ return StringUtils.join("DROP COLUMN ", tableColumn.getName());
+ }
+ if (EditStatus.ADD.name().equals(tableColumn.getEditStatus())) {
+ return StringUtils.join("ADD COLUMN ", buildCreateColumnSql(tableColumn));
+ }
+ if (EditStatus.MODIFY.name().equals(tableColumn.getEditStatus())) {
+ if (!StringUtils.equalsIgnoreCase(tableColumn.getOldName(), tableColumn.getName())) {
+ return StringUtils.join("CHANGE COLUMN ", tableColumn.getOldName(), " ", buildCreateColumnSql(tableColumn));
+ } else {
+ return StringUtils.join("MODIFY COLUMN ", buildCreateColumnSql(tableColumn));
+ }
+ }
+ return "";
+ }
+
+ private String buildDataType(TableColumn column, SnowflakeColumnTypeEnum type) {
+ String columnType = type.columnType.getTypeName();
+ if (EditStatus.MODIFY.name().equals(column.getEditStatus())
+ && StringUtils.equalsIgnoreCase(column.getOldColumn().getTableName(), column.getTableName())
+ && column.getOldColumn().getColumnSize().equals(column.getColumnSize())
+ && column.getOldColumn().getDecimalDigits().equals(column.getDecimalDigits())) {
+ return "";
+ }
+ if (Arrays.asList(BINARY, VARBINARY, VARCHAR, CHAR, STRING, TEXT).contains(type)) {
+ if (column.getColumnSize() == null || column.getColumnSize() == 0){
+ return columnType;
+ } else {
+ return StringUtils.join(columnType, "(", column.getColumnSize(), ")");
+ }
+ }
+
+ if (Arrays.asList(DATE, TIME, DATETIME, TIMESTAMP, TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_LTZ).contains(type)) {
+ if (column.getColumnSize() == null || column.getColumnSize() == 0) {
+ return columnType;
+ } else {
+ return StringUtils.join(columnType, "(", column.getColumnSize(), ")");
+ }
+ }
+
+ if (Arrays.asList(DECIMAL, FLOAT, DOUBLE,TINYINT, INT, NUMBER, NUMERIC, INTEGER, BIGINT, SMALLINT, BYTEINT).contains(type)) {
+ if (column.getColumnSize() == null || column.getDecimalDigits() == null) {
+ return columnType;
+ }
+ if (column.getColumnSize() != null && column.getDecimalDigits() == null) {
+ return StringUtils.join(columnType, "(", column.getColumnSize() + ")");
+ }
+ if (column.getColumnSize() != null && column.getDecimalDigits() != null) {
+ return StringUtils.join(columnType, "(", column.getColumnSize() + "," + column.getDecimalDigits() + ")");
+ }
+ }
+
+ return columnType;
+ }
+
+ private String buildCollation(TableColumn column, SnowflakeColumnTypeEnum type) {
+ if(!type.getColumnType().isSupportCollation() || StringUtils.isEmpty(column.getCollationName())){
+ return "";
+ }
+ return StringUtils.join("COLLATE ", "'", column.getCollationName(), "'");
+ }
+
+ private String buildNullable(TableColumn column, SnowflakeColumnTypeEnum type) {
+ if(!type.getColumnType().isSupportNullable()){
+ return "";
+ }
+ if (EditStatus.MODIFY.name().equals(column.getEditStatus()) && !column.getNullable().equals(column.getOldColumn().getNullable())) {
+ if (column.getNullable()!=null && 1==column.getNullable()) {
+ return "DROP NOT NULL";
+ } else {
+ return "NOT NULL";
+ }
+ } else if (EditStatus.ADD.name().equals(column.getEditStatus())) {
+ if (column.getNullable()!=null && 1==column.getNullable()) {
+ return "";
+ } else {
+ return "NOT NULL";
+ }
+ }
+ return "";
+ }
+
+ private String buildDefaultValue(TableColumn column, SnowflakeColumnTypeEnum type) {
+ if(!type.getColumnType().isSupportDefaultValue() || StringUtils.isEmpty(column.getDefaultValue())){
+ return "";
+ }
+
+ if("EMPTY_STRING".equalsIgnoreCase(column.getDefaultValue().trim())){
+ return StringUtils.join("SET DEFAULT ''");
+ }
+
+ if("NULL".equalsIgnoreCase(column.getDefaultValue().trim())){
+ return StringUtils.join("SET DEFAULT NULL");
+ }
+
+ if(Arrays.asList(CHAR,VARCHAR,BINARY,VARBINARY).contains(type)){
+ return StringUtils.join("SET DEFAULT '",column.getDefaultValue(),"'");
+ }
+
+ if(Arrays.asList(DATE,TIME).contains(type)){
+ return StringUtils.join("SET DEFAULT '",column.getDefaultValue(),"'");
+ }
+
+ if(Arrays.asList(DATETIME,TIMESTAMP).contains(type)){
+ if("CURRENT_TIMESTAMP".equalsIgnoreCase(column.getDefaultValue().trim())){
+ return StringUtils.join("SET DEFAULT ",column.getDefaultValue());
+ }
+ return StringUtils.join("SET DEFAULT '",column.getDefaultValue(),"'");
+ }
+
+ return StringUtils.join("SET DEFAULT ",column.getDefaultValue());
+ }
+
+ private String buildAutoIncrement(TableColumn column, SnowflakeColumnTypeEnum type) {
+ if(!type.getColumnType().isSupportAutoIncrement()){
+ return "";
+ }
+ if (column.getAutoIncrement() != null && column.getAutoIncrement()) {
+ return "identity";
+ }
+ return "";
+ }
+
+ private String buildComment(TableColumn column, SnowflakeColumnTypeEnum type) {
+ if(!type.columnType.isSupportComments() || StringUtils.isEmpty(column.getComment())){
+ return "";
+ }
+ return StringUtils.join("COMMENT '",column.getComment(),"'");
+ }
+
+ public static List getTypes(){
+ return Arrays.stream(SnowflakeColumnTypeEnum.values()).map(columnTypeEnum ->
+ columnTypeEnum.getColumnType()
+ ).toList();
+ }
+
+
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeDefaultValueEnum.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeDefaultValueEnum.java
new file mode 100644
index 000000000..2e1279107
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeDefaultValueEnum.java
@@ -0,0 +1,30 @@
+package ai.chat2db.plugin.snowflake.type;
+
+import ai.chat2db.spi.model.DefaultValue;
+
+import java.util.Arrays;
+import java.util.List;
+
+public enum SnowflakeDefaultValueEnum {
+
+
+ NULL("NULL"),
+ CURRENT_DATE("CURRENT_DATE"),
+ CURRENT_TIMESTAMP("CURRENT_TIMESTAMP"),
+ ;
+ private DefaultValue defaultValue;
+
+ SnowflakeDefaultValueEnum(String defaultValue) {
+ this.defaultValue = new DefaultValue(defaultValue);
+ }
+
+
+ public DefaultValue getDefaultValue() {
+ return defaultValue;
+ }
+
+ public static List getDefaultValues() {
+ return Arrays.stream(SnowflakeDefaultValueEnum.values()).map(SnowflakeDefaultValueEnum::getDefaultValue).collect(java.util.stream.Collectors.toList());
+ }
+
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeIndexTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeIndexTypeEnum.java
new file mode 100644
index 000000000..e93bb1f42
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/java/ai/chat2db/plugin/snowflake/type/SnowflakeIndexTypeEnum.java
@@ -0,0 +1,133 @@
+package ai.chat2db.plugin.snowflake.type;
+
+import ai.chat2db.spi.enums.EditStatus;
+import ai.chat2db.spi.model.IndexType;
+import ai.chat2db.spi.model.TableIndex;
+import ai.chat2db.spi.model.TableIndexColumn;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.List;
+
+public enum SnowflakeIndexTypeEnum {
+
+ PRIMARY_KEY("Primary", "PRIMARY KEY"),
+
+ NORMAL("Normal", "INDEX"),
+
+ UNIQUE("Unique", "UNIQUE INDEX"),
+
+ FULLTEXT("Fulltext", "FULLTEXT INDEX"),
+
+ SPATIAL("Spatial", "SPATIAL INDEX");
+
+ public String getName() {
+ return name;
+ }
+
+ private String name;
+
+
+ public String getKeyword() {
+ return keyword;
+ }
+
+ private String keyword;
+
+ public IndexType getIndexType() {
+ return indexType;
+ }
+
+ public void setIndexType(IndexType indexType) {
+ this.indexType = indexType;
+ }
+
+ private IndexType indexType;
+
+ SnowflakeIndexTypeEnum(String name, String keyword) {
+ this.name = name;
+ this.keyword = keyword;
+ this.indexType = new IndexType(name);
+ }
+
+
+ public static SnowflakeIndexTypeEnum getByType(String type) {
+ for (SnowflakeIndexTypeEnum value : SnowflakeIndexTypeEnum.values()) {
+ if (value.name.equalsIgnoreCase(type)) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ public String buildIndexScript(TableIndex tableIndex) {
+ StringBuilder script = new StringBuilder();
+
+ script.append(keyword).append(" ");
+
+ script.append(buildIndexName(tableIndex)).append(" ");
+
+ script.append(buildIndexColumn(tableIndex)).append(" ");
+
+ script.append(buildIndexComment(tableIndex)).append(" ");
+
+ return script.toString();
+ }
+
+ private String buildIndexComment(TableIndex tableIndex) {
+ if(StringUtils.isBlank(tableIndex.getComment())){
+ return "";
+ }else {
+ return StringUtils.join("COMMENT '",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("\"");
+ if (!StringUtils.isBlank(column.getAscOrDesc()) && !PRIMARY_KEY.equals(this)) {
+ script.append(" ").append(column.getAscOrDesc());
+ }
+ script.append(",");
+ }
+ }
+ script.deleteCharAt(script.length() - 1);
+ script.append(")");
+ return script.toString();
+ }
+
+ private String buildIndexName(TableIndex tableIndex) {
+ if(this.equals(PRIMARY_KEY)){
+ return "";
+ }else {
+ 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", "ADD ", buildIndexScript(tableIndex));
+ }
+ if (EditStatus.ADD.name().equals(tableIndex.getEditStatus())) {
+ return StringUtils.join("ADD ", buildIndexScript(tableIndex));
+ }
+ return "";
+ }
+
+ private String buildDropIndex(TableIndex tableIndex) {
+ if (SnowflakeIndexTypeEnum.PRIMARY_KEY.getName().equals(tableIndex.getType())) {
+ return StringUtils.join("DROP PRIMARY KEY");
+ }
+ return StringUtils.join("DROP INDEX \"", tableIndex.getOldName(),"\"");
+ }
+ public static List getIndexTypes() {
+ return Arrays.asList(SnowflakeIndexTypeEnum.values()).stream().map(SnowflakeIndexTypeEnum::getIndexType).collect(java.util.stream.Collectors.toList());
+ }
+}
diff --git a/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/resources/META-INF/services/ai.chat2db.spi.Plugin b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/resources/META-INF/services/ai.chat2db.spi.Plugin
new file mode 100644
index 000000000..69eb8df57
--- /dev/null
+++ b/chat2db-server/chat2db-plugins/chat2db-snowflake/src/main/resources/META-INF/services/ai.chat2db.spi.Plugin
@@ -0,0 +1 @@
+ai.chat2db.plugin.snowflake.SnowflakePlugin
\ No newline at end of file
diff --git a/chat2db-server/chat2db-plugins/pom.xml b/chat2db-server/chat2db-plugins/pom.xml
index d058b04e7..6c1fc3ca1 100644
--- a/chat2db-server/chat2db-plugins/pom.xml
+++ b/chat2db-server/chat2db-plugins/pom.xml
@@ -30,6 +30,7 @@
chat2db-hive
chat2db-redis
chat2db-kingbase
+ chat2db-snowflake
\ No newline at end of file
diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/pom.xml b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/pom.xml
index ce19bc340..6846396b3 100644
--- a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/pom.xml
+++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/pom.xml
@@ -126,5 +126,10 @@
chat2db-sqlserver
${revision}
+
+ ai.chat2db
+ chat2db-snowflake
+ ${revision}
+
diff --git a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/DlTemplateServiceImpl.java b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/DlTemplateServiceImpl.java
index 3e6aff9e3..1dbd093a5 100644
--- a/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/DlTemplateServiceImpl.java
+++ b/chat2db-server/chat2db-server-domain/chat2db-server-domain-core/src/main/java/ai/chat2db/server/domain/core/impl/DlTemplateServiceImpl.java
@@ -145,7 +145,9 @@ private ExecuteResult executeSQL(String originalSql, DbType dbType, DlExecutePar
String sqlType = SqlTypeEnum.UNKNOWN.getCode();
// 解析sql
String type = Chat2DBContext.getConnectInfo().getDbType();
- boolean supportDruid = !DataSourceTypeEnum.MONGODB.getCode().equals(type);
+ //boolean supportDruid = !DataSourceTypeEnum.MONGODB.getCode().equals(type);
+ boolean supportDruid = !Arrays.asList(DataSourceTypeEnum.MONGODB.getCode(), DataSourceTypeEnum.SNOEFLAKE.getCode()).contains(type);
+
// 解析sql分页
SQLStatement sqlStatement = null;
if (supportDruid) {
diff --git a/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/enums/DataSourceTypeEnum.java b/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/enums/DataSourceTypeEnum.java
index 7a9cbcc64..6df20198b 100644
--- a/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/enums/DataSourceTypeEnum.java
+++ b/chat2db-server/chat2db-server-tools/chat2db-server-tools-base/src/main/java/ai/chat2db/server/tools/base/enums/DataSourceTypeEnum.java
@@ -26,6 +26,11 @@ public enum DataSourceTypeEnum implements BaseEnum {
*/
MONGODB("mongo数据库连接"),
+ /**
+ * snowflake数据库连接
+ */
+ SNOEFLAKE("snowflake数据库连接"),
+
;
final String description;