You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.7 KiB
159 lines
5.7 KiB
'use strict';
|
|
|
|
const { VALIDATED_QUERY_BLOCK_TYPES } = require('./constants');
|
|
const { hasOwn, toInt, ensureObjectPayload } = require('./helpers');
|
|
const { ensureDataSource, ensureInstance, ensureTemplate } = require('./repository');
|
|
const clickhouse = require('./clickhouse');
|
|
const dataease = require('./dataease');
|
|
|
|
const resolveDataSourceType = dataSource => String(dataSource?.type || '').trim().toLowerCase();
|
|
|
|
const getAdapterByType = type => {
|
|
switch (type) {
|
|
case 'clickhouse':
|
|
return clickhouse;
|
|
case 'dataease':
|
|
return dataease;
|
|
default:
|
|
throw `unsupported data source type: ${type}`;
|
|
}
|
|
};
|
|
|
|
const getAdapterByDataSource = dataSource => {
|
|
return getAdapterByType(resolveDataSourceType(dataSource));
|
|
};
|
|
|
|
const getDataSourceTables = async (ctx, dataSourceId, transaction = null) => {
|
|
const dataSource = await ensureDataSource(ctx, dataSourceId, transaction);
|
|
const adapter = getAdapterByDataSource(dataSource);
|
|
|
|
if (resolveDataSourceType(dataSource) === 'clickhouse') {
|
|
const payload = await adapter.listClickHouseTables(ctx, dataSource, transaction);
|
|
return { sourceType: 'clickhouse', ...payload };
|
|
}
|
|
|
|
const rows = await adapter.listDataEaseDatasets(ctx, dataSource);
|
|
return {
|
|
sourceType: 'dataease',
|
|
dataSourceId: toInt(dataSourceId),
|
|
clientKey: null,
|
|
database: null,
|
|
rows,
|
|
};
|
|
};
|
|
|
|
const getDataSourceTableColumns = async (ctx, dataSourceId, tableId, transaction = null) => {
|
|
const dataSource = await ensureDataSource(ctx, dataSourceId, transaction);
|
|
const type = resolveDataSourceType(dataSource);
|
|
const adapter = getAdapterByDataSource(dataSource);
|
|
|
|
if (type === 'clickhouse') {
|
|
const payload = await adapter.getClickHouseTableColumnsPayload(ctx, dataSource, tableId, transaction);
|
|
return { sourceType: 'clickhouse', ...payload };
|
|
}
|
|
|
|
const payload = await adapter.getDataEaseDatasetColumns(ctx, dataSource, tableId);
|
|
return {
|
|
sourceType: 'dataease',
|
|
dataSourceId: toInt(dataSourceId),
|
|
clientKey: payload.clientKey,
|
|
database: payload.database,
|
|
table: payload.datasetId,
|
|
datasetName: payload.datasetName,
|
|
rows: payload.rows,
|
|
};
|
|
};
|
|
|
|
const previewDataSourceQuery = async (ctx, dataSourceId, rawDsl, transaction = null) => {
|
|
const dataSource = await ensureDataSource(ctx, dataSourceId, transaction);
|
|
const type = resolveDataSourceType(dataSource);
|
|
const adapter = getAdapterByDataSource(dataSource);
|
|
|
|
if (type === 'clickhouse') {
|
|
const payload = await adapter.previewClickHouseQuery(ctx, dataSource, rawDsl, transaction);
|
|
return {
|
|
sourceType: 'clickhouse',
|
|
dataSourceId: toInt(dataSourceId),
|
|
...payload,
|
|
};
|
|
}
|
|
|
|
const payload = await adapter.previewDataEaseQuery(ctx, dataSource, rawDsl);
|
|
return {
|
|
...payload,
|
|
dataSourceId: toInt(dataSourceId),
|
|
};
|
|
};
|
|
|
|
const normalizeBlockConfigForDataSource = async (ctx, dataSourceId, blockType, config, transaction = null) => {
|
|
const normalizedBlockType = String(blockType || 'text').trim().toLowerCase();
|
|
if (!VALIDATED_QUERY_BLOCK_TYPES.has(normalizedBlockType)) {
|
|
if (config === null || config === undefined) return {};
|
|
return ensureObjectPayload(config, 'config');
|
|
}
|
|
|
|
const safeConfig = ensureObjectPayload(config, 'config');
|
|
const dslPayload = hasOwn(safeConfig, 'query')
|
|
? ensureObjectPayload(safeConfig.query, 'config.query')
|
|
: safeConfig;
|
|
|
|
const parsedDataSourceId = toInt(dataSourceId);
|
|
if (!parsedDataSourceId) throw 'missing param: dataSourceId';
|
|
|
|
const dataSource = await ensureDataSource(ctx, parsedDataSourceId, transaction);
|
|
const type = resolveDataSourceType(dataSource);
|
|
|
|
let normalizedDsl = null;
|
|
if (type === 'clickhouse') {
|
|
const dataSourceContext = await clickhouse.resolveClickHouseDataSourceContext(ctx, parsedDataSourceId, transaction);
|
|
normalizedDsl = await clickhouse.validateStructuredQueryDsl(dataSourceContext, dslPayload);
|
|
} else if (type === 'dataease') {
|
|
normalizedDsl = (await dataease.validateDataEaseStructuredQueryDsl(ctx, dataSource, dslPayload)).normalizedDsl;
|
|
} else {
|
|
throw `unsupported data source type: ${type}`;
|
|
}
|
|
|
|
if (hasOwn(safeConfig, 'query')) {
|
|
return {
|
|
...safeConfig,
|
|
dataSourceId: parsedDataSourceId,
|
|
query: {
|
|
...normalizedDsl,
|
|
dataSourceId: parsedDataSourceId,
|
|
},
|
|
};
|
|
}
|
|
|
|
return {
|
|
...safeConfig,
|
|
...normalizedDsl,
|
|
dataSourceId: parsedDataSourceId,
|
|
};
|
|
};
|
|
|
|
const normalizeBlockConfigForStorage = async (ctx, instanceId, blockType, config, transaction = null) => {
|
|
const instance = await ensureInstance(ctx, instanceId, transaction);
|
|
const safeConfig = ensureObjectPayload(config || {}, 'config');
|
|
const dslPayload = hasOwn(safeConfig, 'query')
|
|
? ensureObjectPayload(safeConfig.query, 'config.query')
|
|
: safeConfig;
|
|
const dataSourceId = toInt(instance.dataSourceId || dslPayload.dataSourceId || safeConfig.dataSourceId);
|
|
return normalizeBlockConfigForDataSource(ctx, dataSourceId, blockType, safeConfig, transaction);
|
|
};
|
|
|
|
const normalizeTemplateBlockConfigForStorage = async (ctx, templateId, blockType, config, transaction = null) => {
|
|
const template = await ensureTemplate(ctx, templateId, transaction);
|
|
const safeConfig = ensureObjectPayload(config || {}, 'config');
|
|
const dataSourceId = toInt(template.dataSourceId);
|
|
if (!dataSourceId) throw '模板未绑定数据源';
|
|
return normalizeBlockConfigForDataSource(ctx, dataSourceId, blockType, safeConfig, transaction);
|
|
};
|
|
|
|
module.exports = {
|
|
getDataSourceTables,
|
|
getDataSourceTableColumns,
|
|
previewDataSourceQuery,
|
|
normalizeBlockConfigForDataSource,
|
|
normalizeBlockConfigForStorage,
|
|
normalizeTemplateBlockConfigForStorage,
|
|
};
|
|
|