mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-28 09:21:38 +08:00
@@ -23,6 +23,8 @@ describe('connectionDriverType', () => {
|
||||
expect(normalizeDriverType('doris')).toBe('diros');
|
||||
expect(normalizeDriverType('open-gauss')).toBe('opengauss');
|
||||
expect(normalizeDriverType('gauss-db')).toBe('gaussdb');
|
||||
expect(normalizeDriverType('greatdb')).toBe('goldendb');
|
||||
expect(normalizeDriverType('gdb')).toBe('goldendb');
|
||||
expect(normalizeDriverType('InterSystemsIRIS')).toBe('iris');
|
||||
});
|
||||
|
||||
@@ -31,6 +33,7 @@ describe('connectionDriverType', () => {
|
||||
expect(resolveConnectionDriverType('custom', 'postgresql')).toBe('postgres');
|
||||
expect(resolveConnectionDriverType('custom', 'open_gauss')).toBe('opengauss');
|
||||
expect(resolveConnectionDriverType('custom', 'gauss_db')).toBe('gaussdb');
|
||||
expect(resolveConnectionDriverType('custom', 'goldendb')).toBe('goldendb');
|
||||
expect(resolveConnectionDriverType('custom', '')).toBe('');
|
||||
});
|
||||
|
||||
|
||||
@@ -30,6 +30,11 @@ export const normalizeDriverType = (value: string): string => {
|
||||
normalized === 'gauss_db' ||
|
||||
normalized === 'gauss-db'
|
||||
) return 'gaussdb';
|
||||
if (
|
||||
normalized === 'goldendb' ||
|
||||
normalized === 'greatdb' ||
|
||||
normalized === 'gdb'
|
||||
) return 'goldendb';
|
||||
if (
|
||||
normalized === 'intersystems' ||
|
||||
normalized === 'intersystemsiris' ||
|
||||
|
||||
@@ -67,6 +67,7 @@ describe('connectionModalPresentation', () => {
|
||||
it('assigns card-based configuration sections to every supported data source type', () => {
|
||||
const allTypes = [
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'doris',
|
||||
@@ -117,6 +118,15 @@ describe('connectionModalPresentation', () => {
|
||||
'credentials',
|
||||
'databaseScope',
|
||||
]);
|
||||
expect(resolveConnectionConfigLayout('goldendb').sections).toEqual([
|
||||
'identity',
|
||||
'uri',
|
||||
'target',
|
||||
'connectionMode',
|
||||
'replica',
|
||||
'credentials',
|
||||
'databaseScope',
|
||||
]);
|
||||
expect(resolveConnectionConfigLayout('mongodb').sections).toEqual([
|
||||
'identity',
|
||||
'uri',
|
||||
|
||||
@@ -58,6 +58,7 @@ type ConnectionConfigSectionCopy = {
|
||||
|
||||
const mysqlCompatibleTypes = new Set([
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'doris',
|
||||
|
||||
@@ -29,6 +29,7 @@ describe('connectionTypeCapabilities', () => {
|
||||
expect(supportsSSLForType('MongoDB')).toBe(true);
|
||||
expect(supportsSSLForType('elasticsearch')).toBe(true);
|
||||
expect(supportsSSLForType('gaussdb')).toBe(true);
|
||||
expect(supportsSSLForType('greatdb')).toBe(true);
|
||||
expect(supportsSSLForType('chroma')).toBe(true);
|
||||
expect(supportsSSLForType('qdrant')).toBe(true);
|
||||
expect(supportsSSLForType('kafka')).toBe(true);
|
||||
@@ -68,6 +69,7 @@ describe('connectionTypeCapabilities', () => {
|
||||
expect(isFileDatabaseType('duckdb')).toBe(true);
|
||||
expect(isFileDatabaseType('DuckDB')).toBe(false);
|
||||
expect(isMySQLCompatibleType('mysql')).toBe(true);
|
||||
expect(isMySQLCompatibleType('goldendb')).toBe(true);
|
||||
expect(isMySQLCompatibleType('oceanbase')).toBe(true);
|
||||
expect(isMySQLCompatibleType('diros')).toBe(true);
|
||||
expect(isMySQLCompatibleType('postgres')).toBe(false);
|
||||
@@ -75,6 +77,7 @@ describe('connectionTypeCapabilities', () => {
|
||||
|
||||
it('keeps advanced connection params enabled only for supported database types', () => {
|
||||
expect(supportsConnectionParamsForType('mysql')).toBe(true);
|
||||
expect(supportsConnectionParamsForType('gdb')).toBe(true);
|
||||
expect(supportsConnectionParamsForType('postgres')).toBe(true);
|
||||
expect(supportsConnectionParamsForType('gaussdb')).toBe(true);
|
||||
expect(supportsConnectionParamsForType('oracle')).toBe(true);
|
||||
|
||||
@@ -19,12 +19,23 @@ export const singleHostUriSchemesByType: Record<string, string[]> = {
|
||||
};
|
||||
|
||||
const normalizeConnectionType = (type: string) =>
|
||||
String(type || "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
{
|
||||
const normalized = String(type || "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
switch (normalized) {
|
||||
case "goldendb":
|
||||
case "greatdb":
|
||||
case "gdb":
|
||||
return "goldendb";
|
||||
default:
|
||||
return normalized;
|
||||
}
|
||||
};
|
||||
|
||||
const sslSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"goldendb",
|
||||
"mariadb",
|
||||
"oceanbase",
|
||||
"doris",
|
||||
@@ -55,6 +66,7 @@ export const supportsSSLForType = (type: string) =>
|
||||
|
||||
const sslCAPathSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"goldendb",
|
||||
"mariadb",
|
||||
"oceanbase",
|
||||
"diros",
|
||||
@@ -78,6 +90,7 @@ const sslCAPathSupportedTypes = new Set([
|
||||
|
||||
const sslClientCertificateSupportedTypes = new Set([
|
||||
"mysql",
|
||||
"goldendb",
|
||||
"mariadb",
|
||||
"oceanbase",
|
||||
"diros",
|
||||
@@ -116,13 +129,14 @@ export const isFileDatabaseType = (type: string) =>
|
||||
type === "sqlite" || type === "duckdb";
|
||||
|
||||
export const isMySQLCompatibleType = (type: string) =>
|
||||
type === "mysql" ||
|
||||
type === "mariadb" ||
|
||||
type === "oceanbase" ||
|
||||
type === "doris" ||
|
||||
type === "diros" ||
|
||||
type === "starrocks" ||
|
||||
type === "sphinx";
|
||||
normalizeConnectionType(type) === "mysql" ||
|
||||
normalizeConnectionType(type) === "goldendb" ||
|
||||
normalizeConnectionType(type) === "mariadb" ||
|
||||
normalizeConnectionType(type) === "oceanbase" ||
|
||||
normalizeConnectionType(type) === "doris" ||
|
||||
normalizeConnectionType(type) === "diros" ||
|
||||
normalizeConnectionType(type) === "starrocks" ||
|
||||
normalizeConnectionType(type) === "sphinx";
|
||||
|
||||
export const supportsConnectionParamsForType = (type: string) =>
|
||||
isMySQLCompatibleType(type) ||
|
||||
|
||||
@@ -23,6 +23,7 @@ describe('connectionTypeCatalog', () => {
|
||||
expect(keys).toContain('mysql');
|
||||
expect(keys).toContain('oceanbase');
|
||||
expect(keys).toContain('gaussdb');
|
||||
expect(keys).toContain('goldendb');
|
||||
expect(keys).toContain('mongodb');
|
||||
expect(keys).toContain('redis');
|
||||
expect(keys).toContain('elasticsearch');
|
||||
@@ -38,6 +39,7 @@ describe('connectionTypeCatalog', () => {
|
||||
it('returns the existing default port mapping for supported connection types', () => {
|
||||
expect(getConnectionTypeDefaultPort('mysql')).toBe(3306);
|
||||
expect(getConnectionTypeDefaultPort('oceanbase')).toBe(2881);
|
||||
expect(getConnectionTypeDefaultPort('goldendb')).toBe(1523);
|
||||
expect(getConnectionTypeDefaultPort('diros')).toBe(9030);
|
||||
expect(getConnectionTypeDefaultPort('postgres')).toBe(5432);
|
||||
expect(getConnectionTypeDefaultPort('gaussdb')).toBe(5432);
|
||||
@@ -63,6 +65,7 @@ describe('connectionTypeCatalog', () => {
|
||||
expect(getConnectionTypeHint('iotdb')).toContain('Timeseries');
|
||||
expect(getConnectionTypeHint('kafka')).toContain('Consumer Group');
|
||||
expect(getConnectionTypeHint('oceanbase')).toBe('MySQL / Oracle 租户');
|
||||
expect(getConnectionTypeHint('goldendb')).toBe('MySQL 兼容 / 分布式事务');
|
||||
expect(getConnectionTypeHint('duckdb')).toBe('本地文件连接');
|
||||
expect(getConnectionTypeHint('mysql')).toBe('标准连接配置');
|
||||
});
|
||||
|
||||
@@ -36,6 +36,7 @@ export const CONNECTION_TYPE_GROUPS: ConnectionTypeCatalogGroup[] = [
|
||||
{ key: 'vastbase', name: 'Vastbase (海量)' },
|
||||
{ key: 'opengauss', name: 'OpenGauss' },
|
||||
{ key: 'gaussdb', name: 'GaussDB' },
|
||||
{ key: 'goldendb', name: 'GoldenDB' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -83,6 +84,8 @@ export const getConnectionTypeDefaultPort = (type: string): number => {
|
||||
return 3306;
|
||||
case 'oceanbase':
|
||||
return 2881;
|
||||
case 'goldendb':
|
||||
return 1523;
|
||||
case 'doris':
|
||||
case 'diros':
|
||||
case 'starrocks':
|
||||
@@ -157,6 +160,8 @@ export const getConnectionTypeHint = (type: string): string => {
|
||||
return 'Broker / Topic / Consumer Group';
|
||||
case 'oceanbase':
|
||||
return 'MySQL / Oracle 租户';
|
||||
case 'goldendb':
|
||||
return 'MySQL 兼容 / 分布式事务';
|
||||
case 'sqlite':
|
||||
case 'duckdb':
|
||||
return '本地文件连接';
|
||||
|
||||
@@ -30,6 +30,24 @@ describe('dataSourceCapabilities', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('treats GoldenDB as an editable MySQL-family datasource with database-level DDL actions', () => {
|
||||
expect(getDataSourceCapabilities({ type: 'goldendb' })).toMatchObject({
|
||||
type: 'goldendb',
|
||||
supportsQueryEditor: true,
|
||||
supportsSqlQueryExport: true,
|
||||
supportsCopyInsert: true,
|
||||
supportsCreateDatabase: true,
|
||||
supportsRenameDatabase: false,
|
||||
supportsDropDatabase: true,
|
||||
forceReadOnlyQueryResult: false,
|
||||
});
|
||||
expect(getDataSourceCapabilities({ type: 'custom', driver: 'greatdb' })).toMatchObject({
|
||||
type: 'goldendb',
|
||||
supportsQueryEditor: true,
|
||||
supportsCopyInsert: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps StarRocks as an independent SQL datasource capability', () => {
|
||||
expect(getDataSourceCapabilities({ type: 'starrocks' })).toMatchObject({
|
||||
type: 'starrocks',
|
||||
|
||||
@@ -20,6 +20,10 @@ const normalizeDataSourceToken = (raw: string): string => {
|
||||
case 'gauss_db':
|
||||
case 'gauss-db':
|
||||
return 'gaussdb';
|
||||
case 'goldendb':
|
||||
case 'greatdb':
|
||||
case 'gdb':
|
||||
return 'goldendb';
|
||||
case 'dm':
|
||||
return 'dameng';
|
||||
case 'elastic':
|
||||
@@ -66,6 +70,7 @@ export const resolveDataSourceType = (config: ConnectionLike): string => {
|
||||
|
||||
const SQL_QUERY_EXPORT_TYPES = new Set([
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'diros',
|
||||
@@ -89,6 +94,7 @@ const SQL_QUERY_EXPORT_TYPES = new Set([
|
||||
|
||||
const COPY_INSERT_TYPES = new Set([
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'diros',
|
||||
@@ -132,6 +138,7 @@ export type DataSourceCapabilities = {
|
||||
|
||||
const CREATE_DATABASE_TYPES = new Set([
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'diros',
|
||||
@@ -159,6 +166,7 @@ const RENAME_DATABASE_TYPES = new Set([
|
||||
|
||||
const DROP_DATABASE_TYPES = new Set([
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'diros',
|
||||
|
||||
@@ -18,6 +18,7 @@ const resolveDdlFormatterLanguage = (dbType: string): SqlLanguage => {
|
||||
case 'mariadb':
|
||||
return 'mariadb';
|
||||
case 'mysql':
|
||||
case 'goldendb':
|
||||
case 'sphinx':
|
||||
return 'mysql';
|
||||
case 'sqlserver':
|
||||
|
||||
@@ -5,6 +5,7 @@ import { applyQueryAutoLimit } from './queryAutoLimit';
|
||||
describe('applyQueryAutoLimit', () => {
|
||||
const limitDialects = [
|
||||
'mysql',
|
||||
'goldendb',
|
||||
'mariadb',
|
||||
'oceanbase',
|
||||
'diros',
|
||||
|
||||
@@ -25,6 +25,7 @@ describe('sidebarMetadata', () => {
|
||||
});
|
||||
|
||||
it('uses MySQL metadata queries for custom MySQL-compatible domestic drivers', () => {
|
||||
expect(resolveSidebarMetadataDialect('goldendb')).toBe('mysql');
|
||||
expect(resolveSidebarMetadataDialect('custom', 'gdb')).toBe('mysql');
|
||||
expect(resolveSidebarMetadataDialect('custom', 'goldendb')).toBe('mysql');
|
||||
expect(resolveSidebarMetadataDialect('custom', 'greatdb')).toBe('mysql');
|
||||
|
||||
@@ -64,6 +64,11 @@ describe('quoteQualifiedIdent', () => {
|
||||
.toBe('"logs.app-1"');
|
||||
});
|
||||
|
||||
it('quotes GoldenDB identifiers with MySQL-style backticks', () => {
|
||||
expect(quoteQualifiedIdent('goldendb', 'ledger.entries'))
|
||||
.toBe('`ledger`.`entries`');
|
||||
});
|
||||
|
||||
it('does not split dots inside quoted DuckDB identifiers', () => {
|
||||
expect(quoteQualifiedIdent('duckdb', '"daily.events"."2026.06"'))
|
||||
.toBe('"daily.events"."2026.06"');
|
||||
|
||||
@@ -29,7 +29,7 @@ export const quoteIdentPart = (dbType: string, ident: string) => {
|
||||
if (!raw) return raw;
|
||||
const dbTypeLower = (dbType || '').toLowerCase();
|
||||
|
||||
if (dbTypeLower === 'mysql' || dbTypeLower === 'mariadb' || dbTypeLower === 'oceanbase' || dbTypeLower === 'diros' || dbTypeLower === 'starrocks' || dbTypeLower === 'sphinx' || dbTypeLower === 'tdengine' || dbTypeLower === 'iotdb' || dbTypeLower === 'clickhouse') {
|
||||
if (dbTypeLower === 'mysql' || dbTypeLower === 'goldendb' || dbTypeLower === 'mariadb' || dbTypeLower === 'oceanbase' || dbTypeLower === 'diros' || dbTypeLower === 'starrocks' || dbTypeLower === 'sphinx' || dbTypeLower === 'tdengine' || dbTypeLower === 'iotdb' || dbTypeLower === 'clickhouse') {
|
||||
return `\`${raw.replace(/`/g, '``')}\``;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ export const buildOrderBySQL = (
|
||||
// 部分数据源在无显式排序需求时强制 ORDER BY(即使按主键)会显著放大大表预览成本:
|
||||
// MySQL/MariaDB 可能触发 filesort 和 sort memory 错误,DuckDB 大文件可能被排序拖到连接超时。
|
||||
// 因此仅在用户主动点击排序时下发 ORDER BY,默认分页查询不加兜底排序。
|
||||
if (dbTypeLower === 'mysql' || dbTypeLower === 'mariadb' || dbTypeLower === 'oceanbase' || dbTypeLower === 'diros' || dbTypeLower === 'starrocks' || dbTypeLower === 'duckdb') {
|
||||
if (dbTypeLower === 'mysql' || dbTypeLower === 'goldendb' || dbTypeLower === 'mariadb' || dbTypeLower === 'oceanbase' || dbTypeLower === 'diros' || dbTypeLower === 'starrocks' || dbTypeLower === 'duckdb') {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user