diff --git a/internal/app/methods_sync.go b/internal/app/methods_sync.go index c60ba2a..e98a9fe 100644 --- a/internal/app/methods_sync.go +++ b/internal/app/methods_sync.go @@ -11,6 +11,21 @@ import ( "github.com/wailsapp/wails/v2/pkg/runtime" ) +func (a *App) resolveDataSyncConfigSecrets(config sync.SyncConfig) (sync.SyncConfig, error) { + resolved := config + sourceConfig, err := a.resolveConnectionSecrets(config.SourceConfig) + if err != nil { + return resolved, fmt.Errorf("恢复源数据库连接密文失败: %w", err) + } + targetConfig, err := a.resolveConnectionSecrets(config.TargetConfig) + if err != nil { + return resolved, fmt.Errorf("恢复目标数据库连接密文失败: %w", err) + } + resolved.SourceConfig = sourceConfig + resolved.TargetConfig = targetConfig + return resolved, nil +} + // DataSync executes a data synchronization task func (a *App) DataSync(config sync.SyncConfig) sync.SyncResult { jobID := strings.TrimSpace(config.JobID) @@ -33,8 +48,22 @@ func (a *App) DataSync(config sync.SyncConfig) sync.SyncResult { "total": len(config.Tables), }) + resolvedConfig, err := a.resolveDataSyncConfigSecrets(config) + if err != nil { + res := sync.SyncResult{ + Success: false, + Message: err.Error(), + Logs: []string{err.Error()}, + } + runtime.EventsEmit(a.ctx, sync.EventSyncDone, map[string]any{ + "jobId": jobID, + "result": res, + }) + return res + } + engine := sync.NewSyncEngine(reporter) - res := engine.RunSync(config) + res := engine.RunSync(resolvedConfig) runtime.EventsEmit(a.ctx, sync.EventSyncDone, map[string]any{ "jobId": jobID, @@ -67,8 +96,19 @@ func (a *App) DataSyncAnalyze(config sync.SyncConfig) connection.QueryResult { "type": "analyze", }) + resolvedConfig, err := a.resolveDataSyncConfigSecrets(config) + if err != nil { + res := sync.SyncResult{Success: false, Message: err.Error(), Logs: []string{err.Error()}} + runtime.EventsEmit(a.ctx, sync.EventSyncDone, map[string]any{ + "jobId": jobID, + "result": res, + "type": "analyze", + }) + return connection.QueryResult{Success: false, Message: err.Error(), Data: res} + } + engine := sync.NewSyncEngine(reporter) - res := engine.Analyze(config) + res := engine.Analyze(resolvedConfig) runtime.EventsEmit(a.ctx, sync.EventSyncDone, map[string]any{ "jobId": jobID, @@ -90,8 +130,13 @@ func (a *App) DataSyncPreview(config sync.SyncConfig, tableName string, limit in config.JobID = jobID } + resolvedConfig, err := a.resolveDataSyncConfigSecrets(config) + if err != nil { + return connection.QueryResult{Success: false, Message: err.Error()} + } + engine := sync.NewSyncEngine(sync.Reporter{}) - preview, err := engine.Preview(config, tableName, limit) + preview, err := engine.Preview(resolvedConfig, tableName, limit) if err != nil { return connection.QueryResult{Success: false, Message: err.Error()} } diff --git a/internal/app/methods_sync_test.go b/internal/app/methods_sync_test.go new file mode 100644 index 0000000..6257d75 --- /dev/null +++ b/internal/app/methods_sync_test.go @@ -0,0 +1,78 @@ +package app + +import ( + "testing" + + "GoNavi-Wails/internal/connection" + datasync "GoNavi-Wails/internal/sync" +) + +func TestResolveDataSyncConfigSecretsRestoresSavedSourceAndTargetPasswords(t *testing.T) { + app := NewAppWithSecretStore(newFakeAppSecretStore()) + app.configDir = t.TempDir() + + _, err := app.SaveConnection(connection.SavedConnectionInput{ + ID: "source-pg", + Name: "Source PostgreSQL", + Config: connection.ConnectionConfig{ + ID: "source-pg", + Type: "postgres", + Host: "source.local", + Port: 5432, + User: "postgres", + Password: "source-secret", + Database: "schedule", + }, + }) + if err != nil { + t.Fatalf("SaveConnection source returned error: %v", err) + } + _, err = app.SaveConnection(connection.SavedConnectionInput{ + ID: "target-pg", + Name: "Target PostgreSQL", + Config: connection.ConnectionConfig{ + ID: "target-pg", + Type: "postgres", + Host: "target.local", + Port: 5432, + User: "postgres", + Password: "target-secret", + Database: "warehouse", + }, + }) + if err != nil { + t.Fatalf("SaveConnection target returned error: %v", err) + } + + resolved, err := app.resolveDataSyncConfigSecrets(datasync.SyncConfig{ + SourceConfig: connection.ConnectionConfig{ + ID: "source-pg", + Type: "postgres", + Host: "source.local", + Port: 5432, + User: "postgres", + Database: "schedule", + }, + TargetConfig: connection.ConnectionConfig{ + ID: "target-pg", + Type: "postgres", + Host: "target.local", + Port: 5432, + User: "postgres", + Database: "warehouse", + }, + Tables: []string{"jobs"}, + }) + if err != nil { + t.Fatalf("resolveDataSyncConfigSecrets returned error: %v", err) + } + if resolved.SourceConfig.Password != "source-secret" { + t.Fatalf("expected source password to be restored, got %q", resolved.SourceConfig.Password) + } + if resolved.TargetConfig.Password != "target-secret" { + t.Fatalf("expected target password to be restored, got %q", resolved.TargetConfig.Password) + } + if resolved.SourceConfig.Database != "schedule" || resolved.TargetConfig.Database != "warehouse" { + t.Fatalf("expected selected databases to be preserved, got source=%q target=%q", resolved.SourceConfig.Database, resolved.TargetConfig.Database) + } +}