65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package migrate
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"account/internal/utils"
|
|
)
|
|
|
|
const defaultSchemaPath = "sql/schema.sql"
|
|
|
|
// Verifier validates that the live database matches the canonical schema.sql.
|
|
type Verifier struct{}
|
|
|
|
func NewVerifier() *Verifier {
|
|
return &Verifier{}
|
|
}
|
|
|
|
func (v *Verifier) Verify(ctx context.Context, dsn, schemaPath string) error {
|
|
if dsn == "" {
|
|
return errors.New("--dsn is required")
|
|
}
|
|
if schemaPath == "" {
|
|
schemaPath = defaultSchemaPath
|
|
}
|
|
|
|
dump, err := utils.RunPgDump(ctx, dsn)
|
|
if err != nil {
|
|
return fmt.Errorf("dump database schema: %w", err)
|
|
}
|
|
|
|
schemaBytes, err := os.ReadFile(schemaPath)
|
|
if err != nil {
|
|
return fmt.Errorf("read schema file: %w", err)
|
|
}
|
|
|
|
dbStatements := utils.NormalizeStatements(dump)
|
|
fileStatements := utils.NormalizeStatements(string(schemaBytes))
|
|
|
|
onlyDB, onlyFile := utils.CompareStatements(dbStatements, fileStatements)
|
|
|
|
if len(onlyDB) == 0 && len(onlyFile) == 0 {
|
|
fmt.Println("✅ Database schema matches schema.sql")
|
|
return nil
|
|
}
|
|
|
|
if len(onlyFile) > 0 {
|
|
fmt.Println("⚠️ Statements missing from database (present in schema.sql):")
|
|
for _, stmt := range onlyFile {
|
|
fmt.Printf(" + %s;\n", stmt)
|
|
}
|
|
}
|
|
|
|
if len(onlyDB) > 0 {
|
|
fmt.Println("⚠️ Extra statements found in database:")
|
|
for _, stmt := range onlyDB {
|
|
fmt.Printf(" - %s;\n", stmt)
|
|
}
|
|
}
|
|
|
|
return errors.New("schema mismatch detected")
|
|
}
|