feat(elasticsearch): 补齐新建连接入口

- 前端连接弹窗新增 Elasticsearch 入口、默认端口、URI 示例和默认索引配置

- 补齐 Elasticsearch 图标、数据源能力、SQL dialect 和只读查询策略

- 后端驱动管理注册 Elasticsearch 版本、模块路径、构建标签和默认安装入口

- 增加连接展示、能力识别和驱动定义测试覆盖
This commit is contained in:
Syngnat
2026-06-02 15:31:00 +08:00
parent 864ad8a371
commit c315ea9c96
13 changed files with 240 additions and 46 deletions

View File

@@ -86,6 +86,7 @@ describe('connectionModalPresentation', () => {
'opengauss',
'iris',
'mongodb',
'elasticsearch',
'redis',
'tdengine',
'custom',
@@ -147,10 +148,19 @@ describe('connectionModalPresentation', () => {
'credentials',
'databaseScope',
]);
expect(resolveConnectionConfigLayout('elasticsearch').sections).toEqual([
'identity',
'uri',
'target',
'service',
'credentials',
'databaseScope',
]);
});
it('uses localized labels for layout kinds shown in the modal', () => {
expect(getConnectionConfigLayoutKindLabel('mysql-compatible')).toBe('MySQL 兼容');
expect(getConnectionConfigLayoutKindLabel('file')).toBe('文件型数据库');
expect(getConnectionConfigLayoutKindLabel('search')).toBe('搜索引擎');
});
});

View File

@@ -39,6 +39,7 @@ export type ConnectionConfigLayoutKind =
| 'postgres-compatible'
| 'oracle'
| 'file'
| 'search'
| 'custom'
| 'jvm'
| 'generic-sql';
@@ -157,6 +158,8 @@ export const getConnectionConfigLayoutKindLabel = (
return 'Oracle 服务';
case 'file':
return '文件型数据库';
case 'search':
return '搜索引擎';
case 'custom':
return '自定义连接';
case 'jvm':
@@ -233,6 +236,19 @@ export const resolveConnectionConfigLayout = (
],
};
}
if (type === 'elasticsearch') {
return {
kind: 'search',
sections: [
'identity',
'uri',
'target',
'service',
'credentials',
'databaseScope',
],
};
}
if (postgresCompatibleTypes.has(type)) {
return {
kind: 'postgres-compatible',

View File

@@ -54,6 +54,24 @@ describe('dataSourceCapabilities', () => {
});
});
it('treats Elasticsearch as a queryable read-only datasource', () => {
expect(getDataSourceCapabilities({ type: 'elasticsearch' })).toMatchObject({
type: 'elasticsearch',
supportsQueryEditor: true,
supportsSqlQueryExport: false,
supportsCopyInsert: false,
supportsCreateDatabase: false,
supportsRenameDatabase: false,
supportsDropDatabase: false,
forceReadOnlyQueryResult: true,
});
expect(getDataSourceCapabilities({ type: 'custom', driver: 'elastic' })).toMatchObject({
type: 'elasticsearch',
supportsQueryEditor: true,
forceReadOnlyQueryResult: true,
});
});
it('treats OceanBase Oracle protocol as Oracle capabilities', () => {
expect(getDataSourceCapabilities({
type: 'oceanbase',

View File

@@ -18,6 +18,9 @@ const normalizeDataSourceToken = (raw: string): string => {
return 'opengauss';
case 'dm':
return 'dameng';
case 'elastic':
case 'elasticsearch':
return 'elasticsearch';
case 'intersystems':
case 'intersystemsiris':
case 'inter-systems':
@@ -89,7 +92,7 @@ const COPY_INSERT_TYPES = new Set([
]);
const QUERY_EDITOR_DISABLED_TYPES = new Set(['redis']);
const FORCE_READ_ONLY_QUERY_TYPES = new Set(['tdengine', 'clickhouse']);
const FORCE_READ_ONLY_QUERY_TYPES = new Set(['tdengine', 'clickhouse', 'elasticsearch']);
const MANUAL_TOTAL_COUNT_TYPES = new Set(['duckdb', 'oracle']);
const APPROXIMATE_TABLE_COUNT_TYPES = new Set(['duckdb', 'oracle']);
const APPROXIMATE_TOTAL_PAGE_TYPES = new Set(['duckdb']);

View File

@@ -25,6 +25,8 @@ describe('sqlDialect', () => {
expect(resolveSqlDialect('custom', 'dm8')).toBe('dameng');
expect(resolveSqlDialect('custom', 'mariadb')).toBe('mariadb');
expect(resolveSqlDialect('custom', 'open_gauss')).toBe('opengauss');
expect(resolveSqlDialect('Elasticsearch')).toBe('elasticsearch');
expect(resolveSqlDialect('custom', 'elastic')).toBe('elasticsearch');
expect(resolveSqlDialect('OceanBase', '', { oceanBaseProtocol: 'oracle' })).toBe('oracle');
expect(resolveSqlDialect('custom', 'oceanbase', { oceanBaseProtocol: 'oracle' })).toBe('oracle');
expect(isMysqlFamilyDialect('mariadb')).toBe(true);

View File

@@ -29,6 +29,7 @@ export type SqlDialect =
| 'tdengine'
| 'mongodb'
| 'redis'
| 'elasticsearch'
| 'unknown'
| string;
@@ -106,7 +107,10 @@ export const resolveSqlDialect = (
case 'tdengine':
case 'mongodb':
case 'redis':
case 'elasticsearch':
return source;
case 'elastic':
return 'elasticsearch';
default:
break;
}
@@ -130,6 +134,7 @@ export const resolveSqlDialect = (
if (source.includes('tdengine')) return 'tdengine';
if (source.includes('sqlserver') || source.includes('mssql')) return 'sqlserver';
if (source.includes('iris') || source.includes('intersystems')) return 'iris';
if (source.includes('elastic')) return 'elasticsearch';
return source;
};