diff --git a/internal/dms/biz/cloudbeaver.go b/internal/dms/biz/cloudbeaver.go index 4488fb83..3ee84446 100644 --- a/internal/dms/biz/cloudbeaver.go +++ b/internal/dms/biz/cloudbeaver.go @@ -1765,7 +1765,7 @@ func (cu *CloudbeaverUsecase) GenerateCloudbeaverConnectionParams(dbService *DBS return nil, err } switch dbType { - case constant.DBTypeMySQL, constant.DBTypeTDSQLForInnoDB: + case constant.DBTypeMySQL, constant.DBTypeTDSQLForInnoDB, constant.DBTypePolarDBForMySQL: err = cu.fillMySQLParams(config) case constant.DBTypeTiDB: err = cu.fillTiDBParams(config) diff --git a/internal/dms/biz/cloudbeaver_test.go b/internal/dms/biz/cloudbeaver_test.go new file mode 100644 index 00000000..db101f0c --- /dev/null +++ b/internal/dms/biz/cloudbeaver_test.go @@ -0,0 +1,77 @@ +package biz + +import ( + "testing" + + utilLog "github.com/actiontech/dms/pkg/dms-common/pkg/log" +) + +// Test_GenerateCloudbeaverConnectionParams_PolarDB covers design.md §11.2 Table 4 +// (plan 5.10): verifies PolarDB DbService reuses fillMySQLParams to write the +// MySQL driverId and allowPublicKeyRetrieval properties, and that MySQL keeps +// the same behavior as a regression guard. +func Test_GenerateCloudbeaverConnectionParams_PolarDB(t *testing.T) { + cu := &CloudbeaverUsecase{ + log: utilLog.NewHelper(&noopLogger{}, utilLog.WithMessageKey("test")), + } + + cases := map[string]struct { + dbType string + wantDriverID string + wantAllowPublicKeyRetVal string + }{ + // (a) PolarDB happy: driverId == "mysql:mysql8" (plan 3.3) + "PolarDB driverId is mysql:mysql8": { + dbType: "PolarDB For MySQL", + wantDriverID: "mysql:mysql8", + wantAllowPublicKeyRetVal: "TRUE", + }, + // (b) PolarDB happy: properties.allowPublicKeyRetrieval == "TRUE" (fillMySQLParams reuse) + "PolarDB allowPublicKeyRetrieval is TRUE": { + dbType: "PolarDB For MySQL", + wantDriverID: "mysql:mysql8", + wantAllowPublicKeyRetVal: "TRUE", + }, + // (c) MySQL regression: confirm existing MySQL behavior is unchanged + "MySQL regression keeps driverId mysql:mysql8": { + dbType: "MySQL", + wantDriverID: "mysql:mysql8", + wantAllowPublicKeyRetVal: "TRUE", + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + dbService := &DBService{ + Name: "test-instance", + DBType: tc.dbType, + Host: "127.0.0.1", + Port: "3306", + User: "root", + Password: "pwd", + } + + resp, err := cu.GenerateCloudbeaverConnectionParams(dbService, "proj", "") + if err != nil { + t.Fatalf("GenerateCloudbeaverConnectionParams err: %v", err) + } + + config, ok := resp["config"].(map[string]interface{}) + if !ok { + t.Fatalf("config is not map[string]interface{}: %T", resp["config"]) + } + + if got := config["driverId"]; got != tc.wantDriverID { + t.Errorf("driverId = %v, want %v", got, tc.wantDriverID) + } + + props, ok := config["properties"].(map[string]interface{}) + if !ok { + t.Fatalf("properties is not map[string]interface{}: %T", config["properties"]) + } + if got := props["allowPublicKeyRetrieval"]; got != tc.wantAllowPublicKeyRetVal { + t.Errorf("allowPublicKeyRetrieval = %v, want %v", got, tc.wantAllowPublicKeyRetVal) + } + }) + } +} diff --git a/internal/dms/pkg/constant/const_test.go b/internal/dms/pkg/constant/const_test.go index 17baa17b..cd871b98 100644 --- a/internal/dms/pkg/constant/const_test.go +++ b/internal/dms/pkg/constant/const_test.go @@ -121,6 +121,10 @@ func TestParseDBType(t *testing.T) { "DM": {input: "DM", expected: DBTypeDM}, "GaussDB for MySQL": {input: "GaussDB for MySQL", expected: DBTypeGaussDB}, "HANA": {input: "HANA", expected: DBTypeHANA}, + // PolarDB-MySQL 新增 (Issue #826) + "PolarDB For MySQL": {input: "PolarDB For MySQL", expected: DBTypePolarDBForMySQL}, + // "PolarDB" 单独不应匹配 + "PolarDB only": {input: "PolarDB", expectError: true}, "invalid type": {input: "UnknownDB", expectError: true}, "empty string": {input: "", expectError: true}, } diff --git a/internal/sql_workbench/service/sql_workbench_service.go b/internal/sql_workbench/service/sql_workbench_service.go index 551086c2..ce7dc994 100644 --- a/internal/sql_workbench/service/sql_workbench_service.go +++ b/internal/sql_workbench/service/sql_workbench_service.go @@ -961,7 +961,8 @@ func (sqlWorkbenchService *SqlWorkbenchService) SupportDBType(dbType pkgConst.DB dbType == pkgConst.DBTypeDM || dbType == pkgConst.DBTypeTiDB || dbType == pkgConst.DBTypeTDSQLForInnoDB || - dbType == pkgConst.DBTypeGoldenDB + dbType == pkgConst.DBTypeGoldenDB || + dbType == pkgConst.DBTypePolarDBForMySQL } // buildDatabaseUser 当是ob-mysql时需要给账号管理的账号附加租户名集群名等字符: root@oms_mysql#oms_resource_4250 diff --git a/internal/sql_workbench/service/sql_workbench_service_test.go b/internal/sql_workbench/service/sql_workbench_service_test.go index ce6673c0..6c65ba0a 100644 --- a/internal/sql_workbench/service/sql_workbench_service_test.go +++ b/internal/sql_workbench/service/sql_workbench_service_test.go @@ -50,7 +50,7 @@ func Test_SupportDBType(t *testing.T) { "GoldenDB supported": {input: pkgConst.DBTypeGoldenDB, expected: true}, "PostgreSQL unsupported": {input: pkgConst.DBTypePostgreSQL, expected: false}, "SQL Server unsupported": {input: pkgConst.DBTypeSQLServer, expected: false}, - "PolarDB MySQL unsupported": {input: pkgConst.DBTypePolarDBMySQL, expected: false}, + "PolarDB For MySQL supported": {input: pkgConst.DBTypePolarDBForMySQL, expected: true}, } for name, tc := range cases { t.Run(name, func(t *testing.T) {