package darwindb import ( "context" "fmt" pgx "github.com/jackc/pgx/v4" "git.lukegb.com/lukegb/depot/go/trains/darwin" ) // ProcessReferenceData updates the database by processing a PportReferenceData message in the given transaction. func ProcessReferenceData(ctx context.Context, tx pgx.Tx, pprd *darwin.PushPortReferenceData, a *Affected) error { crsToTIPLOC := make(map[string]string) for _, loc := range pprd.Locations { if loc.CRS != nil { crsToTIPLOC[*loc.CRS] = loc.TIPLOC } _, err := tx.Exec(ctx, ` INSERT INTO ref_locations (tiploc, name, crs, toc) VALUES ($1, $2, $3, $4) ON CONFLICT (tiploc) DO UPDATE SET name=COALESCE(ref_locations.override_name, $2), crs=$3, toc=$4 `, loc.TIPLOC, loc.Name, loc.CRS, loc.TOC) if err != nil { return fmt.Errorf("updating location %q: %w", loc.TIPLOC, err) } a.TIPLOC(loc.TIPLOC) } for _, toc := range pprd.TOCs { _, err := tx.Exec(ctx, ` INSERT INTO ref_tocs (toc, name, url) VALUES ($1, $2, $3) ON CONFLICT (toc) DO UPDATE SET name=$2, url=$3 `, toc.TOC, toc.Name, toc.URL) if err != nil { return fmt.Errorf("updating TOC %q: %w", toc.TOC, err) } } for _, r := range pprd.LateRunningReasons { _, err := tx.Exec(ctx, ` INSERT INTO ref_late_running_reasons (code, text) VALUES ($1, $2) ON CONFLICT (code) DO UPDATE SET text=$2 `, r.Code, r.Text) if err != nil { return fmt.Errorf("updating LateRunningReason %q: %w", r.Code, err) } } for _, r := range pprd.CancellationReasons { _, err := tx.Exec(ctx, ` INSERT INTO ref_cancel_reasons (code, text) VALUES ($1, $2) ON CONFLICT (code) DO UPDATE SET text=$2 `, r.Code, r.Text) if err != nil { return fmt.Errorf("updating CancellationReason %q: %w", r.Code, err) } } for _, v := range pprd.Via { _, err := tx.Exec(ctx, ` INSERT INTO ref_via (at_crs, dest_tiploc, loc1_tiploc, loc2_tiploc, text) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (at_crs, dest_tiploc, loc1_tiploc, loc2_tiploc) DO UPDATE SET text=$5 RETURNING at_crs `, v.AtCRS, v.DestTIPLOC, v.Loc1TIPLOC, v.Loc2TIPLOC, v.Text) if err != nil { return fmt.Errorf("updating Via %v/%v/%v/%v: %w", v.AtCRS, v.DestTIPLOC, v.Loc1TIPLOC, v.Loc2TIPLOC, err) } tiploc, ok := crsToTIPLOC[v.AtCRS] if ok { a.TIPLOC(tiploc) } } for _, cis := range pprd.CISSource { _, err := tx.Exec(ctx, ` INSERT INTO ref_cis (code, name) VALUES ($1, $2) ON CONFLICT (code) DO UPDATE SET name=$2 `, cis.CISCode, cis.Name) if err != nil { return fmt.Errorf("updating CISSource %v: %w", cis.CISCode, err) } } return nil }