104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
|
package darwindb
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
pgx "github.com/jackc/pgx/v4"
|
||
|
"hg.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
|
||
|
}
|