Skip to content

Commit 4eac3de

Browse files
committed
feat: Support MySQL data synchronization collation
1 parent c3cc26a commit 4eac3de

File tree

6 files changed

+42
-9
lines changed

6 files changed

+42
-9
lines changed

agent/app/dto/database.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type MysqlDBInfo struct {
3838
From string `json:"from"`
3939
MysqlName string `json:"mysqlName"`
4040
Format string `json:"format"`
41+
Collation string `json:"collation"`
4142
Username string `json:"username"`
4243
Password string `json:"password"`
4344
Permission string `json:"permission"`

agent/init/migration/migrations/init.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,8 +728,31 @@ var AddGPUMonitor = &gormigrate.Migration{
728728
}
729729

730730
var UpdateDatabaseMysql = &gormigrate.Migration{
731-
ID: "20251125-update-database-mysql",
732-
Migrate: func(tx *gorm.DB) error {
733-
return tx.AutoMigrate(&model.DatabaseMysql{})
731+
ID: "20251126-update-database-mysql",
732+
Migrate: func(tx *gorm.DB) error {
733+
if err := tx.AutoMigrate(&model.DatabaseMysql{}); err != nil {
734+
return err
735+
}
736+
var data []model.DatabaseMysql
737+
_ = tx.Where("1 = 1").Find(&data).Error
738+
for _, item := range data {
739+
if len(item.Collation) == 0 {
740+
collation := ""
741+
switch item.Format {
742+
case "utf8":
743+
collation = "utf8_general_ci"
744+
case "utf8mb4":
745+
collation = "utf8mb4_general_ci"
746+
case "gbk":
747+
collation = "gbk_chinese_ci"
748+
case "big5":
749+
collation = "big5_chinese_ci"
750+
default:
751+
collation = "utf8mb4_general_ci"
752+
}
753+
_ = tx.Model(&model.DatabaseMysql{}).Where("id = ?", item.ID).Updates(map[string]interface{}{"collation": collation}).Error
754+
}
755+
}
756+
return nil
734757
},
735758
}

agent/utils/mysql/client/info.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ type SyncDBInfo struct {
101101
From string `json:"from"`
102102
MysqlName string `json:"mysqlName"`
103103
Format string `json:"format"`
104+
Collation string `json:"collation"`
104105
Username string `json:"username"`
105106
Password string `json:"password"`
106107
Permission string `json:"permission"`

agent/utils/mysql/client/local.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ func NewLocal(command []string, dbType, containerName, password, database string
3333

3434
func (r *Local) Create(info CreateInfo) error {
3535
createSql := fmt.Sprintf("create database `%s` default character set %s collate %s", info.Name, info.Format, info.Collation)
36+
if len(info.Collation) == 0 {
37+
createSql = fmt.Sprintf("create database `%s` default character set %s", info.Name, info.Format)
38+
}
3639
if err := r.ExecSQL(createSql, info.Timeout); err != nil {
3740
if strings.Contains(strings.ToLower(err.Error()), "error 1007") {
3841
return buserr.New("ErrDatabaseIsExist")
@@ -287,13 +290,13 @@ func (r *Local) Recover(info RecoverInfo) error {
287290

288291
func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
289292
var datas []SyncDBInfo
290-
lines, err := r.ExecSQLForRows("SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA", 300)
293+
lines, err := r.ExecSQLForRows("SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA", 300)
291294
if err != nil {
292295
return datas, err
293296
}
294297
for _, line := range lines {
295298
parts := strings.Fields(line)
296-
if len(parts) != 2 {
299+
if len(parts) != 3 {
297300
continue
298301
}
299302
if parts[0] == "SCHEMA_NAME" || parts[0] == "information_schema" || parts[0] == "mysql" || parts[0] == "performance_schema" || parts[0] == "sys" || parts[0] == "__recycle_bin__" || parts[0] == "recycle_bin" {
@@ -304,6 +307,7 @@ func (r *Local) SyncDB(version string) ([]SyncDBInfo, error) {
304307
From: "local",
305308
MysqlName: r.Database,
306309
Format: parts[1],
310+
Collation: parts[2],
307311
}
308312
userLines, err := r.ExecSQLForRows(fmt.Sprintf("select user,host from mysql.db where db = '%s'", parts[0]), 300)
309313
if err != nil {

agent/utils/mysql/client/remote.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ func NewRemote(db Remote) *Remote {
4444

4545
func (r *Remote) Create(info CreateInfo) error {
4646
createSql := fmt.Sprintf("create database `%s` default character set %s collate %s", info.Name, info.Format, info.Collation)
47+
if len(info.Collation) == 0 {
48+
createSql = fmt.Sprintf("create database `%s` default character set %s", info.Name, info.Format)
49+
}
4750
if err := r.ExecSQL(createSql, info.Timeout); err != nil {
4851
if strings.Contains(strings.ToLower(err.Error()), "error 1007") {
4952
return buserr.New("ErrDatabaseIsExist")
@@ -311,15 +314,15 @@ func (r *Remote) Recover(info RecoverInfo) error {
311314

312315
func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
313316
var datas []SyncDBInfo
314-
rows, err := r.Client.Query("select schema_name, default_character_set_name from information_schema.SCHEMATA")
317+
rows, err := r.Client.Query("select schema_name, default_character_set_name, default_collation_name from information_schema.SCHEMATA")
315318
if err != nil {
316319
return datas, err
317320
}
318321
defer rows.Close()
319322

320323
for rows.Next() {
321-
var dbName, charsetName string
322-
if err = rows.Scan(&dbName, &charsetName); err != nil {
324+
var dbName, charsetName, collation string
325+
if err = rows.Scan(&dbName, &charsetName, &collation); err != nil {
323326
return datas, err
324327
}
325328
if dbName == "information_schema" || dbName == "mysql" || dbName == "performance_schema" || dbName == "sys" || dbName == "__recycle_bin__" || dbName == "recycle_bin" {
@@ -330,6 +333,7 @@ func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) {
330333
From: "remote",
331334
MysqlName: r.Database,
332335
Format: charsetName,
336+
Collation: collation,
333337
}
334338
userRows, err := r.Client.Query("select user,host from mysql.db where db = ?", dbName)
335339
if err != nil {

frontend/src/views/database/mysql/create/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</el-select>
1616
</el-form-item>
1717
<el-form-item :label="$t('database.collation')" prop="collation">
18-
<el-select filterable v-model="form.collation">
18+
<el-select filterable v-model="form.collation" clearable>
1919
<el-option v-for="item of collationOptions" :key="item" :label="item" :value="item" />
2020
</el-select>
2121
<span class="input-help">{{ $t('database.collationHelper', [form.format]) }}</span>

0 commit comments

Comments
 (0)