feat(iris): 新增 InterSystems IRIS 数据源支持

- 后端新增 IRIS 连接、查询、DDL、索引元数据和 DataGrid 编辑能力
- 接入 optional driver-agent、构建标签、revision 生成和变更检测流程
- 前端新增 IRIS 连接入口、方言映射、能力配置和图标展示
- 修复 IRIS 主键识别、事务开启错误处理和驱动连接关闭问题
- 补充后端、前端和构建脚本相关回归测试
Refs #408
This commit is contained in:
Syngnat
2026-05-17 10:32:08 +08:00
parent 0cde96844d
commit 992d2dee45
57 changed files with 4391 additions and 16 deletions

View File

@@ -84,6 +84,7 @@ describe('connectionModalPresentation', () => {
'highgo',
'vastbase',
'opengauss',
'iris',
'mongodb',
'redis',
'tdengine',
@@ -139,6 +140,13 @@ describe('connectionModalPresentation', () => {
'customDriver',
'customDsn',
]);
expect(resolveConnectionConfigLayout('iris').sections).toEqual([
'identity',
'uri',
'target',
'credentials',
'databaseScope',
]);
});
it('uses localized labels for layout kinds shown in the modal', () => {

View File

@@ -40,6 +40,20 @@ describe('dataSourceCapabilities', () => {
});
});
it('keeps InterSystems IRIS as an editable SQL datasource capability', () => {
expect(getDataSourceCapabilities({ type: 'iris' })).toMatchObject({
type: 'iris',
supportsQueryEditor: true,
supportsSqlQueryExport: true,
supportsCopyInsert: true,
forceReadOnlyQueryResult: false,
});
expect(getDataSourceCapabilities({ type: 'custom', driver: 'intersystemsiris' })).toMatchObject({
type: 'iris',
supportsQueryEditor: true,
});
});
it('treats OceanBase Oracle protocol as Oracle capabilities', () => {
expect(getDataSourceCapabilities({
type: 'oceanbase',

View File

@@ -18,6 +18,11 @@ const normalizeDataSourceToken = (raw: string): string => {
return 'opengauss';
case 'dm':
return 'dameng';
case 'intersystems':
case 'intersystemsiris':
case 'inter-systems':
case 'inter-systems-iris':
return 'iris';
default:
return normalized;
}
@@ -52,6 +57,7 @@ const SQL_QUERY_EXPORT_TYPES = new Set([
'vastbase',
'opengauss',
'sqlserver',
'iris',
'sqlite',
'duckdb',
'oracle',
@@ -73,6 +79,7 @@ const COPY_INSERT_TYPES = new Set([
'vastbase',
'opengauss',
'sqlserver',
'iris',
'sqlite',
'duckdb',
'oracle',

View File

@@ -19,6 +19,8 @@ describe('driver import guidance', () => {
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('pgx');
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('open_gauss');
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('oceanbase');
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('Go database/sql');
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('ODBC/JDBC');
expect(CUSTOM_CONNECTION_DRIVER_HELP).toContain('JDBC Jar');
});
});

View File

@@ -7,4 +7,4 @@ export const DRIVER_LOCAL_IMPORT_SINGLE_FILE_HELP =
'行内“导入驱动包”仅用于单个驱动文件/总包(如 `mariadb-driver-agent`、`mariadb-driver-agent.exe`、`GoNavi-DriverAgents.zip`),不支持直接导入 JDBC Jar批量导入请使用上方“导入驱动目录”。';
export const CUSTOM_CONNECTION_DRIVER_HELP =
'已支持: mysql, starrocks, oceanbase, postgres, opengauss, sqlite, oracle, dm, kingbase别名支持 postgresql/pgx、open_gauss/open-gauss、dm8、kingbase8/kingbasees/kingbasev8。当前不支持通过 JDBC Jar 扩展驱动。';
'已支持: mysql, starrocks, oceanbase, postgres, opengauss, sqlite, oracle, dm, kingbase别名支持 postgresql/pgx、open_gauss/open-gauss、dm8、kingbase8/kingbasees/kingbasev8。请填写 GoNavi 已注册的 Go database/sql 驱动名,不能直接填写系统 ODBC/JDBC 驱动名或导入 JDBC Jar。';

View File

@@ -19,6 +19,8 @@ describe('sqlDialect', () => {
expect(resolveSqlDialect('doris')).toBe('diros');
expect(resolveSqlDialect('StarRocks')).toBe('starrocks');
expect(resolveSqlDialect('dameng')).toBe('dameng');
expect(resolveSqlDialect('InterSystems IRIS')).toBe('iris');
expect(resolveSqlDialect('custom', 'intersystemsiris')).toBe('iris');
expect(resolveSqlDialect('custom', 'kingbase8')).toBe('kingbase');
expect(resolveSqlDialect('custom', 'dm8')).toBe('dameng');
expect(resolveSqlDialect('custom', 'mariadb')).toBe('mariadb');
@@ -43,6 +45,7 @@ describe('sqlDialect', () => {
expect(values(resolveColumnTypeOptions('starrocks'))).toContain('PERCENTILE');
expect(values(resolveColumnTypeOptions('sphinx'))).toContain('text');
expect(values(resolveColumnTypeOptions('clickhouse'))).toContain('DateTime64(3)');
expect(values(resolveColumnTypeOptions('iris'))).toContain('varchar(255)');
expect(values(resolveColumnTypeOptions('tdengine'))).toContain('TIMESTAMP');
expect(values(resolveColumnTypeOptions('duckdb'))).toContain('STRUCT');
});

View File

@@ -22,6 +22,7 @@ export type SqlDialect =
| 'oracle'
| 'dameng'
| 'sqlserver'
| 'iris'
| 'sqlite'
| 'duckdb'
| 'clickhouse'
@@ -68,6 +69,12 @@ export const resolveSqlDialect = (
case 'sql_server':
case 'sql-server':
return 'sqlserver';
case 'intersystems':
case 'intersystemsiris':
case 'inter-systems':
case 'inter-systems-iris':
case 'iris':
return 'iris';
case 'doris':
case 'diros':
return 'diros';
@@ -122,6 +129,7 @@ export const resolveSqlDialect = (
if (source.includes('clickhouse')) return 'clickhouse';
if (source.includes('tdengine')) return 'tdengine';
if (source.includes('sqlserver') || source.includes('mssql')) return 'sqlserver';
if (source.includes('iris') || source.includes('intersystems')) return 'iris';
return source;
};
@@ -479,6 +487,7 @@ export const resolveColumnTypeOptions = (dbType: string): ColumnTypeOption[] =>
if (dialect === 'oracle') return ORACLE_TYPES;
if (dialect === 'dameng') return DAMENG_TYPES;
if (dialect === 'sqlserver') return SQLSERVER_TYPES;
if (dialect === 'iris') return COMMON_TYPES;
if (dialect === 'sqlite') return SQLITE_TYPES;
if (dialect === 'duckdb') return DUCKDB_TYPES;
if (dialect === 'clickhouse') return CLICKHOUSE_TYPES;