forked from github/dataease
refactor: 数据源插件优化
This commit is contained in:
parent
95fd1f5295
commit
7cf6db3d94
@ -90,7 +90,7 @@ public class DatasetDataManage {
|
||||
}
|
||||
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||
datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId()));
|
||||
Provider provider = ProviderFactory.getDefaultProvider();
|
||||
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||
@ -149,9 +149,9 @@ public class DatasetDataManage {
|
||||
dto.setChecked(defaultStatus);
|
||||
dto.setType(ele.getType());
|
||||
int deType = FieldUtils.transType2DeType(ele.getType());
|
||||
dto.setDeExtractType(deType);
|
||||
dto.setDeType(deType);
|
||||
dto.setGroupType(FieldUtils.transDeType2DQ(deType));
|
||||
dto.setDeExtractType(ObjectUtils.isEmpty(ele.getDeExtractType()) ? deType : ele.getDeExtractType());
|
||||
dto.setDeType(ObjectUtils.isEmpty(ele.getDeType()) ? deType : ele.getDeType());
|
||||
dto.setGroupType(FieldUtils.transDeType2DQ(dto.getDeType()));
|
||||
dto.setExtField(0);
|
||||
dto.setDescription(StringUtils.isNotEmpty(ele.getName()) ? ele.getName() : null);
|
||||
return dto;
|
||||
|
@ -1,13 +1,5 @@
|
||||
package io.dataease.dataset.manage;
|
||||
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLObj;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.view.dto.ChartExtFilterDTO;
|
||||
import io.dataease.extensions.view.dto.ChartExtRequest;
|
||||
import io.dataease.extensions.view.dto.SqlVariableDetails;
|
||||
import io.dataease.api.dataset.union.*;
|
||||
import io.dataease.api.permissions.auth.dto.BusiPerCheckDTO;
|
||||
import io.dataease.commons.utils.SqlparserUtils;
|
||||
@ -22,6 +14,16 @@ import io.dataease.datasource.manage.EngineManage;
|
||||
import io.dataease.engine.constant.ExtFieldConstant;
|
||||
import io.dataease.engine.constant.SQLConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.dto.DsTypeDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLObj;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.datasource.vo.PluginDatasourceType;
|
||||
import io.dataease.extensions.view.dto.ChartExtFilterDTO;
|
||||
import io.dataease.extensions.view.dto.ChartExtRequest;
|
||||
import io.dataease.extensions.view.dto.SqlVariableDetails;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.system.manage.CorePermissionManage;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
@ -135,7 +137,7 @@ public class DatasetSQLManage {
|
||||
prefix = "`";
|
||||
suffix = "`";
|
||||
} else {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
prefix = datasourceType.getPrefix();
|
||||
suffix = datasourceType.getSuffix();
|
||||
}
|
||||
@ -188,7 +190,7 @@ public class DatasetSQLManage {
|
||||
tablePrefix = "`";
|
||||
tableSuffix = "`";
|
||||
} else {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = getDatasourceType(dsMap, currentDs1.getDatasourceId());
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, currentDs1.getDatasourceId());
|
||||
tablePrefix = datasourceType.getPrefix();
|
||||
tableSuffix = datasourceType.getSuffix();
|
||||
}
|
||||
@ -214,7 +216,7 @@ public class DatasetSQLManage {
|
||||
pPrefix = "`";
|
||||
pSuffix = "`";
|
||||
} else {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = getDatasourceType(dsMap, parentDs.getDatasourceId());
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, parentDs.getDatasourceId());
|
||||
pPrefix = datasourceType.getPrefix();
|
||||
pSuffix = datasourceType.getSuffix();
|
||||
}
|
||||
@ -226,7 +228,7 @@ public class DatasetSQLManage {
|
||||
cPrefix = "`";
|
||||
cSuffix = "`";
|
||||
} else {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = getDatasourceType(dsMap, currentDs1.getDatasourceId());
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, currentDs1.getDatasourceId());
|
||||
cPrefix = datasourceType.getPrefix();
|
||||
cSuffix = datasourceType.getSuffix();
|
||||
}
|
||||
@ -305,7 +307,7 @@ public class DatasetSQLManage {
|
||||
prefix = "`";
|
||||
suffix = "`";
|
||||
} else {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
DsTypeDTO datasourceType = getDatasourceType(dsMap, datasetTable.getDatasourceId());
|
||||
prefix = datasourceType.getPrefix();
|
||||
suffix = datasourceType.getSuffix();
|
||||
}
|
||||
@ -348,7 +350,7 @@ public class DatasetSQLManage {
|
||||
}
|
||||
}
|
||||
|
||||
private DatasourceConfiguration.DatasourceType getDatasourceType(Map<Long, DatasourceSchemaDTO> dsMap, Long datasourceId) {
|
||||
private DsTypeDTO getDatasourceType(Map<Long, DatasourceSchemaDTO> dsMap, Long datasourceId) {
|
||||
DatasourceSchemaDTO datasourceSchemaDTO = dsMap.get(datasourceId);
|
||||
String type;
|
||||
if (datasourceSchemaDTO == null) {
|
||||
@ -360,7 +362,17 @@ public class DatasetSQLManage {
|
||||
} else {
|
||||
type = datasourceSchemaDTO.getType();
|
||||
}
|
||||
return DatasourceConfiguration.DatasourceType.valueOf(type);
|
||||
if (Arrays.stream(DatasourceConfiguration.DatasourceType.values()).map(DatasourceConfiguration.DatasourceType::getType).toList().contains(type)) {
|
||||
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(type);
|
||||
DsTypeDTO dto = new DsTypeDTO();
|
||||
BeanUtils.copyBean(dto, datasourceType);
|
||||
return dto;
|
||||
} else {
|
||||
PluginDatasourceType.DatasourceType datasourceType = PluginDatasourceType.DatasourceType.valueOf(type);
|
||||
DsTypeDTO dto = new DsTypeDTO();
|
||||
BeanUtils.copyBean(dto, datasourceType);
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
public String subPrefixSuffixChar(String str) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package io.dataease.dataset.utils;
|
||||
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.dto.DsTypeDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLObj;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.utils.Md5Utils;
|
||||
import org.apache.calcite.avatica.util.Quoting;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -39,7 +39,7 @@ public class TableUtils {
|
||||
return "C_" + Md5Utils.md5(fieldName);
|
||||
}
|
||||
|
||||
public static String getTableAndAlias(SQLObj sqlObj, DatasourceConfiguration.DatasourceType datasourceType, boolean isCross) {
|
||||
public static String getTableAndAlias(SQLObj sqlObj, DsTypeDTO datasourceType, boolean isCross) {
|
||||
String schema = "";
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
|
@ -11,6 +11,8 @@ import io.dataease.datasource.type.*;
|
||||
import io.dataease.engine.constant.SQLConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.dto.*;
|
||||
import io.dataease.extensions.datasource.provider.DriverShim;
|
||||
import io.dataease.extensions.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.i18n.Translator;
|
||||
@ -24,7 +26,6 @@ import org.apache.calcite.adapter.jdbc.JdbcSchema;
|
||||
import org.apache.calcite.jdbc.CalciteConnection;
|
||||
import org.apache.calcite.schema.Schema;
|
||||
import org.apache.calcite.schema.SchemaPlus;
|
||||
import org.apache.calcite.sql.SqlDialect;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -442,6 +443,7 @@ public class CalciteProvider extends Provider {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hidePW(DatasourceDTO datasourceDTO) {
|
||||
DatasourceConfiguration configuration = null;
|
||||
DatasourceConfiguration.DatasourceType datasourceType = DatasourceConfiguration.DatasourceType.valueOf(datasourceDTO.getType());
|
||||
@ -1047,20 +1049,6 @@ public class CalciteProvider extends Provider {
|
||||
}
|
||||
}
|
||||
|
||||
public Statement getStatement(Connection connection, int queryTimeout) {
|
||||
if (connection == null) {
|
||||
DEException.throwException("Failed to get connection!");
|
||||
}
|
||||
Statement stat = null;
|
||||
try {
|
||||
stat = connection.createStatement();
|
||||
stat.setQueryTimeout(queryTimeout);
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(e.getMessage());
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
protected boolean isDefaultClassLoader(String customDriver) {
|
||||
return StringUtils.isEmpty(customDriver) || customDriver.equalsIgnoreCase("default");
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import io.dataease.extensions.datasource.dto.*;
|
||||
import io.dataease.extensions.datasource.factory.ProviderFactory;
|
||||
import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.datasource.vo.PluginDatasourceType;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.job.schedule.CheckDsStatusJob;
|
||||
import io.dataease.job.schedule.ScheduleManager;
|
||||
@ -575,7 +576,8 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
} else {
|
||||
if (hidePw) {
|
||||
calciteProvider.hidePW(datasourceDTO);
|
||||
Provider provider = ProviderFactory.getProvider(datasourceDTO.getType());
|
||||
provider.hidePW(datasourceDTO);
|
||||
}
|
||||
|
||||
}
|
||||
@ -851,7 +853,8 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
|
||||
private void preCheckDs(DatasourceDTO datasource) throws DEException {
|
||||
if (!datasourceTypes().stream().map(DatasourceConfiguration.DatasourceType::getType).toList().contains(datasource.getType())) {
|
||||
if (!datasourceTypes().stream().map(DatasourceConfiguration.DatasourceType::getType).toList().contains(datasource.getType())
|
||||
&& !Arrays.stream(PluginDatasourceType.DatasourceType.values()).map(PluginDatasourceType.DatasourceType::getType).toList().contains(datasource.getType())) {
|
||||
DEException.throwException("Datasource type not supported.");
|
||||
}
|
||||
}
|
||||
@ -867,7 +870,8 @@ public class DatasourceServer implements DatasourceApi {
|
||||
if (coreDatasource.getType().equals("API")) {
|
||||
status = ApiUtils.checkStatus(datasourceRequest);
|
||||
} else {
|
||||
status = calciteProvider.checkStatus(datasourceRequest);
|
||||
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||
status = provider.checkStatus(datasourceRequest);
|
||||
}
|
||||
coreDatasource.setStatus(status);
|
||||
} catch (Exception e) {
|
||||
|
@ -1200,6 +1200,21 @@ const treeProps = {
|
||||
return (!data.children?.length && !data.leaf) || data.extraFlag < 0
|
||||
}
|
||||
}
|
||||
|
||||
const pluginDs = ref([])
|
||||
const loadDsPlugin = data => {
|
||||
pluginDs.value = data
|
||||
}
|
||||
const getDsIcon = data => {
|
||||
if (pluginDs?.value.length === 0) return null
|
||||
if (!data.leaf) return null
|
||||
|
||||
const arr = pluginDs.value.filter(ele => {
|
||||
return ele.type === data.type
|
||||
})
|
||||
return arr && arr.length > 0 ? arr[0].icon : null
|
||||
}
|
||||
|
||||
const getDsIconName = data => {
|
||||
if (!data.leaf) return 'dv-folder'
|
||||
return `${data.type}-ds`
|
||||
@ -1280,7 +1295,10 @@ const getDsIconName = data => {
|
||||
<template #default="{ data: { name, leaf, type, extraFlag } }">
|
||||
<div class="flex-align-center icon">
|
||||
<el-icon>
|
||||
<icon :name="getDsIconName({ leaf, type })"></icon>
|
||||
<icon
|
||||
:static-content="getDsIcon({ leaf, type })"
|
||||
:name="getDsIconName({ leaf, type })"
|
||||
></icon>
|
||||
</el-icon>
|
||||
<span v-if="!leaf || extraFlag > -1">{{ name }}</span>
|
||||
<el-tooltip effect="dark" v-else :content="`无效数据源:${name}`" placement="top">
|
||||
@ -1975,6 +1993,10 @@ const getDsIconName = data => {
|
||||
@loaded="XpackLoaded"
|
||||
@load-fail="XpackLoaded"
|
||||
/>
|
||||
<XpackComponent
|
||||
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
|
||||
@load-ds-plugin="loadDsPlugin"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -1,6 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, PropType, computed } from 'vue'
|
||||
import { dsTypes, typeList, nameMap } from './option'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
|
||||
export type DsType = 'OLTP' | 'OLAP' | 'DL' | 'OTHER' | 'LOCAL' | 'latestUse' | 'all'
|
||||
const props = defineProps({
|
||||
@ -80,6 +82,25 @@ const getDatasourceTypes = () => {
|
||||
})
|
||||
}
|
||||
getDatasourceTypes()
|
||||
const loadDsPlugin = data => {
|
||||
data.forEach(item => {
|
||||
const { name, category, type, icon, extraParams, staticMap } = item
|
||||
const node = {
|
||||
name,
|
||||
catalog: category,
|
||||
type,
|
||||
icon,
|
||||
extraParams,
|
||||
isPlugin: true,
|
||||
staticMap
|
||||
}
|
||||
const index = typeList.findIndex(ele => ele === node.catalog)
|
||||
if (index !== -1) {
|
||||
databaseList.value[index].push(node)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const emits = defineEmits(['selectDsType'])
|
||||
const selectDs = ({ type }) => {
|
||||
emits('selectDsType', type)
|
||||
@ -95,12 +116,18 @@ const selectDs = ({ type }) => {
|
||||
<div class="item-container">
|
||||
<div v-for="db in ele.dbList" :key="db.type" class="db-card" @click="selectDs(db)">
|
||||
<el-icon class="icon-border">
|
||||
<Icon :name="`${db.type}-ds`"></Icon>
|
||||
<Icon v-if="db['isPlugin']" :static-content="db.icon"></Icon>
|
||||
<Icon v-else :name="`${db.type}-ds`"></Icon>
|
||||
</el-icon>
|
||||
<p class="db-name">{{ db.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<XpackComponent
|
||||
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
|
||||
@load-ds-plugin="loadDsPlugin"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -0,0 +1,629 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, toRefs, watch } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import type { FormInstance, FormRules } from 'element-plus-secondary'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import type { Configuration, ApiConfiguration, SyncSetting } from './option'
|
||||
import { Base64 } from 'js-base64'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
const { t } = useI18n()
|
||||
const prop = defineProps({
|
||||
form: {
|
||||
required: false,
|
||||
default() {
|
||||
return reactive<{
|
||||
id: number
|
||||
name: string
|
||||
desc: string
|
||||
type: string
|
||||
syncSetting?: SyncSetting
|
||||
configuration?: Configuration
|
||||
apiConfiguration?: ApiConfiguration[]
|
||||
paramsConfiguration?: ApiConfiguration[]
|
||||
}>({
|
||||
id: 0,
|
||||
name: '',
|
||||
desc: '',
|
||||
type: 'API',
|
||||
apiConfiguration: []
|
||||
})
|
||||
},
|
||||
type: Object
|
||||
},
|
||||
|
||||
activeStep: {
|
||||
required: false,
|
||||
default: 1,
|
||||
type: Number
|
||||
}
|
||||
})
|
||||
|
||||
const { form, activeStep } = toRefs(prop)
|
||||
|
||||
const state = reactive({
|
||||
itemRef: []
|
||||
})
|
||||
|
||||
const schemas = ref([])
|
||||
const dsForm = ref<FormInstance>()
|
||||
|
||||
const defaultRule = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.input_name'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 64,
|
||||
message: t('datasource.input_limit_2_25', [2, 64]),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const rule = ref<FormRules>(cloneDeep(defaultRule))
|
||||
const api_table_title = ref('')
|
||||
const editApiItem = ref()
|
||||
const defaultApiItem = {
|
||||
name: '',
|
||||
deTableName: '',
|
||||
url: '',
|
||||
type: '',
|
||||
serialNumber: 0,
|
||||
method: 'GET',
|
||||
request: {
|
||||
headers: [{}],
|
||||
arguments: [],
|
||||
body: {
|
||||
type: '',
|
||||
raw: '',
|
||||
kvs: []
|
||||
},
|
||||
authManager: {
|
||||
verification: '',
|
||||
username: '',
|
||||
password: ''
|
||||
}
|
||||
},
|
||||
fields: []
|
||||
}
|
||||
|
||||
const initForm = type => {
|
||||
form.value.configuration = {
|
||||
dataBase: '',
|
||||
jdbcUrl: '',
|
||||
urlType: 'hostName',
|
||||
extraParams: '',
|
||||
username: '',
|
||||
password: '',
|
||||
host: '',
|
||||
authMethod: '',
|
||||
port: '',
|
||||
initialPoolSize: 5,
|
||||
minPoolSize: 5,
|
||||
maxPoolSize: 5,
|
||||
queryTimeout: 30
|
||||
}
|
||||
schemas.value = []
|
||||
rule.value = cloneDeep(defaultRule)
|
||||
setRules()
|
||||
|
||||
form.value.type = type
|
||||
setTimeout(() => {
|
||||
dsForm.value.clearValidate()
|
||||
}, 0)
|
||||
}
|
||||
|
||||
const setRules = () => {
|
||||
const configRules = {
|
||||
'configuration.jdbcUrl': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_input_jdbc_url'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.dataBase': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_input_data_base'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.authMethod': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_select_oracle_type'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.username': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_input_user_name'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.password': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_input_password'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.host': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource._ip_address'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.extraParams': [
|
||||
{
|
||||
required: false,
|
||||
message: t('datasource.please_input_url'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.port': [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_input_port'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.initialPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputText') + t('datasource.initial_pool_size'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.minPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputText') + t('datasource.min_pool_size'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.maxPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputText') + t('datasource.max_pool_size'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.queryTimeout': [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.inputText') + t('datasource.query_timeout'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
if (['oracle', 'sqlServer', 'pg', 'redshift', 'db2'].includes(form.value.type)) {
|
||||
configRules['configuration.schema'] = [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.please_choose_schema'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
if (form.value.type === 'oracle') {
|
||||
configRules['configuration.connectionType'] = [
|
||||
{
|
||||
required: true,
|
||||
message: t('datasource.connection_mode'),
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
}
|
||||
rule.value = { ...cloneDeep(configRules), ...cloneDeep(defaultRule) }
|
||||
}
|
||||
|
||||
watch(
|
||||
() => form.value.type,
|
||||
val => {
|
||||
if (val !== 'API') {
|
||||
rule.value = cloneDeep(defaultRule)
|
||||
setRules()
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
const activeName = ref('table')
|
||||
const showPriority = ref(false)
|
||||
|
||||
const submitForm = () => {
|
||||
dsForm.value.clearValidate()
|
||||
return dsForm.value.validate
|
||||
}
|
||||
|
||||
const clearForm = () => {
|
||||
return dsForm.value.clearValidate()
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
dsForm.value.resetFields()
|
||||
}
|
||||
|
||||
const showSchema = ref(false)
|
||||
|
||||
const validatorSchema = () => {
|
||||
dsForm.value.validateField('configuration.schema')
|
||||
}
|
||||
|
||||
const activeParamsName = ref('')
|
||||
const activeParamsID = ref(0)
|
||||
|
||||
const setActiveName = val => {
|
||||
gridData.value = val.fields
|
||||
activeParamsName.value = val.name
|
||||
activeParamsName.value = val.serialNumber
|
||||
}
|
||||
|
||||
const gridData = ref([])
|
||||
|
||||
defineExpose({
|
||||
submitForm,
|
||||
resetForm,
|
||||
initForm,
|
||||
clearForm
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="editor-detail">
|
||||
<div class="detail-inner create-dialog">
|
||||
<el-form
|
||||
ref="dsForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
label-width="180px"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
>
|
||||
<el-form-item
|
||||
:label="t('auth.datasource') + t('chart.name')"
|
||||
prop="name"
|
||||
v-show="activeStep !== 2"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
autocomplete="off"
|
||||
:placeholder="t('datasource.input_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('common.description')" v-show="activeStep !== 2">
|
||||
<el-input
|
||||
class="description-text"
|
||||
type="textarea"
|
||||
:placeholder="t('common.inputText')"
|
||||
v-model="form.description"
|
||||
:row="10"
|
||||
:maxlength="50"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="t('datasource.host')"
|
||||
prop="configuration.host"
|
||||
v-if="form.configuration.urlType !== 'jdbcUrl'"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.configuration.host"
|
||||
:placeholder="t('datasource._ip_address')"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="t('datasource.port')"
|
||||
prop="configuration.port"
|
||||
v-if="form.configuration.urlType !== 'jdbcUrl'"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.port"
|
||||
autocomplete="off"
|
||||
step-strictly
|
||||
class="text-left"
|
||||
:min="0"
|
||||
:placeholder="t('common.inputText') + t('datasource.port')"
|
||||
controls-position="right"
|
||||
type="number"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="t('datasource.data_base')"
|
||||
prop="configuration.dataBase"
|
||||
v-if="form.configuration.urlType !== 'jdbcUrl'"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.configuration.dataBase"
|
||||
:placeholder="t('datasource.please_input_data_base')"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('datasource.user_name')" v-if="form.type !== 'presto'">
|
||||
<el-input
|
||||
:placeholder="t('common.inputText') + t('datasource.user_name')"
|
||||
v-model="form.configuration.username"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('datasource.password')" v-if="form.type !== 'presto'">
|
||||
<CustomPassword
|
||||
:placeholder="t('common.inputText') + t('datasource.password')"
|
||||
show-password
|
||||
type="password"
|
||||
v-model="form.configuration.password"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="t('datasource.extra_params')"
|
||||
v-if="form.configuration.urlType !== 'jdbcUrl'"
|
||||
>
|
||||
<el-input
|
||||
:placeholder="t('common.inputText') + t('datasource.extra_params')"
|
||||
v-model="form.configuration.extraParams"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<span
|
||||
v-if="!['es', 'api'].includes(form.type)"
|
||||
class="de-expand"
|
||||
@click="showPriority = !showPriority"
|
||||
>{{ t('datasource.priority') }}
|
||||
<el-icon>
|
||||
<Icon :name="showPriority ? 'icon_down_outlined' : 'icon_down_outlined-1'"></Icon>
|
||||
</el-icon>
|
||||
</span>
|
||||
<template v-if="showPriority">
|
||||
<el-row :gutter="24" class="mb16">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="t('datasource.initial_pool_size')"
|
||||
prop="configuration.initialPoolSize"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.initialPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
:placeholder="t('common.inputText') + t('datasource.initial_pool_size')"
|
||||
type="number"
|
||||
:min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="t('datasource.min_pool_size')" prop="configuration.minPoolSize">
|
||||
<el-input-number
|
||||
v-model="form.configuration.minPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
:placeholder="t('common.inputText') + t('datasource.min_pool_size')"
|
||||
type="number"
|
||||
:min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="t('datasource.max_pool_size')" prop="configuration.maxPoolSize">
|
||||
<el-input-number
|
||||
v-model="form.configuration.maxPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
:placeholder="t('common.inputText') + t('datasource.max_pool_size')"
|
||||
type="number"
|
||||
:min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="`${t('datasource.query_timeout')}(${t('common.second')})`"
|
||||
prop="configuration.queryTimeout"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.queryTimeout"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
:placeholder="t('common.inputText') + t('datasource.query_timeout')"
|
||||
type="number"
|
||||
:min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.editor-detail {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.ed-radio {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.mb16 {
|
||||
:deep(.ed-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.execute-rate-cont {
|
||||
border-radius: 4px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
||||
.de-select {
|
||||
width: 100%;
|
||||
}
|
||||
.ed-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.is-controls-right > span) {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.de-expand {
|
||||
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
color: var(--ed-color-primary);
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
.ed-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ed-date-editor.ed-input) {
|
||||
.ed-input__wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
width: 100%;
|
||||
}
|
||||
.simple-cron {
|
||||
height: 32px;
|
||||
.ed-select,
|
||||
.ed-input-number {
|
||||
width: 140px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
.detail-inner {
|
||||
width: 800px;
|
||||
padding-top: 8px;
|
||||
|
||||
.description-text {
|
||||
:deep(.ed-textarea__inner) {
|
||||
height: 92px;
|
||||
}
|
||||
}
|
||||
|
||||
.base-info {
|
||||
margin: 24px 0 16px 0;
|
||||
}
|
||||
|
||||
.left-api_params {
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
border: 1px solid #bbbfc4;
|
||||
width: 300px;
|
||||
padding: 16px;
|
||||
.name-copy {
|
||||
display: none;
|
||||
line-height: 24px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.list-item_primary:hover {
|
||||
.name-copy {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 74% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-api_params {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border: 1px solid #bbbfc4;
|
||||
border-left: none;
|
||||
width: calc(100% - 200px);
|
||||
}
|
||||
|
||||
.table-info-mr {
|
||||
margin: 28px 0 12px 0;
|
||||
.api-tabs {
|
||||
:deep(.ed-tabs__nav-wrap::after) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-update {
|
||||
height: 22px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
justify-content: center;
|
||||
|
||||
.update-info-line {
|
||||
width: 208px;
|
||||
height: 1px;
|
||||
background: #bcbdbf;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.info-text,
|
||||
.update-text {
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
color: #1f2329;
|
||||
font-weight: 400;
|
||||
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
line-height: 22px;
|
||||
&::before {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: 1px solid var(--ed-color-primary);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.active::before {
|
||||
border: none;
|
||||
background: var(--ed-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-operate {
|
||||
text-align: right;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.flex-space {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -2,11 +2,11 @@
|
||||
import { reactive, ref, computed, watch, nextTick } from 'vue'
|
||||
import { ElIcon, ElMessage, ElMessageBox, ElMessageBoxOptions } from 'element-plus-secondary'
|
||||
import CreatDsGroup from './CreatDsGroup.vue'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import type { DsType } from './DsTypeList.vue'
|
||||
import DsTypeList from './DsTypeList.vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import EditorDetail from './EditorDetail.vue'
|
||||
import EditorDetailPlugin from './EditorDetailPlugin.vue'
|
||||
import ExcelDetail from './ExcelDetail.vue'
|
||||
import { save, update, validate, latestUse, isShowFinishPage, checkRepeat } from '@/api/datasource'
|
||||
import { Base64 } from 'js-base64'
|
||||
@ -19,6 +19,9 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import FinishPage from '../FinishPage.vue'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { XpackComponent, PluginComponent } from '@/components/plugin'
|
||||
|
||||
interface Node {
|
||||
name: string
|
||||
id: string
|
||||
@ -70,6 +73,7 @@ const filterText = ref('')
|
||||
const currentDsType = ref('')
|
||||
const emits = defineEmits(['refresh'])
|
||||
const { emitter } = useEmitt()
|
||||
const isPlugin = ref(false)
|
||||
const selectDsType = (type: string) => {
|
||||
currentDsType.value = type
|
||||
activeStep.value = 1
|
||||
@ -83,6 +87,7 @@ const selectDsType = (type: string) => {
|
||||
.some(ele => {
|
||||
if (ele.type === currentDsType.value) {
|
||||
dsTree.value.setCurrentNode(ele)
|
||||
isPlugin.value = ele['isPlugin']
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -93,6 +98,7 @@ const selectDsType = (type: string) => {
|
||||
const handleDsNodeClick = data => {
|
||||
if (!data.type) return
|
||||
selectDsType(data.type)
|
||||
isPlugin.value = data['isPlugin']
|
||||
}
|
||||
const handleNodeClick = (data: Node) => {
|
||||
currentType.value = data.type
|
||||
@ -135,25 +141,33 @@ const getDatasourceTypes = () => {
|
||||
})
|
||||
}
|
||||
getDatasourceTypes()
|
||||
|
||||
const pluginDs = ref([])
|
||||
const loadDsPlugin = data => {
|
||||
pluginDs.value = data
|
||||
data.forEach(item => {
|
||||
const { name, category, type, icon, extraParams, staticMap } = item
|
||||
const node = {
|
||||
name,
|
||||
category,
|
||||
catalog: category,
|
||||
type,
|
||||
icon,
|
||||
extraParams,
|
||||
isPlugin: true,
|
||||
staticMap
|
||||
}
|
||||
|
||||
const index = typeList.findIndex(ele => ele === node.catalog)
|
||||
if (index !== -1) {
|
||||
databaseList[index].push(node)
|
||||
databaseList.value[index].push(node)
|
||||
}
|
||||
})
|
||||
}
|
||||
const getPluginStatic = type => {
|
||||
const arr = pluginDs.value.filter(ele => {
|
||||
return ele.type === type
|
||||
})
|
||||
return arr && arr.length > 0 ? arr[0].staticMap?.index : null
|
||||
}
|
||||
|
||||
const getLatestUseTypes = () => {
|
||||
latestUse({}).then(res => {
|
||||
@ -663,7 +677,8 @@ defineExpose({
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node flex-align-center">
|
||||
<el-icon v-if="!!data.catalog" class="icon-border" style="width: 18px; height: 18px">
|
||||
<Icon :name="`${data.type}-ds`"></Icon>
|
||||
<Icon v-if="data['isPlugin']" :static-content="data.icon"></Icon>
|
||||
<Icon v-else :name="`${data.type}-ds`"></Icon>
|
||||
</el-icon>
|
||||
<span :title="node.label" class="label-tooltip">{{ node.label }}</span>
|
||||
</span>
|
||||
@ -687,8 +702,21 @@ defineExpose({
|
||||
:form="form"
|
||||
:editDs="editDs"
|
||||
:active-step="activeApiStep"
|
||||
v-if="activeStep !== 0 && currentDsType && currentDsType !== 'Excel' && visible"
|
||||
v-if="
|
||||
activeStep !== 0 && currentDsType && currentDsType !== 'Excel' && visible && !isPlugin
|
||||
"
|
||||
></editor-detail>
|
||||
<plugin-component
|
||||
:jsname="getPluginStatic(currentDsType)"
|
||||
ref="detail"
|
||||
:form="form"
|
||||
:editDs="editDs"
|
||||
:active-step="activeApiStep"
|
||||
v-if="
|
||||
activeStep !== 0 && currentDsType && currentDsType !== 'Excel' && visible && isPlugin
|
||||
"
|
||||
>
|
||||
</plugin-component>
|
||||
<template v-if="activeStep !== 0 && currentDsType == 'Excel'">
|
||||
<excel-detail :editDs="editDs" ref="excel" :param="form2"></excel-detail>
|
||||
</template>
|
||||
@ -738,6 +766,11 @@ defineExpose({
|
||||
:name="dsInfo.name"
|
||||
v-if="showFinishPage"
|
||||
></FinishPage>
|
||||
|
||||
<XpackComponent
|
||||
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
|
||||
@load-ds-plugin="loadDsPlugin"
|
||||
/>
|
||||
</div>
|
||||
</el-drawer>
|
||||
<creat-ds-group
|
||||
@ -745,10 +778,6 @@ defineExpose({
|
||||
@finish="complete"
|
||||
ref="creatDsFolder"
|
||||
></creat-ds-group>
|
||||
<XpackComponent
|
||||
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
|
||||
@load-ds-plugin="loadDsPlugin"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -45,6 +45,7 @@ import { interactiveStoreWithOut } from '@/store/modules/interactive'
|
||||
import treeSort from '@/utils/treeSortUtils'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
const route = useRoute()
|
||||
const interactiveStore = interactiveStoreWithOut()
|
||||
interface Field {
|
||||
@ -302,6 +303,26 @@ const showErrorInfo = info => {
|
||||
dialogErrorInfo.value = true
|
||||
}
|
||||
|
||||
const pluginDs = ref([])
|
||||
const loadDsPlugin = data => {
|
||||
pluginDs.value = data
|
||||
}
|
||||
const getDsIcon = data => {
|
||||
if (pluginDs?.value.length === 0) return null
|
||||
if (!data.leaf) return null
|
||||
|
||||
const arr = pluginDs.value.filter(ele => {
|
||||
return ele.type === data.type
|
||||
})
|
||||
return arr && arr.length > 0 ? arr[0].icon : null
|
||||
}
|
||||
const getDsIconType = type => {
|
||||
const arr = pluginDs.value.filter(ele => {
|
||||
return ele.type === type
|
||||
})
|
||||
return arr && arr.length > 0 ? arr[0].icon : null
|
||||
}
|
||||
|
||||
const getDsIconName = data => {
|
||||
if (!data.leaf) return 'dv-folder'
|
||||
return `${data.type}-ds`
|
||||
@ -945,7 +966,7 @@ const getMenuList = (val: boolean) => {
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<el-icon :class="data.leaf && 'icon-border'" style="font-size: 18px">
|
||||
<Icon :name="getDsIconName(data)"></Icon>
|
||||
<Icon :static-content="getDsIcon(data)" :name="getDsIconName(data)"></Icon>
|
||||
</el-icon>
|
||||
<span
|
||||
:title="node.label"
|
||||
@ -1004,7 +1025,10 @@ const getMenuList = (val: boolean) => {
|
||||
<div class="datasource-info">
|
||||
<div class="info-method">
|
||||
<el-icon class="icon-border">
|
||||
<Icon :name="`${nodeInfo.type}-ds`"></Icon>
|
||||
<Icon
|
||||
:static-content="getDsIconType(nodeInfo.type)"
|
||||
:name="`${nodeInfo.type}-ds`"
|
||||
></Icon>
|
||||
</el-icon>
|
||||
<span :title="nodeInfo.name" class="name ellipsis">
|
||||
{{ nodeInfo.name }}
|
||||
@ -1584,6 +1608,11 @@ const getMenuList = (val: boolean) => {
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<XpackComponent
|
||||
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="
|
||||
@load-ds-plugin="loadDsPlugin"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.dataease.extensions.datasource.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
*/
|
||||
@Data
|
||||
public class DsTypeDTO {
|
||||
private String type;
|
||||
private String name;
|
||||
|
||||
private String catalog;
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
}
|
@ -20,12 +20,16 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class ProviderFactory {
|
||||
|
||||
public static Provider getProvider(String type) {
|
||||
public static Provider getProvider(String type) throws DEException {
|
||||
List<String> list = Arrays.stream(DatasourceConfiguration.DatasourceType.values()).map(DatasourceConfiguration.DatasourceType::getType).toList();
|
||||
if (list.contains(type)) {
|
||||
return SpringContextUtil.getApplicationContext().getBean("calciteProvider", Provider.class);
|
||||
}
|
||||
return getInstance(type);
|
||||
Provider instance = getInstance(type);
|
||||
if (instance == null) {
|
||||
DEException.throwException("插件异常,请检查插件");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Provider getDefaultProvider() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.dataease.datasource.provider;
|
||||
package io.dataease.extensions.datasource.provider;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
@ -43,4 +43,4 @@ public class DriverShim implements Driver {
|
||||
public Connection connect(String u, Properties p) throws SQLException {
|
||||
return this.driver.connect(u, p);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.dataease.datasource.provider;
|
||||
package io.dataease.extensions.datasource.provider;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
@ -94,4 +94,4 @@ public class ExtendedJdbcClassLoader extends URLClassLoader {
|
||||
throw new IOException("Error, could not add URL to system classloader");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -38,6 +39,22 @@ public abstract class Provider {
|
||||
|
||||
public abstract List<TableField> fetchTableField(DatasourceRequest datasourceRequest) throws DEException;
|
||||
|
||||
public abstract void hidePW(DatasourceDTO datasourceDTO);
|
||||
|
||||
public Statement getStatement(Connection connection, int queryTimeout) {
|
||||
if (connection == null) {
|
||||
DEException.throwException("Failed to get connection!");
|
||||
}
|
||||
Statement stat = null;
|
||||
try {
|
||||
stat = connection.createStatement();
|
||||
stat.setQueryTimeout(queryTimeout);
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(e.getMessage());
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
public String rebuildSQL(String sql, SQLMeta sqlMeta, boolean crossDs, Map<Long, DatasourceSchemaDTO> dsMap) {
|
||||
logger.info("calcite sql: " + sql);
|
||||
if (crossDs) {
|
||||
|
@ -0,0 +1,54 @@
|
||||
package io.dataease.extensions.datasource.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
*/
|
||||
@Data
|
||||
public class PluginDatasourceType extends Configuration {
|
||||
private List<String> illegalParameters;
|
||||
private List<String> showTableSqls;
|
||||
|
||||
|
||||
static public enum DatasourceType {
|
||||
hive("hive", "Apache Hive", "DL", "`", "`");
|
||||
|
||||
private String type;
|
||||
private String name;
|
||||
|
||||
private String catalog;
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
|
||||
DatasourceType(String type, String name, String catalog, String prefix, String suffix) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.catalog = catalog;
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCatalog() {
|
||||
return catalog;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user