summaryrefslogtreecommitdiffhomepage
path: root/src/dbx/mintages.go
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2025-07-05 11:12:37 +0200
committerThomas Voss <mail@thomasvoss.com> 2025-07-05 11:12:37 +0200
commit66ac5c365191d7515f7f796e95a754f6882cda8e (patch)
tree99de370773a33d21a6f8bf13c72b842ec0e782a6 /src/dbx/mintages.go
parent5a12e3e229e112e6b316c9ee9f762e36f321271d (diff)
Code simplification
Diffstat (limited to 'src/dbx/mintages.go')
-rw-r--r--src/dbx/mintages.go167
1 files changed, 142 insertions, 25 deletions
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)
}