Skip to content

Commit 8958aaf

Browse files
authored
Merge pull request #666 from actiontech/feat-964-odc-kingbase
feat: sync KingBase datasource type and default schema to ODC
2 parents d8232f9 + ebe4c18 commit 8958aaf

4 files changed

Lines changed: 103 additions & 1 deletion

File tree

internal/dms/pkg/constant/const.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ func ParseDBType(s string) (DBType, error) {
262262
return DBTypeRedis, nil
263263
case "OceanBase For Oracle":
264264
return DBTypeOceanBaseOracle, nil
265+
case "KingBase":
266+
return DBTypeKingBase, nil
265267

266268
default:
267269
return "", fmt.Errorf("invalid db type: %s", s)
@@ -288,6 +290,7 @@ const (
288290
DBTypeMongoDB DBType = "MongoDB"
289291
DBTypeRedis DBType = "Redis"
290292
DBTypeOceanBaseOracle DBType = "OceanBase For Oracle"
293+
DBTypeKingBase DBType = "KingBase"
291294
)
292295

293296
var supportedDataExportDBTypes = map[DBType]struct{}{

internal/dms/pkg/constant/const_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func TestParseDBType(t *testing.T) {
129129
"PolarDB For MySQL": {input: "PolarDB For MySQL", expected: DBTypePolarDBForMySQL},
130130
"MongoDB": {input: "MongoDB", expected: DBTypeMongoDB},
131131
"Redis": {input: "Redis", expected: DBTypeRedis},
132+
"KingBase": {input: "KingBase", expected: DBTypeKingBase},
132133
// "PolarDB" 单独不应匹配
133134
"PolarDB only": {input: "PolarDB", expectError: true},
134135
"invalid type": {input: "UnknownDB", expectError: true},

internal/sql_workbench/service/sql_workbench_service.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,16 @@ func (sqlWorkbenchService *SqlWorkbenchService) fillDatasourceBaseInfo(datasourc
10961096
baseInfo.DefaultSchema = &databaseName
10971097
}
10981098

1099+
// KingBase:database_name → ODC defaultSchema;缺失则失败,禁止静默空默认库
1100+
if dbService.DBType == string(pkgConst.DBTypeKingBase) {
1101+
databaseNameParam := dbService.AdditionalParams.GetParam("database_name")
1102+
if databaseNameParam == nil || databaseNameParam.Value == "" {
1103+
return nil, fmt.Errorf("KingBase 数据源 %s 缺少 AdditionalParam database_name,请在数据源 AdditionalParams 中补充", dbService.Name)
1104+
}
1105+
databaseName := databaseNameParam.Value
1106+
baseInfo.DefaultSchema = &databaseName
1107+
}
1108+
10991109
return baseInfo, nil
11001110
}
11011111

@@ -1187,6 +1197,8 @@ func (sqlWorkbenchService *SqlWorkbenchService) convertDBType(dmsDBType string)
11871197
return "REDIS"
11881198
case "DB2":
11891199
return "DB2"
1200+
case "KingBase":
1201+
return "KINGBASE"
11901202
default:
11911203
return dmsDBType
11921204
}
@@ -1203,7 +1215,8 @@ func (sqlWorkbenchService *SqlWorkbenchService) SupportDBType(dbType pkgConst.DB
12031215
dbType == pkgConst.DBTypePolarDBForMySQL ||
12041216
dbType == pkgConst.DBTypeGaussDB ||
12051217
dbType == pkgConst.DBTypePostgreSQL ||
1206-
dbType == pkgConst.DBTypeRedis
1218+
dbType == pkgConst.DBTypeRedis ||
1219+
dbType == pkgConst.DBTypeKingBase
12071220
}
12081221

12091222
func buildMongoDatasourceOptions(dbService *biz.DBService) (*string, interface{}, map[string]interface{}) {

internal/sql_workbench/service/sql_workbench_service_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ func Test_convertDBType(t *testing.T) {
150150
"MongoDB": {input: "MongoDB", expected: "MONGODB"},
151151
"Redis": {input: "Redis", expected: "REDIS"},
152152
"DB2": {input: "DB2", expected: "DB2"},
153+
"KingBase": {input: "KingBase", expected: "KINGBASE"},
153154
"Unknown passthrough": {input: "UnknownDB", expected: "UnknownDB"},
154155
}
155156
for name, tc := range cases {
@@ -183,6 +184,7 @@ func Test_SupportDBType(t *testing.T) {
183184
"GaussDB supported": {input: pkgConst.DBTypeGaussDB, expected: true},
184185
"GaussDBForMySQL unsupported": {input: pkgConst.DBTypeGaussDBForMySQL, expected: false},
185186
"DB2 unsupported": {input: pkgConst.DBTypeDB2, expected: false},
187+
"KingBase supported": {input: pkgConst.DBTypeKingBase, expected: true},
186188
"empty string unsupported": {input: pkgConst.DBType(""), expected: false},
187189
"unknown type unsupported": {input: pkgConst.DBType("UnknownDBType"), expected: false},
188190
}
@@ -390,6 +392,89 @@ func Test_buildDatasourceBaseInfo_DB2(t *testing.T) {
390392
}
391393
}
392394

395+
// Test_buildDatasourceBaseInfo_KingBase 覆盖 KingBase → defaultSchema 契约(S1 / AC-1):
396+
//
397+
// (a) 正例:database_name=test → DefaultSchema=="test" 且 Type 经 convert 为 KINGBASE
398+
// (b) 负例:缺 database_name → err 含 "database_name"
399+
// (c) MySQL 回归:DefaultSchema == nil
400+
func Test_buildDatasourceBaseInfo_KingBase(t *testing.T) {
401+
svc := &SqlWorkbenchService{}
402+
const envID = int64(1)
403+
const datasourceName = "proj:kingbase_odc_test"
404+
405+
cases := map[string]struct {
406+
dbService *biz.DBService
407+
expectErr bool
408+
expectErrSubstr string
409+
expectDefaultSchema *string
410+
expectType string
411+
}{
412+
"KingBase happy path": {
413+
dbService: &biz.DBService{
414+
Name: "kingbase_odc_test",
415+
DBType: string(pkgConst.DBTypeKingBase),
416+
Host: "10.186.16.126",
417+
Port: "1522",
418+
User: "kb_dev",
419+
AdditionalParams: pkgParams.Params{
420+
{Key: "database_name", Value: "test"},
421+
},
422+
},
423+
expectErr: false,
424+
expectDefaultSchema: strPtr("test"),
425+
expectType: "KINGBASE",
426+
},
427+
"KingBase missing database_name": {
428+
dbService: &biz.DBService{
429+
Name: "kingbase-missing-db",
430+
DBType: string(pkgConst.DBTypeKingBase),
431+
AdditionalParams: pkgParams.Params{},
432+
},
433+
expectErr: true,
434+
expectErrSubstr: "database_name",
435+
},
436+
"MySQL regression still no DefaultSchema": {
437+
dbService: &biz.DBService{
438+
Name: "mysql-1",
439+
DBType: "MySQL",
440+
AdditionalParams: pkgParams.Params{},
441+
},
442+
expectErr: false,
443+
expectDefaultSchema: nil,
444+
expectType: "MYSQL",
445+
},
446+
}
447+
448+
for name, tc := range cases {
449+
t.Run(name, func(t *testing.T) {
450+
got, err := svc.fillDatasourceBaseInfo(datasourceName, tc.dbService, envID)
451+
if tc.expectErr {
452+
if err == nil {
453+
t.Fatalf("expected error, got nil; baseInfo=%+v", got)
454+
}
455+
if tc.expectErrSubstr != "" && !strings.Contains(err.Error(), tc.expectErrSubstr) {
456+
t.Errorf("error %q does not contain %q", err.Error(), tc.expectErrSubstr)
457+
}
458+
return
459+
}
460+
if err != nil {
461+
t.Fatalf("unexpected error: %v", err)
462+
}
463+
if got == nil {
464+
t.Fatalf("expected non-nil baseInfo")
465+
}
466+
if tc.expectType != "" && got.Type != tc.expectType {
467+
t.Errorf("Type = %q, want %q", got.Type, tc.expectType)
468+
}
469+
if (got.DefaultSchema == nil) != (tc.expectDefaultSchema == nil) {
470+
t.Errorf("DefaultSchema nil mismatch: got=%v, want=%v", got.DefaultSchema, tc.expectDefaultSchema)
471+
} else if got.DefaultSchema != nil && tc.expectDefaultSchema != nil && *got.DefaultSchema != *tc.expectDefaultSchema {
472+
t.Errorf("DefaultSchema = %q, want %q", *got.DefaultSchema, *tc.expectDefaultSchema)
473+
}
474+
})
475+
}
476+
}
477+
393478
func strPtr(s string) *string {
394479
return &s
395480
}

0 commit comments

Comments
 (0)