mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-31 08:59:48 +08:00
🐛 fix(connection): 修复 IRIS 连接类型保存后回退为 MySQL
- 将 IRIS 纳入前端连接类型白名单与默认端口配置 - 补齐常见数据源类型别名归一化,避免未知别名回退为 MySQL - 增加 IRIS 连接保存、导入、自动 Limit 和表数据清空回归测试 - 补齐前后端 IRIS truncate 支持 Refs #476
This commit is contained in:
@@ -8,8 +8,10 @@ describe('tableDataDangerActions', () => {
|
||||
expect(supportsTableTruncateAction('oceanbase')).toBe(true);
|
||||
expect(supportsTableTruncateAction('postgres')).toBe(true);
|
||||
expect(supportsTableTruncateAction('opengauss')).toBe(true);
|
||||
expect(supportsTableTruncateAction('iris')).toBe(true);
|
||||
expect(supportsTableTruncateAction('custom', 'postgresql')).toBe(true);
|
||||
expect(supportsTableTruncateAction('custom', 'kingbase8')).toBe(true);
|
||||
expect(supportsTableTruncateAction('custom', 'intersystemsiris')).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects truncate for unsupported or document-style backends', () => {
|
||||
|
||||
@@ -41,6 +41,8 @@ const resolveCustomDriverDialect = (driver: string): string => {
|
||||
case 'iris':
|
||||
case 'intersystems':
|
||||
case 'intersystemsiris':
|
||||
case 'inter-systems':
|
||||
case 'inter-systems-iris':
|
||||
return 'iris';
|
||||
default:
|
||||
break;
|
||||
@@ -53,6 +55,7 @@ const resolveCustomDriverDialect = (driver: string): string => {
|
||||
if (normalized.includes('highgo')) return 'highgo';
|
||||
if (normalized.includes('vastbase')) return 'vastbase';
|
||||
if (normalized.includes('sqlite')) return 'sqlite';
|
||||
if (normalized.includes('iris') || normalized.includes('intersystems')) return 'iris';
|
||||
if (normalized.includes('sphinx')) return 'sphinx';
|
||||
if (normalized.includes('diros') || normalized.includes('doris')) return 'diros';
|
||||
if (normalized.includes('starrocks')) return 'starrocks';
|
||||
@@ -79,6 +82,7 @@ export const supportsTableTruncateAction = (type: string, driver?: string): bool
|
||||
case 'vastbase':
|
||||
case 'opengauss':
|
||||
case 'sqlserver':
|
||||
case 'iris':
|
||||
case 'oracle':
|
||||
case 'dameng':
|
||||
case 'clickhouse':
|
||||
|
||||
@@ -262,6 +262,62 @@ describe('store appearance persistence', () => {
|
||||
expect(config?.port).toBe(9030);
|
||||
});
|
||||
|
||||
it('keeps InterSystems IRIS saved connections as independent datasource type', async () => {
|
||||
const { useStore } = await importStore();
|
||||
|
||||
useStore.getState().replaceConnections([
|
||||
{
|
||||
id: 'iris-user',
|
||||
name: 'IRIS USER',
|
||||
config: {
|
||||
id: 'iris-user',
|
||||
type: 'iris',
|
||||
host: 'iris.local',
|
||||
port: 1972,
|
||||
user: '_SYSTEM',
|
||||
database: 'USER',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'iris-alias',
|
||||
name: 'IRIS Alias',
|
||||
config: {
|
||||
id: 'iris-alias',
|
||||
type: 'InterSystemsIRIS',
|
||||
host: 'iris-alias.local',
|
||||
port: 1972,
|
||||
user: '_SYSTEM',
|
||||
database: 'USER',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const connections = useStore.getState().connections;
|
||||
expect(connections[0]?.config.type).toBe('iris');
|
||||
expect(connections[0]?.config.port).toBe(1972);
|
||||
expect(connections[1]?.config.type).toBe('iris');
|
||||
});
|
||||
|
||||
it('normalizes saved connection type aliases without falling back to mysql', async () => {
|
||||
const { useStore } = await importStore();
|
||||
|
||||
useStore.getState().replaceConnections([
|
||||
{ id: 'pg', name: 'Postgres', config: { id: 'pg', type: 'PostgreSQL', host: 'pg.local', port: 5432, user: 'postgres' } },
|
||||
{ id: 'mssql', name: 'MSSQL', config: { id: 'mssql', type: 'mssql', host: 'sql.local', port: 1433, user: 'sa' } },
|
||||
{ id: 'kingbase', name: 'Kingbase', config: { id: 'kingbase', type: 'kingbase8', host: 'kingbase.local', port: 54321, user: 'system' } },
|
||||
{ id: 'dm', name: 'Dameng', config: { id: 'dm', type: 'dm8', host: 'dm.local', port: 5236, user: 'SYSDBA' } },
|
||||
{ id: 'sqlite', name: 'SQLite', config: { id: 'sqlite', type: 'sqlite3', host: 'D:/db/app.sqlite', port: 0, user: '' } },
|
||||
]);
|
||||
|
||||
expect(useStore.getState().connections.map((conn) => conn.config.type)).toEqual([
|
||||
'postgres',
|
||||
'sqlserver',
|
||||
'kingbase',
|
||||
'dameng',
|
||||
'sqlite',
|
||||
]);
|
||||
});
|
||||
|
||||
it('preserves SSL certificate paths for SSL-capable saved connections', async () => {
|
||||
const { useStore } = await importStore();
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ const SUPPORTED_CONNECTION_TYPES = new Set([
|
||||
"dameng",
|
||||
"kingbase",
|
||||
"sqlserver",
|
||||
"iris",
|
||||
"mongodb",
|
||||
"highgo",
|
||||
"vastbase",
|
||||
@@ -185,6 +186,8 @@ const getDefaultPortByType = (type: string): number => {
|
||||
return 54321;
|
||||
case "sqlserver":
|
||||
return 1433;
|
||||
case "iris":
|
||||
return 1972;
|
||||
case "mongodb":
|
||||
return 27017;
|
||||
case "highgo":
|
||||
@@ -311,6 +314,24 @@ const normalizeConnectionType = (value: unknown): string => {
|
||||
if (type === "doris") {
|
||||
return "diros";
|
||||
}
|
||||
if (type === "postgresql") {
|
||||
return "postgres";
|
||||
}
|
||||
if (type === "mssql" || type === "sql_server" || type === "sql-server") {
|
||||
return "sqlserver";
|
||||
}
|
||||
if (type === "kingbase8" || type === "kingbasees" || type === "kingbasev8") {
|
||||
return "kingbase";
|
||||
}
|
||||
if (type === "dm" || type === "dm8") {
|
||||
return "dameng";
|
||||
}
|
||||
if (type === "sqlite3") {
|
||||
return "sqlite";
|
||||
}
|
||||
if (type === "sphinxql") {
|
||||
return "sphinx";
|
||||
}
|
||||
if (
|
||||
type === "open_gauss" ||
|
||||
type === "open-gauss" ||
|
||||
@@ -318,6 +339,16 @@ const normalizeConnectionType = (value: unknown): string => {
|
||||
) {
|
||||
return "opengauss";
|
||||
}
|
||||
if (
|
||||
type === "inter-systems" ||
|
||||
type === "inter-systems-iris" ||
|
||||
type === "intersystems" ||
|
||||
type === "intersystems iris" ||
|
||||
type === "intersystemsiris" ||
|
||||
type.includes("iris")
|
||||
) {
|
||||
return "iris";
|
||||
}
|
||||
return SUPPORTED_CONNECTION_TYPES.has(type) ? type : DEFAULT_CONNECTION_TYPE;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ describe('applyQueryAutoLimit', () => {
|
||||
'highgo',
|
||||
'vastbase',
|
||||
'opengauss',
|
||||
'iris',
|
||||
'intersystemsiris',
|
||||
'sqlite',
|
||||
'sqlite3',
|
||||
'duckdb',
|
||||
|
||||
@@ -1424,7 +1424,7 @@ const (
|
||||
|
||||
func supportsTruncateTableForDBType(dbType string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(dbType)) {
|
||||
case "mysql", "mariadb", "oceanbase", "starrocks", "postgres", "kingbase", "highgo", "vastbase", "opengauss", "sqlserver", "oracle", "dameng", "clickhouse", "duckdb":
|
||||
case "mysql", "mariadb", "oceanbase", "starrocks", "postgres", "kingbase", "highgo", "vastbase", "opengauss", "sqlserver", "iris", "oracle", "dameng", "clickhouse", "duckdb":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -85,6 +85,19 @@ func TestBuildTableDataClearSQL_KingbaseClearNormalizesQuotedQualifiedTable(t *t
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTableDataClearSQL_IRISTruncateUsesNativeStatement(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sql, err := buildTableDataClearSQL(connection.ConnectionConfig{Type: "InterSystemsIRIS"}, "Sample.Person", tableDataClearModeTruncate)
|
||||
if err != nil {
|
||||
t.Fatalf("buildTableDataClearSQL() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if sql != `TRUNCATE TABLE "Sample"."Person"` {
|
||||
t.Fatalf("unexpected iris truncate sql: %s", sql)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTableDataClearSQL_TruncateRejectsUnsupportedDialect(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user