diff --git a/common/src/main/java/com/tencent/supersonic/common/pojo/ItemDateResp.java b/common/src/main/java/com/tencent/supersonic/common/pojo/ItemDateResp.java index 256c08468..4b1ec2eba 100644 --- a/common/src/main/java/com/tencent/supersonic/common/pojo/ItemDateResp.java +++ b/common/src/main/java/com/tencent/supersonic/common/pojo/ItemDateResp.java @@ -1,15 +1,10 @@ package com.tencent.supersonic.common.pojo; -import java.util.ArrayList; import java.util.List; import lombok.AllArgsConstructor; import lombok.Data; import lombok.ToString; -/** - * @author: kanedai - * @date: 2023/3/29 - */ @Data @AllArgsConstructor @ToString @@ -19,5 +14,5 @@ public class ItemDateResp { private String startDate; private String endDate; private String datePeriod; - private List unavailableDateList = new ArrayList<>(); + private List unavailableDateList; } \ No newline at end of file diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/DataType.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/DataType.java index 099109369..ca7fe9f8a 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/DataType.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/DataType.java @@ -40,7 +40,9 @@ public enum DataType { IMPALA("impala", "impala", "com.cloudera.impala.jdbc41.Driver", "", "", "'", "'"), - TDENGINE("TAOS", "TAOS", "com.taosdata.jdbc.TSDBDriver", "'", "'", "\"", "\""); + TDENGINE("TAOS", "TAOS", "com.taosdata.jdbc.TSDBDriver", "'", "'", "\"", "\""), + + POSTGRESQL("postgresql", "postgresql", "org.postgresql.Driver", "'", "'", "\"", "\""); private String feature; private String desc; diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/EngineType.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/EngineType.java index 563b5ab98..293d5d397 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/EngineType.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/enums/EngineType.java @@ -8,7 +8,8 @@ public enum EngineType { DORIS(2, "doris"), CLICKHOUSE(3, "clickhouse"), KAFKA(4, "kafka"), - H2(5, "h2"); + H2(5, "h2"), + POSTGRESQL(6, "postgresql"); private Integer code; diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/request/DatabaseReq.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/request/DatabaseReq.java index 1f13a88be..55076f97d 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/request/DatabaseReq.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/request/DatabaseReq.java @@ -30,6 +30,7 @@ public class DatabaseReq { private String description; + private String schema; private String url; private List admins = Lists.newArrayList(); diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/response/DatabaseResp.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/response/DatabaseResp.java index eac9eb903..a1e87de2c 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/response/DatabaseResp.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/response/DatabaseResp.java @@ -40,6 +40,8 @@ public class DatabaseResp extends RecordInfo { private String version; + private String schema; + private boolean hasPermission = false; private boolean hasUsePermission = false; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java index ee93047d7..d1e0734c4 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java @@ -15,6 +15,7 @@ public class DbAdaptorFactory { dbAdaptorMap.put(EngineType.CLICKHOUSE.getName(), new ClickHouseAdaptor()); dbAdaptorMap.put(EngineType.MYSQL.getName(), new MysqlAdaptor()); dbAdaptorMap.put(EngineType.H2.getName(), new H2Adaptor()); + dbAdaptorMap.put(EngineType.POSTGRESQL.getName(), new PostgresqlAdaptor()); } public static DbAdaptor getEngineAdaptor(String engineType) { diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java new file mode 100644 index 000000000..f9cd19f00 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java @@ -0,0 +1,59 @@ +package com.tencent.supersonic.headless.core.adaptor.db; + +import com.tencent.supersonic.common.pojo.Constants; +import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; +import com.tencent.supersonic.common.util.jsqlparser.SqlParserReplaceHelper; +import java.util.HashMap; +import java.util.Map; + +public class PostgresqlAdaptor extends DbAdaptor { + + @Override + public String getDateFormat(String dateType, String dateFormat, String column) { + if (dateFormat.equalsIgnoreCase(Constants.DAY_FORMAT_INT)) { + if (TimeDimensionEnum.MONTH.name().equalsIgnoreCase(dateType)) { + return "formatDateTime(toDate(parseDateTimeBestEffort(toString(%s))),'%Y-%m')".replace("%s", column); + } else if (TimeDimensionEnum.WEEK.name().equalsIgnoreCase(dateType)) { + return "toMonday(toDate(parseDateTimeBestEffort(toString(%s))))".replace("%s", column); + } else { + return "toDate(parseDateTimeBestEffort(toString(%s)))".replace("%s", column); + } + } else if (dateFormat.equalsIgnoreCase(Constants.DAY_FORMAT)) { + if (TimeDimensionEnum.MONTH.name().equalsIgnoreCase(dateType)) { + return "formatDateTime(toDate(%s),'%Y-%m')".replace("%s", column); + } else if (TimeDimensionEnum.WEEK.name().equalsIgnoreCase(dateType)) { + return "toMonday(toDate(%s))".replace("%s", column); + } else { + return column; + } + } + return column; + } + + @Override + public String getDbMetaQueryTpl() { + return " SELECT datname as name FROM pg_database WHERE datistemplate = false ;"; + } + + @Override + public String getTableMetaQueryTpl() { + return " SELECT table_name as name FROM information_schema.tables WHERE " + + "table_schema = 'public' AND table_catalog = '%s' ; "; + } + + @Override + public String functionNameCorrector(String sql) { + Map functionMap = new HashMap<>(); + functionMap.put("MONTH".toLowerCase(), "toMonth"); + functionMap.put("DAY".toLowerCase(), "toDayOfMonth"); + functionMap.put("YEAR".toLowerCase(), "toYear"); + return SqlParserReplaceHelper.replaceFunction(sql, functionMap); + } + + @Override + public String getColumnMetaQueryTpl() { + return " SELECT column_name as name, data_type as dataType FROM information_schema.columns " + + "WHERE table_schema = 'public' AND table_catalog = '%s' AND table_name = '%s' ; "; + } + +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/manager/ModelYamlManager.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/manager/ModelYamlManager.java index 3f0f4dc09..0c8983a5a 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/manager/ModelYamlManager.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/manager/ModelYamlManager.java @@ -37,6 +37,7 @@ public class ModelYamlManager { SysTimeDimensionBuilder.addSysTimeDimension(modelDetail.getDimensions(), engineAdaptor); addInterCntMetric(modelResp.getBizName(), modelDetail); DataModelYamlTpl dataModelYamlTpl = new DataModelYamlTpl(); + dataModelYamlTpl.setType(databaseResp.getType()); BeanUtils.copyProperties(modelDetail, dataModelYamlTpl); dataModelYamlTpl.setIdentifiers(modelDetail.getIdentifiers().stream().map(ModelYamlManager::convert) .collect(Collectors.toList())); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/s2sql/DataSource.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/s2sql/DataSource.java index c68bb9810..5d0ea7e70 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/s2sql/DataSource.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/s2sql/DataSource.java @@ -16,6 +16,8 @@ public class DataSource { private Long sourceId; + private String type; + private String sqlQuery; private String tableQuery; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/schema/SemanticSqlDialect.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/schema/SemanticSqlDialect.java index f92f7bb79..1578a855d 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/schema/SemanticSqlDialect.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/schema/SemanticSqlDialect.java @@ -18,7 +18,6 @@ public class SemanticSqlDialect extends SqlDialect { .withDatabaseProduct(DatabaseProduct.BIG_QUERY) .withLiteralQuoteString("'") .withLiteralEscapedQuoteString("''") - .withIdentifierQuoteString("`") .withUnquotedCasing(Casing.UNCHANGED) .withQuotedCasing(Casing.UNCHANGED) .withCaseSensitive(false); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/DataSourceNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/DataSourceNode.java index 0d806a86a..5ac0f4e5b 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/DataSourceNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/DataSourceNode.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.headless.core.parser.calcite.sql.node; import com.google.common.collect.Lists; +import com.tencent.supersonic.headless.api.enums.EngineType; import com.tencent.supersonic.headless.api.request.MetricQueryReq; import com.tencent.supersonic.headless.core.parser.calcite.Configuration; import com.tencent.supersonic.headless.core.parser.calcite.s2sql.Constants; @@ -43,7 +44,13 @@ public class DataSourceNode extends SemanticNode { if (datasource.getSqlQuery() != null && !datasource.getSqlQuery().isEmpty()) { sqlTable = datasource.getSqlQuery(); } else if (datasource.getTableQuery() != null && !datasource.getTableQuery().isEmpty()) { - sqlTable = "select * from " + datasource.getTableQuery(); + if (datasource.getType().equalsIgnoreCase(EngineType.POSTGRESQL.getName())) { + String fullTableName = Arrays.stream(datasource.getTableQuery().split("\\.")) + .collect(Collectors.joining(".public.")); + sqlTable = "select * from " + fullTableName; + } else { + sqlTable = "select * from " + datasource.getTableQuery(); + } } if (sqlTable.isEmpty()) { throw new Exception("DatasourceNode build error [tableSqlNode not found]"); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/SemanticNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/SemanticNode.java index c79bb7501..c071327c3 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/SemanticNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/parser/calcite/sql/node/SemanticNode.java @@ -338,6 +338,7 @@ public abstract class SemanticNode { public static SqlNode optimize(SqlValidatorScope scope, HeadlessSchema schema, SqlNode sqlNode) { try { HepProgramBuilder hepProgramBuilder = new HepProgramBuilder(); + hepProgramBuilder.addRuleInstance(new FilterToGroupScanRule(FilterToGroupScanRule.DEFAULT, schema)); RelOptPlanner relOptPlanner = new HepPlanner(hepProgramBuilder.build()); RelToSqlConverter converter = new RelToSqlConverter(SemanticSqlDialect.DEFAULT); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/yaml/DataModelYamlTpl.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/yaml/DataModelYamlTpl.java index 609508803..6db7e9743 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/yaml/DataModelYamlTpl.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/yaml/DataModelYamlTpl.java @@ -15,6 +15,8 @@ public class DataModelYamlTpl { private Long sourceId; + private String type; + private String sqlQuery; private String tableQuery; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/JdbcDataSourceUtils.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/JdbcDataSourceUtils.java index 17ea9db2a..43f42685a 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/JdbcDataSourceUtils.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/JdbcDataSourceUtils.java @@ -1,23 +1,5 @@ package com.tencent.supersonic.headless.core.utils; -import com.alibaba.druid.util.StringUtils; -import com.tencent.supersonic.common.util.MD5Util; -import com.tencent.supersonic.headless.api.enums.DataType; -import com.tencent.supersonic.headless.api.response.DatabaseResp; -import com.tencent.supersonic.headless.core.pojo.Database; -import com.tencent.supersonic.headless.core.pojo.JdbcDataSource; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; - import static com.tencent.supersonic.common.pojo.Constants.AT_SYMBOL; import static com.tencent.supersonic.common.pojo.Constants.COLON; import static com.tencent.supersonic.common.pojo.Constants.DOUBLE_SLASH; @@ -27,6 +9,23 @@ import static com.tencent.supersonic.common.pojo.Constants.NEW_LINE_CHAR; import static com.tencent.supersonic.common.pojo.Constants.PATTERN_JDBC_TYPE; import static com.tencent.supersonic.common.pojo.Constants.SPACE; +import com.alibaba.druid.util.StringUtils; +import com.tencent.supersonic.common.util.MD5Util; +import com.tencent.supersonic.headless.api.enums.DataType; +import com.tencent.supersonic.headless.api.response.DatabaseResp; +import com.tencent.supersonic.headless.core.pojo.Database; +import com.tencent.supersonic.headless.core.pojo.JdbcDataSource; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import javax.sql.DataSource; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + /** * tools functions about jdbc */ @@ -127,7 +126,6 @@ public class JdbcDataSourceUtils { if (dataTypeEnum != null) { return dataTypeEnum.getDriver(); } - throw new RuntimeException("Not supported data type: jdbcUrl=" + jdbcUrl); } diff --git a/headless/server/pom.xml b/headless/server/pom.xml index 80c8fb19b..a009887bf 100644 --- a/headless/server/pom.xml +++ b/headless/server/pom.xml @@ -110,6 +110,11 @@ easyexcel ${easyexcel.version} + + org.postgresql + postgresql + ${postgresql.version} + \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/HeadlessSchemaManager.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/HeadlessSchemaManager.java index 78d8dcb3d..29c3b36e5 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/HeadlessSchemaManager.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/HeadlessSchemaManager.java @@ -120,7 +120,7 @@ public class HeadlessSchemaManager { public static DataSource getDatasource(final DataModelYamlTpl d) { DataSource datasource = DataSource.builder().id(d.getId()).sourceId(d.getSourceId()) - .sqlQuery(d.getSqlQuery()).name(d.getName()).tableQuery(d.getTableQuery()) + .type(d.getType()).sqlQuery(d.getSqlQuery()).name(d.getName()).tableQuery(d.getTableQuery()) .identifiers(getIdentify(d.getIdentifiers())).measures(getMeasures(d.getMeasures())) .dimensions(getDimensions(d.getDimensions())).build(); datasource.setAggTime(getDataSourceAggTime(datasource.getDimensions())); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClickHouseParametersBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClickHouseParametersBuilder.java new file mode 100644 index 000000000..601b89738 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/ClickHouseParametersBuilder.java @@ -0,0 +1,44 @@ +package com.tencent.supersonic.headless.server.pojo; + + +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class ClickHouseParametersBuilder implements DbParametersBuilder { + + @Override + public List build() { + List databaseParameters = new ArrayList<>(); + DatabaseParameter host = new DatabaseParameter(); + host.setName("host"); + host.setEnName("host"); + host.setComment("请输入host"); + databaseParameters.add(host); + + DatabaseParameter port = new DatabaseParameter(); + port.setName("port"); + port.setEnName("port"); + port.setComment("请输入端口号"); + databaseParameters.add(port); + + DatabaseParameter userName = new DatabaseParameter(); + userName.setName("用户名"); + userName.setEnName("username"); + databaseParameters.add(userName); + + DatabaseParameter password = new DatabaseParameter(); + password.setName("密码"); + password.setEnName("password"); + databaseParameters.add(password); + + DatabaseParameter database = new DatabaseParameter(); + database.setName("数据库名称"); + database.setEnName("database"); + databaseParameters.add(database); + return databaseParameters; + } +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DatabaseParameter.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DatabaseParameter.java new file mode 100644 index 000000000..e9b07d02a --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DatabaseParameter.java @@ -0,0 +1,19 @@ +package com.tencent.supersonic.headless.server.pojo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DatabaseParameter { + + private String name; + private String enName; + private String comment; + private String defaultValue; + +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParameterFactory.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParameterFactory.java new file mode 100644 index 000000000..b809254d9 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParameterFactory.java @@ -0,0 +1,28 @@ +package com.tencent.supersonic.headless.server.pojo; + +import com.tencent.supersonic.headless.api.enums.EngineType; +import java.util.LinkedHashMap; +import java.util.Map; + + +public class DbParameterFactory { + + private static Map parametersBuilder; + + static { + parametersBuilder = new LinkedHashMap<>(); + parametersBuilder.put(EngineType.H2.getName(), new H2ParametersBuilder()); + parametersBuilder.put(EngineType.CLICKHOUSE.getName(), new ClickHouseParametersBuilder()); + parametersBuilder.put(EngineType.MYSQL.getName(), new MysqlParametersBuilder()); + parametersBuilder.put(EngineType.POSTGRESQL.getName(), new PostgresqlParametersBuilder()); + } + + public static DbParametersBuilder get(String engineType) { + return parametersBuilder.get(engineType); + } + + public static Map getMap() { + return parametersBuilder; + } + +} \ No newline at end of file diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParametersBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParametersBuilder.java new file mode 100644 index 000000000..8a69ca167 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/DbParametersBuilder.java @@ -0,0 +1,9 @@ +package com.tencent.supersonic.headless.server.pojo; + +import java.util.List; + +public interface DbParametersBuilder { + + List build(); + +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/H2ParametersBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/H2ParametersBuilder.java new file mode 100644 index 000000000..5ee50a82d --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/H2ParametersBuilder.java @@ -0,0 +1,44 @@ +package com.tencent.supersonic.headless.server.pojo; + + +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class H2ParametersBuilder implements DbParametersBuilder { + + @Override + public List build() { + List databaseParameters = new ArrayList<>(); + DatabaseParameter host = new DatabaseParameter(); + host.setName("链接"); + host.setEnName("url"); + host.setComment("请输入链接"); + databaseParameters.add(host); + + DatabaseParameter port = new DatabaseParameter(); + port.setName("port"); + port.setEnName("port"); + port.setComment("请输入端口号"); + databaseParameters.add(port); + + DatabaseParameter userName = new DatabaseParameter(); + userName.setName("用户名"); + userName.setEnName("username"); + databaseParameters.add(userName); + + DatabaseParameter password = new DatabaseParameter(); + password.setName("密码"); + password.setEnName("password"); + databaseParameters.add(password); + + DatabaseParameter database = new DatabaseParameter(); + database.setName("数据库名称"); + database.setEnName("database"); + databaseParameters.add(database); + return databaseParameters; + } +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/MysqlParametersBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/MysqlParametersBuilder.java new file mode 100644 index 000000000..d38c99f2a --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/MysqlParametersBuilder.java @@ -0,0 +1,50 @@ +package com.tencent.supersonic.headless.server.pojo; + + +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class MysqlParametersBuilder implements DbParametersBuilder { + + @Override + public List build() { + List databaseParameters = new ArrayList<>(); + DatabaseParameter host = new DatabaseParameter(); + host.setName("host"); + host.setEnName("host"); + host.setComment("请输入host"); + databaseParameters.add(host); + + DatabaseParameter port = new DatabaseParameter(); + port.setName("port"); + port.setEnName("port"); + port.setComment("请输入端口号"); + databaseParameters.add(port); + + DatabaseParameter version = new DatabaseParameter(); + version.setName("数据库版本"); + version.setEnName("version"); + version.setComment("请输入数据库版本"); + databaseParameters.add(version); + + DatabaseParameter userName = new DatabaseParameter(); + userName.setName("用户名"); + userName.setEnName("username"); + databaseParameters.add(userName); + + DatabaseParameter password = new DatabaseParameter(); + password.setName("密码"); + password.setEnName("password"); + databaseParameters.add(password); + + DatabaseParameter database = new DatabaseParameter(); + database.setName("数据库名称"); + database.setEnName("database"); + databaseParameters.add(database); + return databaseParameters; + } +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/PostgresqlParametersBuilder.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/PostgresqlParametersBuilder.java new file mode 100644 index 000000000..a60f1a6a1 --- /dev/null +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/pojo/PostgresqlParametersBuilder.java @@ -0,0 +1,50 @@ +package com.tencent.supersonic.headless.server.pojo; + + +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class PostgresqlParametersBuilder implements DbParametersBuilder { + + @Override + public List build() { + List databaseParameters = new ArrayList<>(); + DatabaseParameter host = new DatabaseParameter(); + host.setName("host"); + host.setEnName("host"); + host.setComment("请输入host"); + databaseParameters.add(host); + + DatabaseParameter port = new DatabaseParameter(); + port.setName("port"); + port.setEnName("port"); + port.setComment("请输入端口号"); + databaseParameters.add(port); + + DatabaseParameter userName = new DatabaseParameter(); + userName.setName("用户名"); + userName.setEnName("username"); + databaseParameters.add(userName); + + DatabaseParameter password = new DatabaseParameter(); + password.setName("密码"); + password.setEnName("password"); + databaseParameters.add(password); + + DatabaseParameter schema = new DatabaseParameter(); + schema.setName("schema"); + schema.setEnName("schema"); + schema.setDefaultValue("public"); + databaseParameters.add(schema); + + DatabaseParameter database = new DatabaseParameter(); + database.setName("数据库名称"); + database.setEnName("database"); + databaseParameters.add(database); + return databaseParameters; + } +} diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/DatabaseController.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/DatabaseController.java index 91518122b..6b978bfb1 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/DatabaseController.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/DatabaseController.java @@ -6,7 +6,9 @@ import com.tencent.supersonic.headless.api.request.DatabaseReq; import com.tencent.supersonic.headless.api.request.SqlExecuteReq; import com.tencent.supersonic.headless.api.response.DatabaseResp; import com.tencent.supersonic.headless.api.response.QueryResultWithSchemaResp; +import com.tencent.supersonic.headless.server.pojo.DatabaseParameter; import com.tencent.supersonic.headless.server.service.DatabaseService; +import java.util.Map; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -53,7 +55,7 @@ public class DatabaseController { @GetMapping("/getDatabaseList") public List getDatabaseList(HttpServletRequest request, - HttpServletResponse response) { + HttpServletResponse response) { User user = UserHolder.findUser(request, response); return databaseService.getDatabaseList(user); } @@ -66,8 +68,8 @@ public class DatabaseController { @PostMapping("/executeSql") public QueryResultWithSchemaResp executeSql(@RequestBody SqlExecuteReq sqlExecuteReq, - HttpServletRequest request, - HttpServletResponse response) { + HttpServletRequest request, + HttpServletResponse response) { User user = UserHolder.findUser(request, response); return databaseService.executeSql(sqlExecuteReq.getSql(), sqlExecuteReq.getId(), user); } @@ -90,4 +92,10 @@ public class DatabaseController { return databaseService.getColumns(id, db, table); } + @GetMapping("/getDatabaseParameters") + public Map> getDatabaseParameters(HttpServletRequest request, + HttpServletResponse response) { + return databaseService.getDatabaseParameters(); + } + } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DatabaseService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DatabaseService.java index ea4e58e33..bf6bee06d 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DatabaseService.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DatabaseService.java @@ -4,8 +4,9 @@ import com.tencent.supersonic.auth.api.authentication.pojo.User; import com.tencent.supersonic.headless.api.request.DatabaseReq; import com.tencent.supersonic.headless.api.response.DatabaseResp; import com.tencent.supersonic.headless.api.response.QueryResultWithSchemaResp; - +import com.tencent.supersonic.headless.server.pojo.DatabaseParameter; import java.util.List; +import java.util.Map; public interface DatabaseService { @@ -14,6 +15,8 @@ public interface DatabaseService { QueryResultWithSchemaResp executeSql(String sql, Long id, User user); + Map> getDatabaseParameters(); + boolean testConnect(DatabaseReq databaseReq, User user); DatabaseResp createOrUpdateDatabase(DatabaseReq databaseReq, User user); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java index 3d04add7b..d9c573f48 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DatabaseServiceImpl.java @@ -7,23 +7,26 @@ import com.tencent.supersonic.headless.api.response.ModelResp; import com.tencent.supersonic.headless.api.response.QueryResultWithSchemaResp; import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptor; import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptorFactory; +import com.tencent.supersonic.headless.core.pojo.Database; +import com.tencent.supersonic.headless.core.utils.JdbcDataSourceUtils; +import com.tencent.supersonic.headless.core.utils.SqlUtils; import com.tencent.supersonic.headless.server.persistence.dataobject.DatabaseDO; import com.tencent.supersonic.headless.server.persistence.repository.DatabaseRepository; -import com.tencent.supersonic.headless.core.pojo.Database; +import com.tencent.supersonic.headless.server.pojo.DatabaseParameter; +import com.tencent.supersonic.headless.server.pojo.DbParameterFactory; import com.tencent.supersonic.headless.server.pojo.ModelFilter; import com.tencent.supersonic.headless.server.service.DatabaseService; import com.tencent.supersonic.headless.server.service.ModelService; import com.tencent.supersonic.headless.server.utils.DatabaseConverter; -import com.tencent.supersonic.headless.core.utils.JdbcDataSourceUtils; -import com.tencent.supersonic.headless.core.utils.SqlUtils; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import java.util.List; -import java.util.stream.Collectors; - @Slf4j @Service @@ -34,8 +37,8 @@ public class DatabaseServiceImpl implements DatabaseService { private ModelService datasourceService; public DatabaseServiceImpl(DatabaseRepository databaseRepository, - SqlUtils sqlUtils, - @Lazy ModelService datasourceService) { + SqlUtils sqlUtils, + @Lazy ModelService datasourceService) { this.databaseRepository = databaseRepository; this.sqlUtils = sqlUtils; this.datasourceService = datasourceService; @@ -67,8 +70,8 @@ public class DatabaseServiceImpl implements DatabaseService { public List getDatabaseList(User user) { List databaseResps = databaseRepository.getDatabaseList() - .stream().map(DatabaseConverter::convert) - .collect(Collectors.toList()); + .stream().map(DatabaseConverter::convert) + .collect(Collectors.toList()); fillPermission(databaseResps, user); return databaseResps; } @@ -133,6 +136,13 @@ public class DatabaseServiceImpl implements DatabaseService { return queryWithColumns(sql, databaseResp); } + @Override + public Map> getDatabaseParameters() { + return DbParameterFactory.getMap().entrySet().stream().collect(LinkedHashMap::new, + (map, entry) -> map.put(entry.getKey(), entry.getValue().build()), + LinkedHashMap::putAll); + } + private QueryResultWithSchemaResp queryWithColumns(String sql, DatabaseResp databaseResp) { QueryResultWithSchemaResp queryResultWithColumns = new QueryResultWithSchemaResp(); SqlUtils sqlUtils = this.sqlUtils.init(databaseResp); diff --git a/launchers/standalone/src/main/resources/application-local.yaml b/launchers/standalone/src/main/resources/application-local.yaml index ce5ce830d..901d273a1 100644 --- a/launchers/standalone/src/main/resources/application-local.yaml +++ b/launchers/standalone/src/main/resources/application-local.yaml @@ -83,4 +83,8 @@ logging: inMemoryEmbeddingStore: persistent: - path: /tmp \ No newline at end of file + path: /tmp + +query: + optimizer: + enable: true \ No newline at end of file diff --git a/pom.xml b/pom.xml index ec6bc2bd0..e778d8b81 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,7 @@ 2.2.6 3.17 0.24.0 + 42.7.1