diff --git a/docs/issues/2026-04-11-issue-backlog-tracking.md b/docs/issues/2026-04-11-issue-backlog-tracking.md index 2c5d544..c388736 100644 --- a/docs/issues/2026-04-11-issue-backlog-tracking.md +++ b/docs/issues/2026-04-11-issue-backlog-tracking.md @@ -32,6 +32,7 @@ | #331 | 重复连接 DB,一分钟重试了 60 多次 | Fixed | `ca76440` | | #333 | AI 功能添加供应商测试正常,但问答显示失败 | Fixed | Pending | | #337 | 自动更新无效 | Fixed | Pending | +| #338 | 连接clickhouse不能通过8132端口 | Fixed | Pending | | #351 | 为什么没有截断和清空表的功能呀? | Fixed | Pending | ## Notes @@ -102,6 +103,12 @@ - 处理:为更新资产解析新增“基于当前可执行文件路径推断 Linux 变体”的后缀选择逻辑;同时调整 Linux 更新脚本,解压后优先搜索与当前运行二进制同名的文件,再回退查找 `GoNavi`。 - 验证:补充 `internal/app/methods_update_test.go` 回归测试,覆盖 Linux `WebKit41` 资产名选择与更新脚本目标名解析,并执行 `go test ./internal/app -run 'Test(ExpectedAssetNameForExecutableUsesLinuxWebKit41Suffix|BuildLinuxScriptPrefersTargetExecutableBasename|TestFetchLatestUpdateInfo|TestCheckForUpdates|TestBuildWindowsScript)' -count=1`。 +### #338 + +- 根因:ClickHouse 连接协议识别只把 `8123/8443` 视为 HTTP 端口,`8132` 会被误判为 native,导致连接阶段优先走错协议。 +- 处理:将 `8132` 纳入 ClickHouse HTTP 端口识别,并同步更新自动切换日志和错误提示中的端口说明,避免排障信息继续误导。 +- 验证:补充 `internal/db/clickhouse_impl_test.go` 回归测试,覆盖 `8132`、`8123`、`8443` 的 HTTP 判定以及 `9000/9440` 的 native 判定,并执行 `go test -tags gonavi_clickhouse_driver ./internal/db -run 'TestClickHouse(PingValidatesQueryPath|GetDatabasesFallsBackToCurrentDatabase|DetectClickHouseProtocolTreatsHTTPPortsAsHTTP)' -count=1`。 + ### #330 - 根因:查询结果表格已经支持拖拽调整列宽,但 resize handle 没有提供双击自适应逻辑,导致用户只能靠手工拖拽慢慢试宽度。 diff --git a/internal/db/clickhouse_impl.go b/internal/db/clickhouse_impl.go index aad3011..15a5964 100644 --- a/internal/db/clickhouse_impl.go +++ b/internal/db/clickhouse_impl.go @@ -26,6 +26,7 @@ const ( defaultClickHouseUser = "default" defaultClickHouseDatabase = "default" minClickHouseReadTimeout = 5 * time.Minute + clickHouseHTTPPortHint = "8123/8132/8443" ) type ClickHouseDB struct { @@ -133,12 +134,21 @@ func detectClickHouseProtocol(config connection.ConnectionConfig) clickhouse.Pro if strings.HasPrefix(uriText, "http://") || strings.HasPrefix(uriText, "https://") { return clickhouse.HTTP } - if config.Port == 8123 || config.Port == 8443 { + if isClickHouseHTTPPort(config.Port) { return clickhouse.HTTP } return clickhouse.Native } +func isClickHouseHTTPPort(port int) bool { + switch port { + case 8123, 8132, 8443: + return true + default: + return false + } +} + func isClickHouseProtocolMismatch(err error) bool { if err == nil { return false @@ -246,14 +256,14 @@ func (c *ClickHouseDB) Connect(config connection.ConnectionConfig) error { logger.Warnf("ClickHouse SSL 优先连接失败,已回退至明文连接") } if pIdx > 0 { - logger.Warnf("ClickHouse 已自动切换连接协议为 %s(常见于 8123/8443 HTTP 端口)", protocol.String()) + logger.Warnf("ClickHouse 已自动切换连接协议为 %s(常见于 %s HTTP 端口)", protocol.String(), clickHouseHTTPPortHint) } return nil } } _ = c.Close() - return fmt.Errorf("连接建立后验证失败(可检查 ClickHouse 端口与协议是否匹配:Native=9000/9440,HTTP=8123/8443):%s", strings.Join(failures, ";")) + return fmt.Errorf("连接建立后验证失败(可检查 ClickHouse 端口与协议是否匹配:Native=9000/9440,HTTP=%s):%s", clickHouseHTTPPortHint, strings.Join(failures, ";")) } func (c *ClickHouseDB) Close() error { diff --git a/internal/db/clickhouse_impl_test.go b/internal/db/clickhouse_impl_test.go index cd7c7b5..cd7c2f2 100644 --- a/internal/db/clickhouse_impl_test.go +++ b/internal/db/clickhouse_impl_test.go @@ -12,6 +12,10 @@ import ( "sync" "testing" "time" + + "GoNavi-Wails/internal/connection" + + clickhouse "github.com/ClickHouse/clickhouse-go/v2" ) const fakeClickHouseDriverName = "gonavi-fake-clickhouse" @@ -129,6 +133,65 @@ func TestClickHouseGetDatabasesFallsBackToCurrentDatabase(t *testing.T) { } } +func TestDetectClickHouseProtocolTreatsHTTPPortsAsHTTP(t *testing.T) { + tests := []struct { + name string + config connection.ConnectionConfig + expected clickhouse.Protocol + }{ + { + name: "http uri", + config: connection.ConnectionConfig{ + URI: "http://127.0.0.1:8132/default", + }, + expected: clickhouse.HTTP, + }, + { + name: "default http port", + config: connection.ConnectionConfig{ + Port: 8123, + }, + expected: clickhouse.HTTP, + }, + { + name: "alternate http port 8132", + config: connection.ConnectionConfig{ + Port: 8132, + }, + expected: clickhouse.HTTP, + }, + { + name: "https port", + config: connection.ConnectionConfig{ + Port: 8443, + }, + expected: clickhouse.HTTP, + }, + { + name: "native port", + config: connection.ConnectionConfig{ + Port: 9000, + }, + expected: clickhouse.Native, + }, + { + name: "native tls port", + config: connection.ConnectionConfig{ + Port: 9440, + }, + expected: clickhouse.Native, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if protocol := detectClickHouseProtocol(tt.config); protocol != tt.expected { + t.Fatalf("expected protocol %s, got %s", tt.expected.String(), protocol.String()) + } + }) + } +} + type fakeClickHouseDriver struct{} func (fakeClickHouseDriver) Open(name string) (driver.Conn, error) {