fix: enforce no foreign keys in new migrations
This commit is contained in:
@@ -176,6 +176,9 @@ func Migrate(ctx context.Context, db *sql.DB) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("migration %d: %w", m.Version, err)
|
||||
}
|
||||
if err := validateNoReferenceDDL(m.Version, statements); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := conn.ExecContext(ctx, "INSERT INTO orbit_schema_migrations (version,name,checksum,dirty) VALUES (?,?,?,TRUE)", m.Version, m.Name, m.Checksum); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -191,6 +194,24 @@ func Migrate(ctx context.Context, db *sql.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateNoReferenceDDL protects the post-removal migration line at runtime.
|
||||
// Versions 1-8 are immutable compatibility history: version 8 removes the
|
||||
// legacy constraints from databases that were created before the no-FK policy.
|
||||
// Every later migration must be incapable of creating or retaining a database
|
||||
// reference constraint, even if a future author forgets the static test.
|
||||
func validateNoReferenceDDL(version uint64, statements []string) error {
|
||||
if version <= 8 {
|
||||
return nil
|
||||
}
|
||||
for _, statement := range statements {
|
||||
upper := strings.ToUpper(statement)
|
||||
if strings.Contains(upper, "FOREIGN KEY") || strings.Contains(upper, " REFERENCES ") {
|
||||
return fmt.Errorf("migration %d contains forbidden foreign-key DDL", version)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyFreshInstallBaseline creates a new database directly at the current
|
||||
// schema version. It records every historical migration as dirty before DDL so
|
||||
// an interrupted baseline remains blocked for operator reconciliation, just
|
||||
|
||||
Reference in New Issue
Block a user