feat(awards): a reference's number can be corrected in the editor
The one field the editor would not let you touch, and the one that was wrong on WAJA. Every other property of a reference — its name, pattern, entity list, validity window — was editable; the code was rendered readOnly, so correcting a number meant deleting all 47 references and importing a new list, throwing away anything the operator had adjusted in it. A rename in the store, not a delete plus an insert: everything the reference carries travels with it, which is the whole point of correcting a number rather than replacing an entry. A number already in use is refused — REPLACE INTO would have let one reference silently swallow another, discovered much later as a prefecture quietly missing from the list. The typed code is held apart from the selection. The list and every field patch key off the selected code, so editing it in place made the editor lose the reference mid-edit. SaveAwardReference now recomputes the log like Delete and Replace already did. A reference's name is what the award column SHOWS for awards displaying by name, and its pattern is part of what matches at all — so editing one changes rows, and the grid was left showing the old label until something else happened to trigger a pass. Changelog: the three TCI-sharing lines are merged into one. The server and the two fixes made to it while building are one unreleased feature, and an operator only ever meets the finished thing. The TCI-client PTT line stays separate — it is OpsLog driving a SunSDR, the other direction entirely.
This commit is contained in:
@@ -266,6 +266,48 @@ func (r *Repo) Upsert(ctx context.Context, awardCode string, ref Ref) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rename changes a reference's CODE, keeping everything else about it.
|
||||
//
|
||||
// Wanted because a shipped list can simply be wrong: WAJA went out numbered by
|
||||
// the Japanese state instead of by the JARL, and the only way to correct it was
|
||||
// to delete all 47 references and import a new list — losing anything the
|
||||
// operator had adjusted. The number is the one field an editor could not touch.
|
||||
//
|
||||
// A rename, not a delete plus an insert: everything the reference carries — its
|
||||
// pattern, its DXCC list, its validity window — travels with it, which is the
|
||||
// whole point of correcting a number rather than replacing an entry.
|
||||
func (r *Repo) Rename(ctx context.Context, awardCode, oldCode, newCode string) error {
|
||||
ac := strings.ToUpper(strings.TrimSpace(awardCode))
|
||||
from := strings.ToUpper(strings.TrimSpace(oldCode))
|
||||
to := strings.ToUpper(strings.TrimSpace(newCode))
|
||||
if ac == "" || from == "" || to == "" {
|
||||
return fmt.Errorf("empty award or reference code")
|
||||
}
|
||||
if from == to {
|
||||
return nil
|
||||
}
|
||||
// A collision would REPLACE the other reference and take its name, pattern
|
||||
// and dates with it — one silently swallowing another, discovered much later
|
||||
// as a reference that has quietly gone missing.
|
||||
var n int
|
||||
if err := r.db.QueryRowContext(ctx,
|
||||
`SELECT COUNT(*) FROM award_references WHERE award_code = ? AND ref_code = ?`, ac, to).Scan(&n); err != nil {
|
||||
return err
|
||||
}
|
||||
if n > 0 {
|
||||
return fmt.Errorf("%s already has a reference %s", ac, to)
|
||||
}
|
||||
res, err := r.db.ExecContext(ctx,
|
||||
`UPDATE award_references SET ref_code = ? WHERE award_code = ? AND ref_code = ?`, to, ac, from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||
return fmt.Errorf("%s has no reference %s", ac, from)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes one reference from an award.
|
||||
func (r *Repo) Delete(ctx context.Context, awardCode, refCode string) error {
|
||||
_, err := r.db.ExecContext(ctx,
|
||||
|
||||
Reference in New Issue
Block a user