mirror of
https://github.com/Awuqing/BackupX.git
synced 2026-09-04 23:16:41 +08:00
功能: 新增 SAP HANA 完整备份支持与 Backint 协议代理 (#37)
* chore: ignore web/dist directory in git repository * 功能: 新增 SAP HANA 完整备份支持与 Backint 协议代理 - 修复 service 层校验 bug,使 SAP HANA 类型可正常创建 - 增强 hdbsql Runner:支持完整/增量/差异/日志备份、并行通道、失败重试 - 新增 Backint 协议代理(backupx backint 子命令),HANA 原生接口直连 BackupX 存储后端 - 新增本地 SQLite 目录维护 EBID↔对象键映射 - 前端新增 SAP HANA 扩展字段表单(备份类型/级别/通道数/重试次数/实例编号) - README 中英文补充 SAP HANA 两种模式的使用说明
This commit is contained in:
@@ -525,6 +525,22 @@ func (s *BackupExecutionService) buildTaskSpec(task *model.BackupTask, startedAt
|
||||
return backup.TaskSpec{}, apperror.Internal("BACKUP_TASK_DECODE_FAILED", "无法解析源路径配置", err)
|
||||
}
|
||||
}
|
||||
dbSpec := backup.DatabaseSpec{
|
||||
Host: task.DBHost,
|
||||
Port: task.DBPort,
|
||||
User: task.DBUser,
|
||||
Password: password,
|
||||
Names: []string{task.DBName},
|
||||
Path: task.DBPath,
|
||||
}
|
||||
// 解析 ExtraConfig 填充类型特有字段(目前主要用于 SAP HANA)
|
||||
if strings.TrimSpace(task.ExtraConfig) != "" {
|
||||
extra := map[string]any{}
|
||||
if err := json.Unmarshal([]byte(task.ExtraConfig), &extra); err != nil {
|
||||
return backup.TaskSpec{}, apperror.Internal("BACKUP_TASK_DECODE_FAILED", "无法解析扩展配置", err)
|
||||
}
|
||||
applyHANAExtraConfig(&dbSpec, extra)
|
||||
}
|
||||
return backup.TaskSpec{
|
||||
ID: task.ID,
|
||||
Name: task.Name,
|
||||
@@ -540,17 +556,30 @@ func (s *BackupExecutionService) buildTaskSpec(task *model.BackupTask, startedAt
|
||||
MaxBackups: task.MaxBackups,
|
||||
StartedAt: startedAt,
|
||||
TempDir: s.tempDir,
|
||||
Database: backup.DatabaseSpec{
|
||||
Host: task.DBHost,
|
||||
Port: task.DBPort,
|
||||
User: task.DBUser,
|
||||
Password: password,
|
||||
Names: []string{task.DBName},
|
||||
Path: task.DBPath,
|
||||
},
|
||||
Database: dbSpec,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// applyHANAExtraConfig 从 ExtraConfig map 中提取 SAP HANA 字段填入 DatabaseSpec。
|
||||
// 不识别的键被忽略,保持向后兼容。
|
||||
func applyHANAExtraConfig(spec *backup.DatabaseSpec, extra map[string]any) {
|
||||
if v, ok := extra["instanceNumber"].(string); ok {
|
||||
spec.InstanceNumber = strings.TrimSpace(v)
|
||||
}
|
||||
if v, ok := extra["backupLevel"].(string); ok {
|
||||
spec.BackupLevel = strings.ToLower(strings.TrimSpace(v))
|
||||
}
|
||||
if v, ok := extra["backupType"].(string); ok {
|
||||
spec.BackupType = strings.ToLower(strings.TrimSpace(v))
|
||||
}
|
||||
if v, ok := extra["backupChannels"].(float64); ok {
|
||||
spec.BackupChannels = int(v)
|
||||
}
|
||||
if v, ok := extra["maxRetries"].(float64); ok {
|
||||
spec.MaxRetries = int(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BackupExecutionService) loadRecordProvider(ctx context.Context, recordID uint) (*model.BackupRecord, storage.StorageProvider, error) {
|
||||
record, err := s.records.FindByID(ctx, recordID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user