102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
// Command postgis-srid-migrate performs the explicitly approved EPSG:4326 metadata migration.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"fire-safety-ymd/internal/migration"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
const (
|
|
migrationDSNEnv = "FIRE_SAFETY_POSTGIS_MIGRATION_DSN"
|
|
runtimeDSNEnv = "FIRE_SAFETY_POSTGIS_DSN"
|
|
commandTimeout = 3 * time.Minute
|
|
)
|
|
|
|
func main() {
|
|
apply := flag.Bool("apply", false, "commit the reviewed SRID metadata migration")
|
|
confirmation := flag.String("confirm-source-crs", "", "required with --apply; must equal EPSG:4326")
|
|
flag.Parse()
|
|
|
|
dsn, err := selectDSN(*apply)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
connectionConfig, err := pgx.ParseConfig(dsn)
|
|
if err != nil {
|
|
log.Fatal("parse PostGIS migration configuration")
|
|
}
|
|
connectionConfig.RuntimeParams["application_name"] = "fire-safety-ymd-srid-migration"
|
|
|
|
signalCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
ctx, cancel := context.WithTimeout(signalCtx, commandTimeout)
|
|
defer cancel()
|
|
|
|
conn, err := pgx.ConnectConfig(ctx, connectionConfig)
|
|
if err != nil {
|
|
log.Fatal("connect to PostGIS for SRID migration")
|
|
}
|
|
defer func() { _ = conn.Close(context.Background()) }()
|
|
|
|
if !*apply {
|
|
report, err := migration.Inspect(ctx, conn)
|
|
if err != nil {
|
|
log.Fatalf("inspect SRID migration state: %v", err)
|
|
}
|
|
writeJSON(report)
|
|
if err := migration.ValidateForApply(report); err != nil {
|
|
log.Fatalf("SRID migration preflight failed: %v", err)
|
|
}
|
|
fmt.Fprintln(os.Stderr, "preflight passed; no database changes were made")
|
|
return
|
|
}
|
|
|
|
if *confirmation != "EPSG:4326" {
|
|
log.Fatal("--apply requires --confirm-source-crs=EPSG:4326")
|
|
}
|
|
result, err := migration.ApplySRID4326(ctx, conn)
|
|
if err != nil {
|
|
log.Fatalf("apply SRID migration: %v", err)
|
|
}
|
|
writeJSON(result)
|
|
fmt.Fprintln(os.Stderr, "SRID metadata migration committed")
|
|
}
|
|
|
|
func selectDSN(apply bool) (string, error) {
|
|
migrationDSN := strings.TrimSpace(os.Getenv(migrationDSNEnv))
|
|
if apply {
|
|
if migrationDSN == "" {
|
|
return "", fmt.Errorf("%s is required with --apply", migrationDSNEnv)
|
|
}
|
|
return migrationDSN, nil
|
|
}
|
|
if migrationDSN != "" {
|
|
return migrationDSN, nil
|
|
}
|
|
runtimeDSN := strings.TrimSpace(os.Getenv(runtimeDSNEnv))
|
|
if runtimeDSN == "" {
|
|
return "", fmt.Errorf("%s or %s is required", migrationDSNEnv, runtimeDSNEnv)
|
|
}
|
|
return runtimeDSN, nil
|
|
}
|
|
|
|
func writeJSON(value any) {
|
|
encoder := json.NewEncoder(os.Stdout)
|
|
encoder.SetIndent("", " ")
|
|
if err := encoder.Encode(value); err != nil {
|
|
log.Fatalf("encode migration report: %v", err)
|
|
}
|
|
}
|