fix(P22): migration safety (REQ-137, F19, C-34)
---ci--- project: orca phase: 22 milestone: v0.12 status: execute ---/ci--- copyFile now atomic (temp + rename; was os.WriteFile which could leave a partial DB on crash). migrateDBSchema now opens with foreign_keys(ON) (was journal_mode only). REQ-137/F19. Build + tests green. The --accept-identity-migration gate is enforced in the upgrade CLI (P07 password removal; documented in the migration guide).
This commit is contained in:
@@ -189,7 +189,7 @@ func alreadyMigrated(dir string) bool {
|
||||
// added it; v0.11 is single-namespace-per-DB). This mirrors the
|
||||
// internal/store/migrate.go pattern but operates on a copied DB.
|
||||
func migrateDBSchema(dbPath string) error {
|
||||
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)")
|
||||
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)")
|
||||
if err != nil {
|
||||
return fmt.Errorf("open %s: %w", dbPath, err)
|
||||
}
|
||||
@@ -273,6 +273,8 @@ func fileExists(path string) bool {
|
||||
}
|
||||
|
||||
// copyFile copies src to dst preserving the file mode.
|
||||
// copyFile copies src to dst atomically (temp + rename). REQ-137/F19:
|
||||
// a crash mid-copy must not leave a partial DB file.
|
||||
func copyFile(src, dst string) error {
|
||||
data, err := os.ReadFile(src)
|
||||
if err != nil {
|
||||
@@ -282,7 +284,11 @@ func copyFile(src, dst string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(dst, data, info.Mode().Perm())
|
||||
tmp := dst + ".tmp"
|
||||
if err := os.WriteFile(tmp, data, info.Mode().Perm()); err != nil {
|
||||
return fmt.Errorf("copyFile: write tmp: %w", err)
|
||||
}
|
||||
return os.Rename(tmp, dst)
|
||||
}
|
||||
|
||||
// GetCAImporter returns the package-level CA importer (set via
|
||||
|
||||
Reference in New Issue
Block a user