Commit 6b60243b by inrgihc

反馈问题修复

parent d458787e
......@@ -31,6 +31,7 @@ public class ProductContext implements Serializable {
private String name;
private String driver;
private int defaultPort;
private boolean multiDialect;
private String testSql;
private String urlPrefix;
private String[] tplUrls;
......
......@@ -9,8 +9,6 @@
/////////////////////////////////////////////////////////////
package org.dromara.sqlrest.common.enums;
import org.dromara.sqlrest.common.dto.ProductContext;
import org.dromara.sqlrest.common.dto.ThreeConsumer;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
......@@ -18,6 +16,8 @@ import java.util.Collections;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.dromara.sqlrest.common.dto.ProductContext;
import org.dromara.sqlrest.common.dto.ThreeConsumer;
@Getter
public enum ProductTypeEnum {
......@@ -257,7 +257,7 @@ public enum ProductTypeEnum {
.tplUrls(new String[]{"jdbc:gbase://{host}[:{port}]/[{database}][\\?{params}]"})
.urlSample("jdbc:gbase://172.17.2.10:5258/test")
.sqlSchemaList("SELECT schema_name FROM information_schema.schemata ")
.adapter(database -> Pair.of(null, database))
.adapter(database -> Pair.of(database, null))
.pageSql("select * from (%s) alias limit ? offset ? ")
.pageConsumer(
(page, size, parameters) -> {
......@@ -453,17 +453,17 @@ public enum ProductTypeEnum {
OCEANBASE(
ProductContext.builder()
.id(18)
.quote("`")
.quote("")
.name("oceanbase")
.driver("com.oceanbase.jdbc.Driver")
.defaultPort(2881)
.testSql("/* ping */ SELECT 1")
.multiDialect(true)
.testSql("show global variables where variable_name = 'ob_compatibility_mode'")
.urlPrefix("jdbc:oceanbase://")
.tplUrls(new String[]{"jdbc:oceanbase://{host}[:{port}]/[{database}][\\?{params}]"})
.urlSample(
"jdbc:oceanbase://127.0.0.1:2881/test?pool=false&useUnicode=true&characterEncoding=utf-8&useSSL=false")
.sqlSchemaList("SELECT `SCHEMA_NAME` FROM `information_schema`.`SCHEMATA`")
.adapter(database -> Pair.of(database, null))
.urlSample("jdbc:oceanbase://127.0.0.1:2881/test")
.sqlSchemaList(null)
.adapter(null)
.pageSql("select * from (%s) alias limit ? OFFSET ? ")
.pageConsumer(
(page, size, parameters) -> {
......@@ -523,6 +523,10 @@ public enum ProductTypeEnum {
return this.context.getTplUrls();
}
public boolean isMultiDialect() {
return this.context.isMultiDialect();
}
public String getTestSql() {
return this.context.getTestSql();
}
......@@ -551,14 +555,14 @@ public enum ProductTypeEnum {
return this != SQLITE3;
}
public String quoteName(String name) {
return String.format("%s%s%s", context.getQuote(), name, context.getQuote());
}
public String quoteSchemaTableName(String schema, String table) {
String quote = context.getQuote();
return String.format("%s%s%s.%s%s%s", quote, schema, quote, quote, table, quote);
}
// public String quoteName(String name) {
// return String.format("%s%s%s", context.getQuote(), name, context.getQuote());
// }
//
// public String quoteSchemaTableName(String schema, String table) {
// String quote = context.getQuote();
// return String.format("%s%s%s.%s%s%s", quote, schema, quote, quote, table, quote);
// }
public String getPageSql(String sql, int page, int size) {
String pageSql = String.format(context.getPageSql(), sql);
......
......@@ -9,15 +9,7 @@
/////////////////////////////////////////////////////////////
package org.dromara.sqlrest.core.exec.module;
import org.dromara.sqlrest.common.enums.NamingStrategyEnum;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
import org.dromara.sqlrest.core.exec.SqlExecuteLogger;
import org.dromara.sqlrest.core.exec.annotation.Comment;
import org.dromara.sqlrest.core.exec.annotation.Module;
import org.dromara.sqlrest.core.util.ConvertUtils;
import org.dromara.sqlrest.core.util.PageSizeUtils;
import org.dromara.sqlrest.template.SqlMeta;
import org.dromara.sqlrest.template.XmlSqlTemplate;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
......@@ -30,6 +22,16 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sqlrest.common.enums.NamingStrategyEnum;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
import org.dromara.sqlrest.core.exec.SqlExecuteLogger;
import org.dromara.sqlrest.core.exec.annotation.Comment;
import org.dromara.sqlrest.core.exec.annotation.Module;
import org.dromara.sqlrest.core.util.ConvertUtils;
import org.dromara.sqlrest.core.util.PageSizeUtils;
import org.dromara.sqlrest.core.util.PageSqlUtils;
import org.dromara.sqlrest.template.SqlMeta;
import org.dromara.sqlrest.template.XmlSqlTemplate;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
import org.springframework.jdbc.core.ColumnMapRowMapper;
......@@ -41,6 +43,7 @@ import org.springframework.jdbc.support.GeneratedKeyHolder;
@Module("db")
public class DbVarModule {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
private ProductTypeEnum productType;
private Map<String, Object> params;
......@@ -48,6 +51,7 @@ public class DbVarModule {
public DbVarModule(DataSource dataSource, ProductTypeEnum productType, Map<String, Object> params,
NamingStrategyEnum strategy) {
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.productType = productType;
this.params = params;
......@@ -58,6 +62,17 @@ public class DbVarModule {
this.converter = strategy.getFunction();
}
private String getPageSql(String sql, int page, int size) {
if (!productType.isMultiDialect()) {
return productType.getPageSql(sql, page, size);
}
try (Connection connection = dataSource.getConnection()) {
return PageSqlUtils.getPageSql(productType, connection, sql, page, size);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private Map<String, Object> build(Map<String, Object> row) {
return ConvertUtils.to(row, converter);
}
......@@ -126,7 +141,7 @@ public class DbVarModule {
int size = PageSizeUtils.getSizeFromParams(params);
XmlSqlTemplate template = new XmlSqlTemplate(sqlOrXml);
SqlMeta sqlMeta = template.process(params);
String pageSql = productType.getPageSql(sqlMeta.getSql(), page, size);
String pageSql = getPageSql(sqlMeta.getSql(), page, size);
List<Object> parameters = sqlMeta.getParameter();
this.productType.getPageConsumer().accept(page, size, parameters);
long start = System.currentTimeMillis();
......
......@@ -11,6 +11,23 @@ package org.dromara.sqlrest.core.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.zaxxer.hikari.HikariDataSource;
import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.dromara.sqlrest.common.dto.PageResult;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
import org.dromara.sqlrest.common.exception.CommonException;
......@@ -29,20 +46,8 @@ import org.dromara.sqlrest.persistence.dao.ApiAssignmentDao;
import org.dromara.sqlrest.persistence.dao.DataSourceDao;
import org.dromara.sqlrest.persistence.entity.DataSourceEntity;
import org.dromara.sqlrest.persistence.util.PageUtils;
import com.zaxxer.hikari.HikariDataSource;
import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@Service
public class DataSourceService {
......@@ -168,6 +173,7 @@ public class DataSourceService {
validJdbcUrlFormat(dataSourceEntity);
dataSourceDao.updateById(dataSourceEntity);
DataSourceUtils.dropHikariDataSource(request.getId());
}
public void deleteDataSource(Long id) {
......@@ -191,16 +197,21 @@ public class DataSourceService {
public List<String> getDatasourceSchemas(Long id) {
DataSourceEntity dataSourceEntity = dataSourceDao.getById(id);
String sqlList = dataSourceEntity.getType().getContext().getSqlSchemaList();
if (null == sqlList) {
List<String> ret = dataSourceEntity.getType().getContext().getRetSchemaList();
if (null != ret) {
return ret;
}
}
File driverPathFile = SpringUtil.getBean(DriverLoadService.class)
.getVersionDriverFile(dataSourceEntity.getType(),
dataSourceEntity.getVersion());
String driverPath = driverPathFile.getAbsolutePath();
String sqlList = dataSourceEntity.getType().getContext().getSqlSchemaList();
if (null == sqlList) {
return dataSourceEntity.getType().getContext().getRetSchemaList();
}
List<String> result = new ArrayList<>();
HikariDataSource ds = DataSourceUtils.getHikariDataSource(dataSourceEntity, driverPath);
List<String> result = new ArrayList<>();
if (StringUtils.isNotBlank(sqlList)) {
try (Connection connection = ds.getConnection();
Statement statement = connection.createStatement();
......@@ -208,7 +219,24 @@ public class DataSourceService {
while (rs.next()) {
result.add(rs.getString(1));
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
try (Connection connection = ds.getConnection()) {
DatabaseMetaData metaData = connection.getMetaData();
try (ResultSet rs = metaData.getSchemas(connection.getCatalog(), null)) {
while (rs.next()) {
result.add(rs.getString("TABLE_SCHEM"));
}
}
if (CollectionUtils.isEmpty(result)) {
try (ResultSet catalogRs = metaData.getCatalogs()) {
while (catalogRs.next()) {
result.add(catalogRs.getString("TABLE_CAT"));
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
......@@ -228,8 +256,8 @@ public class DataSourceService {
try (Connection connection = ds.getConnection()) {
String catalogName = productType.getContext().isHasCatalogAndSchema()
? connection.getCatalog()
: productType.getContext().getAdapter().apply(schema).getLeft();
String schemaName = productType.getContext().getAdapter().apply(schema).getRight();
: getAdapter(productType, connection, schema).getLeft();
String schemaName = getAdapter(productType, connection, schema).getRight();
try (ResultSet rs = connection.getMetaData()
.getTables(catalogName, schemaName, "%", new String[]{"TABLE"})) {
while (rs.next()) {
......@@ -257,8 +285,8 @@ public class DataSourceService {
try (Connection connection = ds.getConnection()) {
String catalogName = productType.getContext().isHasCatalogAndSchema()
? connection.getCatalog()
: productType.getContext().getAdapter().apply(schema).getLeft();
String schemaName = productType.getContext().getAdapter().apply(schema).getRight();
: getAdapter(productType, connection, schema).getLeft();
String schemaName = getAdapter(productType, connection, schema).getRight();
try (ResultSet rs = connection.getMetaData()
.getTables(catalogName, schemaName, "%", new String[]{"VIEW"})) {
while (rs.next()) {
......@@ -283,8 +311,8 @@ public class DataSourceService {
try (Connection connection = ds.getConnection()) {
String catalogName = productType.getContext().isHasCatalogAndSchema()
? connection.getCatalog()
: productType.getContext().getAdapter().apply(schema).getLeft();
String schemaName = productType.getContext().getAdapter().apply(schema).getRight();
: getAdapter(productType, connection, schema).getLeft();
String schemaName = getAdapter(productType, connection, schema).getRight();
try (ResultSet rs = connection.getMetaData()
.getColumns(catalogName, schemaName, table, null)) {
while (rs.next()) {
......@@ -330,4 +358,55 @@ public class DataSourceService {
}
}
}
private Pair<String, String> getAdapter(ProductTypeEnum productType, Connection connection, String schema) {
if (null != productType.getContext().getAdapter()) {
return productType.getContext().getAdapter().apply(schema);
}
return getAdapter(connection, schema);
}
@SneakyThrows
private Pair<String, String> getAdapter(Connection connection, String schema) {
boolean hasCatalogLayer = hasCatalogLayer(connection);
boolean hasSchemaLayer = hasSchemaLayer(connection);
if (hasCatalogLayer) {
if (hasSchemaLayer) {
return Pair.of(connection.getCatalog(), schema);
} else {
return Pair.of(schema, null);
}
} else {
return Pair.of(null, schema);
}
}
private boolean hasCatalogLayer(Connection conn) {
try (ResultSet catalogs = conn.getMetaData().getCatalogs()) {
return catalogs.next();
} catch (SQLException e) {
throw new RuntimeException("Detect has catalog layer failed:" + e.getMessage());
}
}
private boolean hasSchemaLayer(Connection conn) {
try {
DatabaseMetaData dbMeta = conn.getMetaData();
try (ResultSet catalogRs = dbMeta.getCatalogs()) {
while (catalogRs.next()) {
String name = catalogRs.getString("TABLE_CAT");
try (ResultSet schemaRs = dbMeta.getSchemas(name, null)) {
if (schemaRs.next()) {
return true;
}
}
}
}
try (ResultSet schemaRs = dbMeta.getSchemas()) {
return schemaRs.next();
}
} catch (SQLException e) {
throw new RuntimeException("Detect has schema layer failed:" + e.getMessage());
}
}
}
// Copyright tang. All rights reserved.
// https://gitee.com/inrgihc/sqlrest
//
// Use of this source code is governed by a BSD-style license
//
// Author: tang (inrgihc@126.com)
// Date : 2024/3/31
// Location: beijing , china
/////////////////////////////////////////////////////////////
package org.dromara.sqlrest.core.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
@Slf4j
@UtilityClass
public class PageSqlUtils {
public static final String sqlDialect = "show global variables where variable_name = 'ob_compatibility_mode'";
public static String getPageSql(ProductTypeEnum productType, Connection conn, String sql, Integer page,
Integer size) {
if (ProductTypeEnum.OCEANBASE == productType) {
if (PageSqlUtils.isInMysqlMode(conn)) {
return ProductTypeEnum.MYSQL.getPageSql(sql, page, size);
} else {
return ProductTypeEnum.ORACLE.getPageSql(sql, page, size);
}
}
return productType.getPageSql(sql, page, size);
}
public static boolean isInMysqlMode(Connection connection) {
try (PreparedStatement statement = connection.prepareStatement(sqlDialect)) {
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
String value = resultSet.getString(2);
if (Objects.nonNull(value)) {
if (value.toUpperCase().contains("MYSQL")) {
return true;
} else {
return false;
}
} else {
throw new RuntimeException("Execute SQL[" + sqlDialect + "] return null value");
}
} else {
throw new RuntimeException("Execute SQL[" + sqlDialect + "] no result");
}
}
} catch (SQLException sqlException) {
if (log.isDebugEnabled()) {
log.debug("Failed to execute sql :{}, and guesses OceanBase is MySQL Mode!", sqlDialect);
}
}
return true;
}
}
\ No newline at end of file
......@@ -9,11 +9,6 @@
/////////////////////////////////////////////////////////////
package org.dromara.sqlrest.core.util;
import org.dromara.sqlrest.common.enums.NamingStrategyEnum;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
import org.dromara.sqlrest.common.util.LambdaUtils;
import org.dromara.sqlrest.core.exec.SqlExecuteLogger;
import org.dromara.sqlrest.template.SqlMeta;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -27,6 +22,11 @@ import java.util.function.Consumer;
import java.util.function.Function;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sqlrest.common.enums.NamingStrategyEnum;
import org.dromara.sqlrest.common.enums.ProductTypeEnum;
import org.dromara.sqlrest.common.util.LambdaUtils;
import org.dromara.sqlrest.core.exec.SqlExecuteLogger;
import org.dromara.sqlrest.template.SqlMeta;
@Slf4j
@UtilityClass
......@@ -42,7 +42,9 @@ public class SqlJdbcUtils {
NamingStrategyEnum strategy, int page, int size) throws SQLException {
List<Object> paramValues = sqlMeta.getParameter();
boolean isQuerySql = sqlMeta.isQuerySQL();
String sql = isQuerySql ? productType.getPageSql(sqlMeta.getSql(), page, size) : sqlMeta.getSql();
String sql = isQuerySql
? PageSqlUtils.getPageSql(productType, connection, sqlMeta.getSql(), page, size)
: sqlMeta.getSql();
Consumer<Connection> executeBeforeQuery = productType.getContext().getExecuteBeforeQuery();
LambdaUtils.ifDo(Objects.nonNull(executeBeforeQuery), () -> executeBeforeQuery.accept(connection));
PreparedStatement statement = connection.prepareStatement(sql);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment