From 66ac5c365191d7515f7f796e95a754f6882cda8e Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 5 Jul 2025 11:12:37 +0200 Subject: Code simplification --- src/dbx/mintages.go | 167 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 142 insertions(+), 25 deletions(-) (limited to 'src/dbx/mintages.go') diff --git a/src/dbx/mintages.go b/src/dbx/mintages.go index 4a6d5d3..d78e59c 100644 --- a/src/dbx/mintages.go +++ b/src/dbx/mintages.go @@ -1,31 +1,57 @@ package dbx +import ( + "database/sql" + "slices" +) + type MintageData struct { Standard []MSRow Commemorative []MCRow } +type msRowInternal struct { + Country string + Type MintageType + Year int + Denomination float64 + Mintmark sql.Null[string] + Mintage sql.Null[int] + Reference sql.Null[string] +} + +type mcRowInternal struct { + Country string + Type MintageType + Year int + Name string + Number int + Mintmark sql.Null[string] + Mintage sql.Null[int] + Reference sql.Null[string] +} + type MSRow struct { - Type int `db:"type"` - Year int `db:"year"` - Mintmark string `db:"mintmark"` - Mintages [ndenoms]int `db:"€0,01;€0,02;€0,05;€0,10;€0,20;€0,50;€1,00;€2,00"` - Reference string `db:"reference"` + Year int + Mintmark string + Mintages [ndenoms]int + References []string } type MCRow struct { - Type int `db:"type"` - Year int `db:"year"` - Name string `db:"name"` - Number int `db:"number"` - Mintmark string `db:"mintmark"` - Mintage int `db:"mintage"` - Reference string `db:"reference"` + Year int + Name string + Number int + Mintmark string + Mintage int + Reference string } +type MintageType int + /* DO NOT REORDER! */ const ( - TypeCirc = iota + TypeCirc MintageType = iota TypeNifc TypeProof ) @@ -38,28 +64,119 @@ const ( const ndenoms = 8 -func GetMintages(country string) (MintageData, error) { - var zero MintageData +func NewMintageType(s string) MintageType { + switch s { + case "circ": + return TypeCirc + case "nifc": + return TypeNifc + case "proof": + return TypeProof + } + /* TODO: Handle this */ + panic("TODO") +} - srows, err := db.Query(`SELECT * FROM mintages_s WHERE country = ?`, country) +func GetMintages(country string, typ MintageType) (MintageData, error) { + var ( + zero MintageData + xs []MSRow + ys []MCRow + ) + + rs, err := db.Queryx(` + SELECT * FROM mintages_s + WHERE country = ? AND type = ? + ORDER BY year, mintmark, denomination + `, country, typ) if err != nil { return zero, err } - defer srows.Close() - xs, err := scanToStructs[MSRow](srows) - if err != nil { - return zero, err + + for rs.Next() { + var x msRowInternal + if err = rs.StructScan(&x); err != nil { + return zero, err + } + + loop: + msr := MSRow{ + Year: x.Year, + Mintmark: sqlOr(x.Mintmark, ""), + References: make([]string, 0, ndenoms), + } + for i := range msr.Mintages { + msr.Mintages[i] = MintageUnknown + } + msr.Mintages[denomToIdx(x.Denomination)] = + sqlOr(x.Mintage, MintageUnknown) + if x.Reference.Valid { + msr.References = append(msr.References, x.Reference.V) + } + + for rs.Next() { + var y msRowInternal + if err = rs.StructScan(&y); err != nil { + return zero, err + } + + if x.Year != y.Year || x.Mintmark != y.Mintmark { + x = y + xs = append(xs, msr) + goto loop + } + + msr.Mintages[denomToIdx(y.Denomination)] = + sqlOr(y.Mintage, MintageUnknown) + if y.Reference.Valid { + msr.References = append(msr.References, y.Reference.V) + } + } + + xs = append(xs, msr) } - crows, err := db.Query(`SELECT * FROM mintages_c WHERE country = ?`, country) - if err != nil { + if err = rs.Err(); err != nil { return zero, err } - defer crows.Close() - ys, err := scanToStructs[MCRow](crows) + + rs, err = db.Queryx(` + SELECT * FROM mintages_c + WHERE country = ? AND type = ? + ORDER BY year, mintmark, number + `, country, typ) if err != nil { return zero, err } - return MintageData{xs, ys}, nil + for rs.Next() { + var y mcRowInternal + if err = rs.StructScan(&y); err != nil { + return zero, err + } + ys = append(ys, MCRow{ + Year: y.Year, + Name: y.Name, + Number: y.Number, + Mintmark: sqlOr(y.Mintmark, ""), + Mintage: sqlOr(y.Mintage, MintageUnknown), + Reference: sqlOr(y.Reference, ""), + }) + } + + return MintageData{xs, ys}, rs.Err() +} + +func sqlOr[T any](v sql.Null[T], dflt T) T { + if v.Valid { + return v.V + } + return dflt +} + +func denomToIdx(d float64) int { + return slices.Index([]float64{ + 0.01, 0.02, 0.05, 0.10, + 0.20, 0.50, 1.00, 2.00, + }, d) } -- cgit v1.2.3