Files
MyGoNavi/internal/sync/migration_runtime_helpers.go
Syngnat b9f9a8fca2 feat(sync): 扩展跨库迁移自动建表能力
- 新增 MySQL、PG-like、ClickHouse、MongoDB 同类库迁移规划器
- 支持可映射库对自动建表、补字段及兼容索引迁移
- 修复 MongoDB 创建集合时建表 SQL 为空的执行判断
- 避免 PG-like 主键索引重复迁移并保留默认值表达式
- 更新 Data Sync 自动建表能力提示与回归测试
Refs #465
2026-05-15 20:33:42 +08:00

79 lines
2.6 KiB
Go

package sync
import (
"GoNavi-Wails/internal/connection"
"fmt"
"strings"
)
func supportsAutoAddColumnsForPair(sourceType string, targetType string) bool {
source := normalizeMigrationDBType(sourceType)
target := normalizeMigrationDBType(targetType)
if isMySQLLikeWritableTargetType(target) {
return isMySQLCoreType(source)
}
if isPGLikeSameFamilyDDLType(source) && isPGLikeSameFamilyDDLType(target) {
return true
}
if isPGLikeTarget(target) {
return isMySQLLikeSourceType(source)
}
if source == "clickhouse" && target == "clickhouse" {
return true
}
return false
}
func buildAddColumnSQLForPair(sourceType string, targetType string, targetQueryTable string, sourceCol connection.ColumnDefinition) (string, error) {
source := normalizeMigrationDBType(sourceType)
target := normalizeMigrationDBType(targetType)
switch {
case isMySQLCoreType(source) && isMySQLLikeWritableTargetType(target):
colType := sanitizeMySQLColumnType(sourceCol.Type)
return fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s NULL",
quoteQualifiedIdentByType("mysql", targetQueryTable),
quoteIdentByType("mysql", sourceCol.Name),
colType,
), nil
case isMySQLLikeSourceType(source) && isPGLikeTarget(target):
colType, _, warnings := mapMySQLColumnToKingbase(sourceCol)
if len(warnings) > 0 && strings.Contains(strings.Join(warnings, " "), "identity") {
// 对已有目标表补字段时保守处理,不补建自增语义。
}
return fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s NULL",
quoteQualifiedIdentByType(target, targetQueryTable),
quoteIdentByType(target, sourceCol.Name),
colType,
), nil
case isPGLikeSameFamilyDDLType(source) && isPGLikeSameFamilyDDLType(target):
colType := sanitizePGLikeColumnType(sourceCol.Type)
return fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s NULL",
quoteQualifiedIdentByType(target, targetQueryTable),
quoteIdentByType(target, sourceCol.Name),
colType,
), nil
case source == "clickhouse" && target == "clickhouse":
colType := sanitizeClickHouseColumnType(sourceCol.Type)
return fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s",
quoteQualifiedIdentByType(target, targetQueryTable),
quoteIdentByType(target, sourceCol.Name),
colType,
), nil
default:
return "", fmt.Errorf("当前不支持 source=%s target=%s 的自动补字段", sourceType, targetType)
}
}
func executeSQLStatements(execFn func(string) (int64, error), statements []string) error {
for _, stmt := range statements {
trimmed := strings.TrimSpace(stmt)
if trimmed == "" {
continue
}
if _, err := execFn(trimmed); err != nil {
return err
}
}
return nil
}