diff options
Diffstat (limited to 'src/dbx/mintages.go')
| -rw-r--r-- | src/dbx/mintages.go | 217 |
1 files changed, 182 insertions, 35 deletions
diff --git a/src/dbx/mintages.go b/src/dbx/mintages.go index 4a6d5d3..2223eff 100644 --- a/src/dbx/mintages.go +++ b/src/dbx/mintages.go @@ -1,65 +1,212 @@ package dbx -type MintageData struct { - Standard []MSRow - Commemorative []MCRow +import ( + "context" + "database/sql" + "slices" +) + +type CountryMintageData struct { + Standard []MSCountryRow + Commemorative []MCommemorative +} + +type YearMintageData struct { + Standard []MSYearRow + Commemorative []MCommemorative +} + +type msRow struct { + Country string + Type MintageType + Year int + Denomination float64 + 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"` +type MSCountryRow struct { + Year int + Mintmark sql.Null[string] + Mintages [ndenoms]sql.Null[int] + References [ndenoms]sql.Null[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"` +type MSYearRow struct { + Country string + Mintmark sql.Null[string] + Mintages [ndenoms]sql.Null[int] + References [ndenoms]sql.Null[string] } +type MCommemorative struct { + Country string + Type MintageType + Year int + Name string + Number int + Mintmark sql.Null[string] + Mintage sql.Null[int] + Reference sql.Null[string] +} + +type MintageType int + /* DO NOT REORDER! */ const ( - TypeCirc = iota + TypeCirc MintageType = iota TypeNifc TypeProof ) -/* DO NOT REORDER! */ -const ( - MintageUnknown = -iota - 1 - MintageInvalid -) - 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 + } + /* We can get here if the user sends a request manually, so just + fallback to this */ + return TypeCirc +} + +func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) { + var ( + zero YearMintageData + xs []MSYearRow + ys []MCommemorative + ) - srows, err := db.Query(`SELECT * FROM mintages_s WHERE country = ?`, country) + rs, err := db.QueryxContext(context.TODO(), ` + SELECT * FROM mintages_s + WHERE year = ? AND type = ? + ORDER BY country, mintmark, denomination + `, year, typ) if err != nil { return zero, err } - defer srows.Close() - xs, err := scanToStructs[MSRow](srows) - if err != nil { + + for rs.Next() { + var x msRow + if err = rs.StructScan(&x); err != nil { + return zero, err + } + + loop: + msr := MSYearRow{ + Country: x.Country, + Mintmark: x.Mintmark, + } + i := denomToIdx(x.Denomination) + msr.Mintages[i] = x.Mintage + msr.References[i] = x.Reference + + for rs.Next() { + var y msRow + if err = rs.StructScan(&y); err != nil { + return zero, err + } + + if x.Country != y.Country || x.Mintmark != y.Mintmark { + x = y + xs = append(xs, msr) + goto loop + } + + i = denomToIdx(y.Denomination) + msr.Mintages[i] = y.Mintage + msr.References[i] = y.Reference + } + + xs = append(xs, msr) + } + + if err = rs.Err(); err != nil { return zero, err } - crows, err := db.Query(`SELECT * FROM mintages_c WHERE country = ?`, country) + db.SelectContext(context.TODO(), &ys, ` + SELECT * FROM mintages_c + WHERE year = ? and type = ? + ORDER BY country, mintmark, number + `, year, typ) + + return YearMintageData{xs, ys}, nil +} + +func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData, error) { + var ( + zero CountryMintageData + xs []MSCountryRow + ys []MCommemorative + ) + + rs, err := db.QueryxContext(context.TODO(), ` + SELECT * FROM mintages_s + WHERE country = ? AND type = ? + ORDER BY year, mintmark, denomination + `, country, typ) if err != nil { return zero, err } - defer crows.Close() - ys, err := scanToStructs[MCRow](crows) - if err != nil { + + for rs.Next() { + var x msRow + if err = rs.StructScan(&x); err != nil { + return zero, err + } + + loop: + msr := MSCountryRow{ + Year: x.Year, + Mintmark: x.Mintmark, + } + i := denomToIdx(x.Denomination) + msr.Mintages[i] = x.Mintage + msr.References[i] = x.Reference + + for rs.Next() { + var y msRow + 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 + } + + i = denomToIdx(y.Denomination) + msr.Mintages[i] = y.Mintage + msr.References[i] = y.Reference + } + + xs = append(xs, msr) + } + + if err = rs.Err(); err != nil { return zero, err } - return MintageData{xs, ys}, nil + db.SelectContext(context.TODO(), &ys, ` + SELECT * FROM mintages_c + WHERE country = ? and type = ? + ORDER BY year, mintmark, number + `, country, typ) + + return CountryMintageData{xs, ys}, rs.Err() +} + +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) } |