mirror of
https://github.com/dataease/dataease.git
synced 2026-05-14 21:12:33 +08:00
perf: SQLBot 数据源接口 行列权限机制优化
This commit is contained in:
committed by
fit2cloud-chenyw
parent
c4fcd23f8b
commit
ee1870a172
@@ -31,8 +31,10 @@ import io.dataease.engine.trans.WhereTree2Str;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.api.PluginManageApi;
|
||||
import io.dataease.extensions.datasource.dto.CalParam;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.dto.FieldGroupDTO;
|
||||
import io.dataease.extensions.datasource.factory.ProviderFactory;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
@@ -270,7 +272,11 @@ public class DatasetSQLBotManage {
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildTable(SQLBotAssistanTable table, List<DataSetColumnPermissionsDTO> columnPermissionsDTOS, List<DataSetRowPermissionsTreeDTO> rowPermissionsTree) {
|
||||
TypeReference<List<FieldGroupDTO>> groupTokenType = new TypeReference<>() {
|
||||
};
|
||||
TypeReference<List<CalParam>> typeToken = new TypeReference<>() {
|
||||
};
|
||||
private void rebuildTable(SQLBotAssistanTable table, List<DataSetColumnPermissionsDTO> columnPermissionsDTOS, List<DataSetRowPermissionsTreeDTO> rowPermissionsTree, Map<String, Object> dsRowData) {
|
||||
Map<String, Object> rowData = table.getRowData();
|
||||
CoreDatasetGroup coreDatasetGroup = BeanUtils.mapToBean(rowData, CoreDatasetGroup.class);
|
||||
|
||||
@@ -287,6 +293,12 @@ public class DatasetSQLBotManage {
|
||||
List<DatasetTableFieldDTO> dsFields = sqlbotFields.stream().map(field -> {
|
||||
Map<String, Object> fieldRowData = field.getRowData();
|
||||
DatasetTableFieldDTO fieldDTO = BeanUtils.mapToBean(fieldRowData, DatasetTableFieldDTO.class);
|
||||
if (ObjectUtils.isNotEmpty(fieldRowData.get("group_list"))) {
|
||||
fieldDTO.setGroupList(JsonUtil.parseList(fieldRowData.get("group_list").toString(), groupTokenType));
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(fieldRowData.get("params"))) {
|
||||
fieldDTO.setParams(JsonUtil.parseList(fieldRowData.get("params").toString(), typeToken));
|
||||
}
|
||||
fieldDTO.setFieldShortName(fieldDTO.getDataeaseName());
|
||||
return fieldDTO;
|
||||
}).collect(Collectors.toList());
|
||||
@@ -301,8 +313,16 @@ public class DatasetSQLBotManage {
|
||||
}
|
||||
|
||||
Map<String, Object> sqlMap = null;
|
||||
CoreDatasource coreDatasource = null;
|
||||
String dsType = dsRowData.get("type").toString();
|
||||
Configuration config = null;
|
||||
if (dsType.contains(DatasourceConfiguration.DatasourceType.Excel.name()) || dsType.contains(DatasourceConfiguration.DatasourceType.API.name())) {
|
||||
coreDatasource = deEngine;
|
||||
} else {
|
||||
coreDatasource = BeanUtils.mapToBean(dsRowData, CoreDatasource.class);
|
||||
}
|
||||
try {
|
||||
sqlMap = datasetSQLManage.getUnionSQLForEdit(datasetGroupInfoDTO, null);
|
||||
sqlMap = datasetSQLManage.getUnionSQLForEdit(datasetGroupInfoDTO, null, coreDatasource);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -357,7 +377,7 @@ public class DatasetSQLBotManage {
|
||||
Order2SQLObj.getOrders(sqlMeta, datasetGroupInfoDTO.getSortFields(), fields, false, dsMap, Utils.getParams(fields), null, pluginManage);
|
||||
String querySQL;
|
||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, false);
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, false, dsMap);
|
||||
querySQL = provider.rebuildSQL(querySQL, sqlMeta, false, dsMap, true);
|
||||
table.setSql(querySQL);
|
||||
}
|
||||
|
||||
@@ -371,13 +391,18 @@ public class DatasetSQLBotManage {
|
||||
return;
|
||||
}
|
||||
vos.forEach(vo -> {
|
||||
Map<String, Object> dsRowData = vo.getRowData();
|
||||
List<SQLBotAssistanTable> tables = vo.getTables();
|
||||
tables.forEach(table -> {
|
||||
Long datasetGroupId = table.getDatasetGroupId();
|
||||
List<DataSetColumnPermissionsDTO> columnPermissionsDTOS = ObjectUtils.isEmpty(colPermissionMap) ? null : colPermissionMap.get(datasetGroupId);
|
||||
List<DataSetRowPermissionsTreeDTO> rowPermissionsTreeDTOS = ObjectUtils.isEmpty(rowPermissionMap) ? null : rowPermissionMap.get(datasetGroupId);
|
||||
if (table.isNeedTransform() || ObjectUtils.isNotEmpty(columnPermissionsDTOS) || ObjectUtils.isNotEmpty(rowPermissionsTreeDTOS)) {
|
||||
rebuildTable(table, columnPermissionsDTOS, rowPermissionsTreeDTOS);
|
||||
try {
|
||||
rebuildTable(table, columnPermissionsDTOS, rowPermissionsTreeDTOS, dsRowData);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -416,16 +441,17 @@ public class DatasetSQLBotManage {
|
||||
dsHost = environment.getProperty("dataease.dataease-servers", String.class);
|
||||
}
|
||||
String dsType = row.get("cd_type").toString();
|
||||
String config_json = null;
|
||||
Configuration config = null;
|
||||
if (dsType.contains(DatasourceConfiguration.DatasourceType.Excel.name()) || dsType.contains(DatasourceConfiguration.DatasourceType.API.name())) {
|
||||
String config_json = EncryptUtils.aesDecrypt(deEngine.getConfiguration()).toString();
|
||||
config_json = EncryptUtils.aesDecrypt(deEngine.getConfiguration()).toString();
|
||||
config = JsonUtil.parseObject(config_json, Configuration.class);
|
||||
if (StringUtils.isNotBlank(dsHost) && ObjectUtils.isNotEmpty(config)) {
|
||||
config.setHost(dsHost);
|
||||
}
|
||||
dsType = deEngine.getType();
|
||||
} else {
|
||||
String config_json = EncryptUtils.aesDecrypt(dsConfig.toString()).toString();
|
||||
config_json = EncryptUtils.aesDecrypt(dsConfig.toString()).toString();
|
||||
config = JsonUtil.parseObject(config_json, Configuration.class);
|
||||
}
|
||||
DataSQLBotAssistantVO vo = new DataSQLBotAssistantVO();
|
||||
@@ -439,7 +465,10 @@ public class DatasetSQLBotManage {
|
||||
vo.setSchema(config.getSchema());
|
||||
vo.setUser(config.getUsername());
|
||||
vo.setPassword(config.getPassword());
|
||||
vo.setRowData(buildRowData(row, 0));
|
||||
row.put("cd_configuration", config_json);
|
||||
Map<String, Object> rowData = buildRowData(row, 0);
|
||||
rowData.put("id", Long.parseLong(row.get("cd_id").toString()));
|
||||
vo.setRowData(rowData);
|
||||
if (encryptEnabled) {
|
||||
aesVO(vo);
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public class DatasetSQLManage {
|
||||
}
|
||||
|
||||
public Map<String, Object> getUnionSQLForEdit(DatasetGroupInfoDTO dataTableInfoDTO, ChartExtRequest chartExtRequest) throws Exception {
|
||||
return getUnionSQLForEdit(dataTableInfoDTO, chartExtRequest, null);
|
||||
}
|
||||
|
||||
public Map<String, Object> getUnionSQLForEdit(DatasetGroupInfoDTO dataTableInfoDTO, ChartExtRequest chartExtRequest, CoreDatasource coreDatasource) throws Exception {
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = new LinkedHashMap<>();
|
||||
List<UnionDTO> union = dataTableInfoDTO.getUnion();
|
||||
// 所有选中的字段,即select后的查询字段
|
||||
@@ -146,7 +150,7 @@ public class DatasetSQLManage {
|
||||
if (dsMap.containsKey(datasetTable.getDatasourceId())) {
|
||||
schema = dsMap.get(datasetTable.getDatasourceId()).getSchemaAlias();
|
||||
} else {
|
||||
schema = putObj2Map(dsMap, datasetTable, isCross);
|
||||
schema = putObj2Map(dsMap, datasetTable, isCross, coreDatasource);
|
||||
}
|
||||
SQLObj table = getUnionTable(datasetTable, tableInfo, schema, i, filterParameters(chartExtRequest, currentDs.getId()), chartExtRequest == null, isCross, dsMap);
|
||||
if (i == 0) {
|
||||
@@ -491,24 +495,29 @@ public class DatasetSQLManage {
|
||||
}
|
||||
|
||||
public String putObj2Map(Map<Long, DatasourceSchemaDTO> dsMap, DatasetTableDTO ds, boolean isCross) {
|
||||
return putObj2Map(dsMap, ds, isCross, null);
|
||||
}
|
||||
public String putObj2Map(Map<Long, DatasourceSchemaDTO> dsMap, DatasetTableDTO ds, boolean isCross, CoreDatasource coreDatasource) {
|
||||
// 通过datasource id校验数据源权限
|
||||
BusiPerCheckDTO dto = new BusiPerCheckDTO();
|
||||
dto.setId(ds.getDatasourceId());
|
||||
dto.setAuthEnum(AuthEnum.READ);
|
||||
boolean checked = corePermissionManage.checkAuth(dto);
|
||||
if (!checked) {
|
||||
DEException.throwException(Translator.get("i18n_no_datasource_permission"));
|
||||
if (ObjectUtils.isEmpty(coreDatasource)) {
|
||||
BusiPerCheckDTO dto = new BusiPerCheckDTO();
|
||||
dto.setId(ds.getDatasourceId());
|
||||
dto.setAuthEnum(AuthEnum.READ);
|
||||
boolean checked = corePermissionManage.checkAuth(dto);
|
||||
if (!checked) {
|
||||
DEException.throwException(Translator.get("i18n_no_datasource_permission"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String schemaAlias;
|
||||
if (StringUtils.equalsIgnoreCase(ds.getType(), DatasetTableType.DB) || StringUtils.equalsIgnoreCase(ds.getType(), DatasetTableType.SQL)) {
|
||||
CoreDatasource coreDatasource = dataSourceManage.getCoreDatasource(ds.getDatasourceId());
|
||||
if (coreDatasource == null) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_ds_error") + ",ID:" + ds.getDatasourceId());
|
||||
}
|
||||
if (coreDatasource.getType().contains(DatasourceConfiguration.DatasourceType.Excel.name()) || coreDatasource.getType().contains(DatasourceConfiguration.DatasourceType.API.name())) {
|
||||
coreDatasource = engineManage.getDeEngine();
|
||||
if (ObjectUtils.isEmpty(coreDatasource)) {
|
||||
coreDatasource = dataSourceManage.getCoreDatasource(ds.getDatasourceId());
|
||||
if (coreDatasource == null) {
|
||||
DEException.throwException(Translator.get("i18n_dataset_ds_error") + ",ID:" + ds.getDatasourceId());
|
||||
}
|
||||
if (coreDatasource.getType().contains(DatasourceConfiguration.DatasourceType.Excel.name()) || coreDatasource.getType().contains(DatasourceConfiguration.DatasourceType.API.name())) {
|
||||
coreDatasource = engineManage.getDeEngine();
|
||||
}
|
||||
}
|
||||
|
||||
Map map = JsonUtil.parseObject(coreDatasource.getConfiguration(), Map.class);
|
||||
@@ -525,7 +534,9 @@ public class DatasetSQLManage {
|
||||
dsMap.put(coreDatasource.getId(), datasourceSchemaDTO);
|
||||
}
|
||||
} else if (StringUtils.equalsIgnoreCase(ds.getType(), DatasetTableType.Es)) {
|
||||
CoreDatasource coreDatasource = dataSourceManage.getCoreDatasource(ds.getDatasourceId());
|
||||
if (ObjectUtils.isEmpty(coreDatasource)) {
|
||||
coreDatasource = dataSourceManage.getCoreDatasource(ds.getDatasourceId());
|
||||
}
|
||||
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
|
||||
if (!dsMap.containsKey(coreDatasource.getId())) {
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||
@@ -534,7 +545,9 @@ public class DatasetSQLManage {
|
||||
dsMap.put(coreDatasource.getId(), datasourceSchemaDTO);
|
||||
}
|
||||
} else {
|
||||
CoreDatasource coreDatasource = engineManage.getDeEngine();
|
||||
if (ObjectUtils.isEmpty(coreDatasource)) {
|
||||
coreDatasource = engineManage.getDeEngine();
|
||||
}
|
||||
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
|
||||
if (!dsMap.containsKey(coreDatasource.getId())) {
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||
|
||||
@@ -108,16 +108,75 @@ public class BeanUtils {
|
||||
|
||||
// 查找Map中对应的key(支持驼峰和下划线)
|
||||
Object value = findValueInMap(map, propertyName);
|
||||
|
||||
// 只有当值存在且有写入方法时才设置属性
|
||||
if (value != null && descriptor.getWriteMethod() != null) {
|
||||
descriptor.getWriteMethod().invoke(bean, value);
|
||||
try {
|
||||
// 可选:添加类型转换逻辑来处理类型不匹配的情况
|
||||
Object convertedValue = convertTypeIfNeeded(value, descriptor.getPropertyType());
|
||||
descriptor.getWriteMethod().invoke(bean, convertedValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 类型不匹配时跳过该属性,而不是抛出异常
|
||||
System.err.println("类型不匹配跳过属性: " + propertyName + ", 期望类型: " +
|
||||
descriptor.getPropertyType() + ", 实际类型: " + value.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Map转Bean失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convertTypeIfNeeded(Object value, Class<?> targetType) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果类型匹配,直接返回
|
||||
if (targetType.isInstance(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// 添加常见的类型转换逻辑
|
||||
try {
|
||||
if (targetType == String.class) {
|
||||
return value.toString();
|
||||
} else if (targetType == Integer.class || targetType == int.class) {
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).intValue();
|
||||
} else {
|
||||
return Integer.parseInt(value.toString());
|
||||
}
|
||||
} else if (targetType == Long.class || targetType == long.class) {
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
} else {
|
||||
return Long.parseLong(value.toString());
|
||||
}
|
||||
} else if (targetType == Double.class || targetType == double.class) {
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).doubleValue();
|
||||
} else {
|
||||
return Double.parseDouble(value.toString());
|
||||
}
|
||||
} else if (targetType == Boolean.class || targetType == boolean.class) {
|
||||
if (value instanceof Boolean) {
|
||||
return value;
|
||||
} else {
|
||||
return Boolean.parseBoolean(value.toString());
|
||||
}
|
||||
}
|
||||
// 可以继续添加其他类型的转换...
|
||||
} catch (Exception e) {
|
||||
// 转换失败时返回原值,让后续逻辑处理
|
||||
System.err.println("类型转换失败: " + value + " to " + targetType);
|
||||
}
|
||||
|
||||
return value; // 无法转换时返回原值
|
||||
}
|
||||
|
||||
private static Object findValueInMap(Map<String, Object> map, String propertyName) {
|
||||
Object value = map.get(propertyName);
|
||||
if (value != null) return value;
|
||||
|
||||
@@ -123,12 +123,15 @@ public abstract class Provider {
|
||||
}
|
||||
|
||||
public String rebuildSQL(String sql, SQLMeta sqlMeta, boolean crossDs, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
return rebuildSQL(sql, sqlMeta, crossDs, dsMap, false);
|
||||
}
|
||||
public String rebuildSQL(String sql, SQLMeta sqlMeta, boolean crossDs, Map<Long, DatasourceSchemaDTO> dsMap, boolean forSqlbot) {
|
||||
logger.debug("calcite sql: " + sql);
|
||||
if (crossDs) {
|
||||
return sql;
|
||||
}
|
||||
|
||||
String s = transSqlDialect(sql, dsMap);
|
||||
String s = transSqlDialect(sql, dsMap, forSqlbot);
|
||||
String tableDialect = sqlMeta.getTableDialect();
|
||||
s = replaceTablePlaceHolder(s, tableDialect);
|
||||
s = replaceCalcFieldPlaceHolder(s, sqlMeta);
|
||||
@@ -136,11 +139,18 @@ public abstract class Provider {
|
||||
}
|
||||
|
||||
public String transSqlDialect(String sql, Map<Long, DatasourceSchemaDTO> dsMap) throws DEException {
|
||||
return transSqlDialect(sql, dsMap, false);
|
||||
}
|
||||
public String transSqlDialect(String sql, Map<Long, DatasourceSchemaDTO> dsMap, boolean forSqlbot) throws DEException {
|
||||
DatasourceSchemaDTO value = dsMap.entrySet().iterator().next().getValue();
|
||||
try (ConnectionObj connection = getConnection(value)) {
|
||||
// 获取数据库version
|
||||
if (connection != null) {
|
||||
value.setDsVersion(connection.getConnection().getMetaData().getDatabaseMajorVersion());
|
||||
ConnectionObj connection = null;
|
||||
try {
|
||||
if (!forSqlbot) {
|
||||
connection = getConnection(value);
|
||||
// 获取数据库version
|
||||
if (connection != null) {
|
||||
value.setDsVersion(connection.getConnection().getMetaData().getDatabaseMajorVersion());
|
||||
}
|
||||
}
|
||||
SqlParser parser = SqlParser.create(sql, SqlParser.Config.DEFAULT.withLex(Lex.JAVA));
|
||||
SqlNode sqlNode = parser.parseStmt();
|
||||
@@ -151,6 +161,14 @@ public abstract class Provider {
|
||||
return dialect;
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(e.getMessage());
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user