Skip to content

Commit 9c4238d

Browse files
committed
feat: add restore_database config option for snapshot restore
1 parent 256cbe4 commit 9c4238d

3 files changed

Lines changed: 31 additions & 7 deletions

File tree

regresql/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type (
3535
MigrationCommand string `yaml:"migration_command,omitempty"` // external command to run migrations (e.g., goose, migrate)
3636
Fixtures []string `yaml:"fixtures,omitempty"` // SQL/YAML fixture files for snapshot build
3737
AutoRestore *bool `yaml:"auto_restore,omitempty"` // restore snapshot before test (default: true if path is set)
38+
RestoreDatabase string `yaml:"restore_database,omitempty"` // override target database for restore
3839
}
3940
)
4041

regresql/regresql.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ func autoRestore(cfg config, root string, noRestore bool) {
146146
}
147147
fmt.Printf("Restoring snapshot: %s\n", snapshotPath)
148148
opts := RestoreOptions{
149-
InputPath: snapshotPath,
150-
Clean: true,
149+
InputPath: snapshotPath,
150+
Clean: true,
151+
TargetDatabase: cfg.Snapshot.RestoreDatabase,
151152
}
152153
if err := RestoreSnapshot(cfg.PgUri, opts); err != nil {
153154
fmt.Printf("Error: failed to restore snapshot: %s\n", err)

regresql/snapshot.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"fmt"
77
"io"
8+
"net/url"
89
"os"
910
"os/exec"
1011
"path/filepath"
@@ -61,9 +62,10 @@ type (
6162
}
6263

6364
RestoreOptions struct {
64-
InputPath string
65-
Format SnapshotFormat
66-
Clean bool // drop existing objects before restore
65+
InputPath string
66+
Format SnapshotFormat
67+
Clean bool // drop existing objects before restore
68+
TargetDatabase string // override database name from connection string
6769
}
6870
)
6971

@@ -428,21 +430,41 @@ func ShouldAutoRestore(cfg *SnapshotConfig) bool {
428430
return *cfg.AutoRestore
429431
}
430432

433+
// replaceDatabase returns a new connection string with a different database
434+
func replaceDatabase(pguri, newDB string) (string, error) {
435+
u, err := url.Parse(pguri)
436+
if err != nil {
437+
return "", err
438+
}
439+
u.Path = "/" + newDB
440+
return u.String(), nil
441+
}
442+
431443
// RestoreSnapshot restores a database snapshot using pg_restore or psql
432444
func RestoreSnapshot(pguri string, opts RestoreOptions) error {
433445
if _, err := os.Stat(opts.InputPath); os.IsNotExist(err) {
434446
return fmt.Errorf("snapshot file not found: %s", opts.InputPath)
435447
}
436448

449+
// Override target database if specified
450+
targetURI := pguri
451+
if opts.TargetDatabase != "" {
452+
var err error
453+
targetURI, err = replaceDatabase(pguri, opts.TargetDatabase)
454+
if err != nil {
455+
return fmt.Errorf("failed to set target database: %w", err)
456+
}
457+
}
458+
437459
format := opts.Format
438460
if format == "" {
439461
format = DetectSnapshotFormat(opts.InputPath)
440462
}
441463

442464
if format == FormatPlain {
443-
return restoreWithPsql(pguri, opts)
465+
return restoreWithPsql(targetURI, opts)
444466
}
445-
return restoreWithPgRestore(pguri, opts, format)
467+
return restoreWithPgRestore(targetURI, opts, format)
446468
}
447469

448470
func restoreWithPgRestore(pguri string, opts RestoreOptions, format SnapshotFormat) error {

0 commit comments

Comments
 (0)