mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-12 17:39:42 +08:00
✨ feat(elasticsearch): 补齐新建连接入口
- 前端连接弹窗新增 Elasticsearch 入口、默认端口、URI 示例和默认索引配置 - 补齐 Elasticsearch 图标、数据源能力、SQL dialect 和只读查询策略 - 后端驱动管理注册 Elasticsearch 版本、模块路径、构建标签和默认安装入口 - 增加连接展示、能力识别和驱动定义测试覆盖
This commit is contained in:
@@ -16,3 +16,17 @@ describe('ConnectionModal edit password behavior', () => {
|
||||
expect(source).toContain('String(config.password || "") === ""');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ConnectionModal data source registry', () => {
|
||||
it('exposes Elasticsearch in the create-connection picker with HTTP defaults', () => {
|
||||
expect(source).toContain('case "elasticsearch":\n return 9200;');
|
||||
expect(source).toContain('elasticsearch: ["http", "https"]');
|
||||
expect(source).toContain('key: "elasticsearch"');
|
||||
expect(source).toContain('name: "Elasticsearch"');
|
||||
expect(source).toContain('getDbIcon("elasticsearch", undefined, 36)');
|
||||
expect(source).toContain('type === "elasticsearch"');
|
||||
expect(source).toContain('"http://elastic:pass@127.0.0.1:9200/logs-*"');
|
||||
expect(source).toContain('label="默认索引(可选)"');
|
||||
expect(source).toContain('"显示索引 (留空显示全部)"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -259,6 +259,8 @@ const getDefaultPortByType = (type: string) => {
|
||||
return 1972;
|
||||
case "mongodb":
|
||||
return 27017;
|
||||
case "elasticsearch":
|
||||
return 9200;
|
||||
case "highgo":
|
||||
return 5866;
|
||||
case "mariadb":
|
||||
@@ -282,6 +284,7 @@ const singleHostUriSchemesByType: Record<string, string[]> = {
|
||||
sqlserver: ["sqlserver"],
|
||||
iris: ["iris", "intersystems"],
|
||||
redis: ["redis"],
|
||||
elasticsearch: ["http", "https"],
|
||||
tdengine: ["tdengine"],
|
||||
dameng: ["dameng", "dm"],
|
||||
kingbase: ["kingbase"],
|
||||
@@ -308,6 +311,7 @@ const sslSupportedTypes = new Set([
|
||||
"opengauss",
|
||||
"mongodb",
|
||||
"redis",
|
||||
"elasticsearch",
|
||||
"tdengine",
|
||||
]);
|
||||
|
||||
@@ -334,6 +338,7 @@ const sslCAPathSupportedTypes = new Set([
|
||||
"opengauss",
|
||||
"mongodb",
|
||||
"redis",
|
||||
"elasticsearch",
|
||||
]);
|
||||
|
||||
const sslClientCertificateSupportedTypes = new Set([
|
||||
@@ -352,6 +357,7 @@ const sslClientCertificateSupportedTypes = new Set([
|
||||
"opengauss",
|
||||
"mongodb",
|
||||
"redis",
|
||||
"elasticsearch",
|
||||
]);
|
||||
|
||||
const supportsSSLCAPathForType = (type: string) =>
|
||||
@@ -405,6 +411,7 @@ const supportsConnectionParamsForType = (type: string) =>
|
||||
type === "iris" ||
|
||||
type === "clickhouse" ||
|
||||
type === "mongodb" ||
|
||||
type === "elasticsearch" ||
|
||||
type === "dameng" ||
|
||||
type === "tdengine";
|
||||
|
||||
@@ -1967,6 +1974,15 @@ const ConnectionModal: React.FC<{
|
||||
parsedValues.useSSL = false;
|
||||
parsedValues.sslMode = "disable";
|
||||
}
|
||||
} else if (type === "elasticsearch") {
|
||||
const isHTTPS = trimmedUri.toLowerCase().startsWith("https://");
|
||||
const skipVerify = normalizeBool(parsed.params.get("skip_verify"));
|
||||
parsedValues.useSSL = isHTTPS;
|
||||
parsedValues.sslMode = isHTTPS
|
||||
? skipVerify
|
||||
? "skip-verify"
|
||||
: "required"
|
||||
: "disable";
|
||||
}
|
||||
}
|
||||
return parsedValues;
|
||||
@@ -2032,6 +2048,9 @@ const ConnectionModal: React.FC<{
|
||||
if (dbType === "redis") {
|
||||
return "redis://:pass@127.0.0.1:6379,127.0.0.2:6379/0?topology=cluster";
|
||||
}
|
||||
if (dbType === "elasticsearch") {
|
||||
return "http://elastic:pass@127.0.0.1:9200/logs-*";
|
||||
}
|
||||
if (dbType === "oracle") {
|
||||
return "oracle://user:pass@127.0.0.1:1521/ORCLPDB1";
|
||||
}
|
||||
@@ -2251,6 +2270,10 @@ const ConnectionModal: React.FC<{
|
||||
? values.useSSL
|
||||
? "https"
|
||||
: "http"
|
||||
: type === "elasticsearch"
|
||||
? values.useSSL
|
||||
? "https"
|
||||
: "http"
|
||||
: type;
|
||||
const dbPath = database ? `/${encodeURIComponent(database)}` : "";
|
||||
const params = new URLSearchParams();
|
||||
@@ -2297,6 +2320,11 @@ const ConnectionModal: React.FC<{
|
||||
if (mode === "skip-verify" || mode === "preferred") {
|
||||
params.set("skip_verify", "true");
|
||||
}
|
||||
} else if (type === "elasticsearch") {
|
||||
if (mode === "skip-verify" || mode === "preferred") {
|
||||
params.set("skip_verify", "true");
|
||||
}
|
||||
appendSSLPathParamsForUri(params, type, values);
|
||||
}
|
||||
} else if (supportsSSLForType(type)) {
|
||||
if (isPostgresCompatibleSSLType(type)) {
|
||||
@@ -3813,7 +3841,13 @@ const ConnectionModal: React.FC<{
|
||||
});
|
||||
} else if (type !== "custom") {
|
||||
const defaultUser =
|
||||
type === "clickhouse" ? "default" : type === "redis" ? "" : "root";
|
||||
type === "clickhouse"
|
||||
? "default"
|
||||
: type === "redis"
|
||||
? ""
|
||||
: type === "elasticsearch"
|
||||
? "elastic"
|
||||
: "root";
|
||||
const sslCapableType = supportsSSLForType(type);
|
||||
setUseSSL(false);
|
||||
setUseHttpTunnel(false);
|
||||
@@ -4005,6 +4039,11 @@ const ConnectionModal: React.FC<{
|
||||
name: "Redis",
|
||||
icon: getDbIcon("redis", undefined, 36),
|
||||
},
|
||||
{
|
||||
key: "elasticsearch",
|
||||
name: "Elasticsearch",
|
||||
icon: getDbIcon("elasticsearch", undefined, 36),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -4045,6 +4084,8 @@ const ConnectionModal: React.FC<{
|
||||
return "单机 / 集群";
|
||||
case "mongodb":
|
||||
return "单机 / 副本集";
|
||||
case "elasticsearch":
|
||||
return "索引 / JSON DSL";
|
||||
case "oceanbase":
|
||||
return "MySQL / Oracle 租户";
|
||||
case "sqlite":
|
||||
@@ -5087,6 +5128,25 @@ const ConnectionModal: React.FC<{
|
||||
),
|
||||
})}
|
||||
|
||||
{dbType === "elasticsearch" &&
|
||||
renderConfigSectionCard({
|
||||
sectionKey: "service",
|
||||
icon: <DatabaseOutlined />,
|
||||
children: (
|
||||
<Form.Item
|
||||
name="database"
|
||||
label="默认索引(可选)"
|
||||
help="留空时 JSON DSL 和 query_string 会默认查询所有可见索引;也可以填写 logs-* 这类索引通配符。"
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Input
|
||||
{...noAutoCapInputProps}
|
||||
placeholder="例如:logs-*"
|
||||
/>
|
||||
</Form.Item>
|
||||
),
|
||||
})}
|
||||
|
||||
{(dbType === "oracle" || isOceanBaseOracle) &&
|
||||
renderConfigSectionCard({
|
||||
sectionKey: "service",
|
||||
@@ -5703,13 +5763,25 @@ const ConnectionModal: React.FC<{
|
||||
children: (
|
||||
<Form.Item
|
||||
name="includeDatabases"
|
||||
label="显示数据库 (留空显示全部)"
|
||||
help="连接测试成功后可选择"
|
||||
label={
|
||||
dbType === "elasticsearch"
|
||||
? "显示索引 (留空显示全部)"
|
||||
: "显示数据库 (留空显示全部)"
|
||||
}
|
||||
help={
|
||||
dbType === "elasticsearch"
|
||||
? "连接测试成功后可选择需要展示的索引"
|
||||
: "连接测试成功后可选择"
|
||||
}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="选择显示的数据库"
|
||||
placeholder={
|
||||
dbType === "elasticsearch"
|
||||
? "选择显示的索引"
|
||||
: "选择显示的数据库"
|
||||
}
|
||||
allowClear
|
||||
>
|
||||
{dbList.map((db) => (
|
||||
|
||||
@@ -10,6 +10,12 @@ describe('DatabaseIcons', () => {
|
||||
expect(getDbIconLabel('iris')).toBe('InterSystems IRIS');
|
||||
});
|
||||
|
||||
it('includes Elasticsearch in the selectable database icons', () => {
|
||||
expect(DB_ICON_TYPES).toContain('elasticsearch');
|
||||
expect(getDbIconLabel('elasticsearch')).toBe('Elasticsearch');
|
||||
expect(renderToStaticMarkup(<>{getDbIcon('elasticsearch', undefined, 22)}</>)).toContain('ES');
|
||||
});
|
||||
|
||||
it('wraps database icons in a consistent frame for sidebar sizing', () => {
|
||||
const mysqlMarkup = renderToStaticMarkup(<>{getDbIcon('mysql', undefined, 22)}</>);
|
||||
const jvmMarkup = renderToStaticMarkup(<>{getDbIcon('jvm', undefined, 22)}</>);
|
||||
|
||||
@@ -35,6 +35,7 @@ const DB_DEFAULT_COLORS: Record<string, string> = {
|
||||
postgres: '#336791',
|
||||
redis: '#DC382D',
|
||||
mongodb: '#47A248',
|
||||
elasticsearch: '#005571',
|
||||
jvm: '#1677FF',
|
||||
kingbase: '#1890FF',
|
||||
dameng: '#E6002D',
|
||||
@@ -130,6 +131,9 @@ const RedisIcon: React.FC<DbIconProps> = ({ size = 16, color }) => (
|
||||
const MongoDBIcon: React.FC<DbIconProps> = ({ size = 16, color }) => (
|
||||
<BrandSvgIcon type="mongodb" size={size} color={color} />
|
||||
);
|
||||
const ElasticsearchIcon: React.FC<DbIconProps> = ({ size = 16, color }) => (
|
||||
<ColorBadge size={size} color={color || DB_DEFAULT_COLORS.elasticsearch} label="ES" />
|
||||
);
|
||||
const ClickHouseIcon: React.FC<DbIconProps> = ({ size = 16, color }) => (
|
||||
<BrandSvgIcon type="clickhouse" size={size} color={color} />
|
||||
);
|
||||
@@ -214,6 +218,7 @@ const DB_ICON_MAP: Record<string, React.FC<DbIconProps>> = {
|
||||
postgres: PostgresIcon,
|
||||
redis: RedisIcon,
|
||||
mongodb: MongoDBIcon,
|
||||
elasticsearch: ElasticsearchIcon,
|
||||
jvm: JVMIcon,
|
||||
kingbase: KingBaseIcon,
|
||||
dameng: DamengIcon,
|
||||
@@ -232,7 +237,7 @@ const DB_ICON_MAP: Record<string, React.FC<DbIconProps>> = {
|
||||
|
||||
/** 可选图标类型列表(用于图标选择器 UI) */
|
||||
export const DB_ICON_TYPES: string[] = [
|
||||
'mysql', 'mariadb', 'oceanbase', 'postgres', 'redis', 'mongodb', 'jvm',
|
||||
'mysql', 'mariadb', 'oceanbase', 'postgres', 'redis', 'mongodb', 'elasticsearch', 'jvm',
|
||||
'oracle', 'sqlserver', 'sqlite', 'duckdb', 'clickhouse', 'starrocks',
|
||||
'kingbase', 'dameng', 'vastbase', 'opengauss', 'highgo', 'iris', 'tdengine', 'custom',
|
||||
];
|
||||
@@ -251,7 +256,7 @@ export const getDbIcon = (type: string, color?: string, size?: number): React.Re
|
||||
export const getDbIconLabel = (type: string): string => {
|
||||
const labels: Record<string, string> = {
|
||||
mysql: 'MySQL', mariadb: 'MariaDB', oceanbase: 'OceanBase', postgres: 'PostgreSQL',
|
||||
redis: 'Redis', mongodb: 'MongoDB', jvm: 'JVM',
|
||||
redis: 'Redis', mongodb: 'MongoDB', elasticsearch: 'Elasticsearch', jvm: 'JVM',
|
||||
oracle: 'Oracle',
|
||||
sqlserver: 'SQL Server', clickhouse: 'ClickHouse', sqlite: 'SQLite',
|
||||
starrocks: 'StarRocks',
|
||||
|
||||
@@ -264,6 +264,7 @@ const SUPPORTED_CONNECTION_TYPES = new Set([
|
||||
"sqlserver",
|
||||
"iris",
|
||||
"mongodb",
|
||||
"elasticsearch",
|
||||
"highgo",
|
||||
"vastbase",
|
||||
"opengauss",
|
||||
@@ -290,6 +291,7 @@ const SSL_SUPPORTED_CONNECTION_TYPES = new Set([
|
||||
"opengauss",
|
||||
"mongodb",
|
||||
"redis",
|
||||
"elasticsearch",
|
||||
"tdengine",
|
||||
]);
|
||||
|
||||
@@ -332,6 +334,8 @@ const getDefaultPortByType = (type: string): number => {
|
||||
return 1972;
|
||||
case "mongodb":
|
||||
return 27017;
|
||||
case "elasticsearch":
|
||||
return 9200;
|
||||
case "highgo":
|
||||
return 5866;
|
||||
default:
|
||||
|
||||
@@ -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('搜索引擎');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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']);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -349,7 +349,8 @@ const builtinDriverManifestJSON = `{
|
||||
"iris": { "engine": "go", "version": "0.2.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/iris" },
|
||||
"mongodb": { "engine": "go", "version": "2.5.0", "checksumPolicy": "off", "downloadUrl": "builtin://activate/mongodb" },
|
||||
"tdengine": { "engine": "go", "version": "3.7.8", "checksumPolicy": "off", "downloadUrl": "builtin://activate/tdengine" },
|
||||
"clickhouse": { "engine": "go", "version": "2.43.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/clickhouse" }
|
||||
"clickhouse": { "engine": "go", "version": "2.43.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/clickhouse" },
|
||||
"elasticsearch": { "engine": "go", "version": "8.19.6", "checksumPolicy": "off", "downloadUrl": "builtin://activate/elasticsearch" }
|
||||
}
|
||||
}`
|
||||
|
||||
@@ -389,47 +390,49 @@ var pinnedDriverPackageMap = map[string]pinnedDriverPackage{
|
||||
}
|
||||
|
||||
var latestDriverVersionMap = map[string]string{
|
||||
"mysql": "1.9.3",
|
||||
"mariadb": "1.9.3",
|
||||
"oceanbase": "1.9.3",
|
||||
"diros": "1.9.3",
|
||||
"starrocks": "1.9.3",
|
||||
"sphinx": "1.9.3",
|
||||
"sqlserver": "1.9.6",
|
||||
"sqlite": "1.46.1",
|
||||
"duckdb": "2.5.6",
|
||||
"dameng": "1.8.22",
|
||||
"kingbase": "0.0.0-20201021123113-29bd62a876c3",
|
||||
"highgo": "0.0.0-local",
|
||||
"vastbase": "1.11.2",
|
||||
"opengauss": "1.11.1",
|
||||
"iris": "0.2.1",
|
||||
"mongodb": "2.5.0",
|
||||
"tdengine": "3.7.8",
|
||||
"clickhouse": "2.43.1",
|
||||
"oracle": "2.9.0",
|
||||
"postgres": "1.11.2",
|
||||
"redis": "9.17.3",
|
||||
"mysql": "1.9.3",
|
||||
"mariadb": "1.9.3",
|
||||
"oceanbase": "1.9.3",
|
||||
"diros": "1.9.3",
|
||||
"starrocks": "1.9.3",
|
||||
"sphinx": "1.9.3",
|
||||
"sqlserver": "1.9.6",
|
||||
"sqlite": "1.46.1",
|
||||
"duckdb": "2.5.6",
|
||||
"dameng": "1.8.22",
|
||||
"kingbase": "0.0.0-20201021123113-29bd62a876c3",
|
||||
"highgo": "0.0.0-local",
|
||||
"vastbase": "1.11.2",
|
||||
"opengauss": "1.11.1",
|
||||
"iris": "0.2.1",
|
||||
"mongodb": "2.5.0",
|
||||
"tdengine": "3.7.8",
|
||||
"clickhouse": "2.43.1",
|
||||
"elasticsearch": "8.19.6",
|
||||
"oracle": "2.9.0",
|
||||
"postgres": "1.11.2",
|
||||
"redis": "9.17.3",
|
||||
}
|
||||
|
||||
var driverGoModulePathMap = map[string]string{
|
||||
"mariadb": "github.com/go-sql-driver/mysql",
|
||||
"oceanbase": "github.com/go-sql-driver/mysql",
|
||||
"diros": "github.com/go-sql-driver/mysql",
|
||||
"starrocks": "github.com/go-sql-driver/mysql",
|
||||
"sphinx": "github.com/go-sql-driver/mysql",
|
||||
"sqlserver": "github.com/microsoft/go-mssqldb",
|
||||
"sqlite": "modernc.org/sqlite",
|
||||
"duckdb": "github.com/duckdb/duckdb-go/v2",
|
||||
"dameng": "gitee.com/chunanyong/dm",
|
||||
"kingbase": "gitea.com/kingbase/gokb",
|
||||
"highgo": "github.com/highgo/pq-sm3",
|
||||
"vastbase": "github.com/lib/pq",
|
||||
"opengauss": "github.com/lib/pq",
|
||||
"iris": "github.com/caretdev/go-irisnative",
|
||||
"mongodb": "go.mongodb.org/mongo-driver/v2",
|
||||
"tdengine": "github.com/taosdata/driver-go/v3",
|
||||
"clickhouse": "github.com/ClickHouse/clickhouse-go/v2",
|
||||
"mariadb": "github.com/go-sql-driver/mysql",
|
||||
"oceanbase": "github.com/go-sql-driver/mysql",
|
||||
"diros": "github.com/go-sql-driver/mysql",
|
||||
"starrocks": "github.com/go-sql-driver/mysql",
|
||||
"sphinx": "github.com/go-sql-driver/mysql",
|
||||
"sqlserver": "github.com/microsoft/go-mssqldb",
|
||||
"sqlite": "modernc.org/sqlite",
|
||||
"duckdb": "github.com/duckdb/duckdb-go/v2",
|
||||
"dameng": "gitee.com/chunanyong/dm",
|
||||
"kingbase": "gitea.com/kingbase/gokb",
|
||||
"highgo": "github.com/highgo/pq-sm3",
|
||||
"vastbase": "github.com/lib/pq",
|
||||
"opengauss": "github.com/lib/pq",
|
||||
"iris": "github.com/caretdev/go-irisnative",
|
||||
"mongodb": "go.mongodb.org/mongo-driver/v2",
|
||||
"tdengine": "github.com/taosdata/driver-go/v3",
|
||||
"clickhouse": "github.com/ClickHouse/clickhouse-go/v2",
|
||||
"elasticsearch": "github.com/elastic/go-elasticsearch/v8",
|
||||
}
|
||||
|
||||
var driverGoModuleAliasPathMap = map[string][]string{
|
||||
@@ -1494,6 +1497,7 @@ func allDriverDefinitionsWithPackages(packages map[string]pinnedDriverPackage) [
|
||||
buildOptionalGoDriverDefinition("mongodb", "MongoDB", packages),
|
||||
buildOptionalGoDriverDefinition("tdengine", "TDengine", packages),
|
||||
buildOptionalGoDriverDefinition("clickhouse", "ClickHouse", packages),
|
||||
buildOptionalGoDriverDefinition("elasticsearch", "Elasticsearch", packages),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3821,6 +3825,8 @@ func optionalDriverBuildTag(driverType string, selectedVersion string) (string,
|
||||
return "gonavi_tdengine_driver", nil
|
||||
case "clickhouse":
|
||||
return "gonavi_clickhouse_driver", nil
|
||||
case "elasticsearch":
|
||||
return "gonavi_elasticsearch_driver", nil
|
||||
default:
|
||||
return "", fmt.Errorf("未配置驱动构建标签:%s", driverType)
|
||||
}
|
||||
|
||||
@@ -268,6 +268,39 @@ func TestIRISDriverDefinitionUsesOptionalAgent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestElasticsearchDriverDefinitionUsesOptionalAgent(t *testing.T) {
|
||||
definition, ok := resolveDriverDefinition("elasticsearch")
|
||||
if !ok {
|
||||
t.Fatal("expected elasticsearch driver definition")
|
||||
}
|
||||
if definition.Name != "Elasticsearch" {
|
||||
t.Fatalf("unexpected elasticsearch driver name: %q", definition.Name)
|
||||
}
|
||||
if definition.BuiltIn {
|
||||
t.Fatal("expected elasticsearch to be an optional driver agent")
|
||||
}
|
||||
if driverGoModulePathMap["elasticsearch"] != "github.com/elastic/go-elasticsearch/v8" {
|
||||
t.Fatalf("unexpected elasticsearch go module path: %q", driverGoModulePathMap["elasticsearch"])
|
||||
}
|
||||
if definition.PinnedVersion != "8.19.6" {
|
||||
t.Fatalf("unexpected elasticsearch definition pinned version: %q", definition.PinnedVersion)
|
||||
}
|
||||
if definition.DefaultDownloadURL != "builtin://activate/elasticsearch" {
|
||||
t.Fatalf("unexpected elasticsearch default download URL: %q", definition.DefaultDownloadURL)
|
||||
}
|
||||
if latestDriverVersionMap["elasticsearch"] != "8.19.6" {
|
||||
t.Fatalf("unexpected elasticsearch pinned version: %q", latestDriverVersionMap["elasticsearch"])
|
||||
}
|
||||
|
||||
tags, err := optionalDriverBuildTags("elasticsearch", "")
|
||||
if err != nil {
|
||||
t.Fatalf("resolve elasticsearch build tags failed: %v", err)
|
||||
}
|
||||
if tags != "gonavi_elasticsearch_driver" {
|
||||
t.Fatalf("unexpected elasticsearch build tag: %q", tags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionalDriverInstallPlanMessagePrefersDirectThenBundle(t *testing.T) {
|
||||
message := buildOptionalDriverInstallPlanMessage("SQL Server", "1.9.6", false, false, false, false, 1, 2)
|
||||
if !strings.Contains(message, "先尝试 1 个预编译直链") {
|
||||
|
||||
Reference in New Issue
Block a user