aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2025-08-07 13:35:49 +0200
committerThomas Voss <mail@thomasvoss.com> 2025-08-07 13:35:49 +0200
commit46a4e630a46fd7a57631cfb08bc01da250814336 (patch)
tree450f0db2416b46b8cad395e17cad20dbdf3debc6 /src
parentcca182b4202a31c4fa281a40dfb6ce7f56cdcd2a (diff)
Simplify mintages code
Diffstat (limited to 'src')
-rw-r--r--src/dbx/mintages.go178
-rw-r--r--src/http.go10
-rw-r--r--src/templates/coins-mintages.html.tmpl52
3 files changed, 79 insertions, 161 deletions
diff --git a/src/dbx/mintages.go b/src/dbx/mintages.go
index 9b98bd6..c612a92 100644
--- a/src/dbx/mintages.go
+++ b/src/dbx/mintages.go
@@ -1,21 +1,22 @@
package dbx
import (
+ "context"
"database/sql"
"slices"
)
type CountryMintageData struct {
Standard []MSCountryRow
- Commemorative []MCCountryRow
+ Commemorative []MCommemorative
}
type YearMintageData struct {
Standard []MSYearRow
- Commemorative []MCYearRow
+ Commemorative []MCommemorative
}
-type msRowInternal struct {
+type msRow struct {
Country string
Type MintageType
Year int
@@ -25,47 +26,29 @@ type msRowInternal struct {
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 MSCountryRow struct {
Year int
- Mintmark string
- Mintages [ndenoms]int
- References []string
-}
-
-type MCCountryRow struct {
- Year int
- Name string
- Number int
- Mintmark string
- Mintage int
- Reference string
+ Mintmark sql.Null[string]
+ Mintages [ndenoms]sql.Null[int]
+ References [ndenoms]sql.Null[string]
}
type MSYearRow struct {
Country string
- Mintmark string
- Mintages [ndenoms]int
- References []string
+ Mintmark sql.Null[string]
+ Mintages [ndenoms]sql.Null[int]
+ References [ndenoms]sql.Null[string]
}
-type MCYearRow struct {
- Country string
- Name string
+type MCommemorative struct {
+ Country string
+ Type MintageType
+ Year int
+ Name string
Number int
- Mintmark string
- Mintage int
- Reference string
+ Mintmark sql.Null[string]
+ Mintage sql.Null[int]
+ Reference sql.Null[string]
}
type MintageType int
@@ -77,12 +60,6 @@ const (
TypeProof
)
-/* DO NOT REORDER! */
-const (
- MintageUnknown = -iota - 1
- MintageInvalid
-)
-
const ndenoms = 8
func NewMintageType(s string) MintageType {
@@ -103,10 +80,10 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) {
var (
zero YearMintageData
xs []MSYearRow
- ys []MCYearRow
+ ys []MCommemorative
)
- rs, err := db.Queryx(`
+ rs, err := db.QueryxContext(context.TODO(), `
SELECT * FROM mintages_s
WHERE year = ? AND type = ?
ORDER BY country, mintmark, denomination
@@ -116,7 +93,7 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) {
}
for rs.Next() {
- var x msRowInternal
+ var x msRow
if err = rs.StructScan(&x); err != nil {
return zero, err
}
@@ -124,20 +101,14 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) {
loop:
msr := MSYearRow{
Country: x.Country,
- 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)
+ Mintmark: x.Mintmark,
}
+ i := denomToIdx(x.Denomination)
+ msr.Mintages[i] = x.Mintage
+ msr.References[i] = x.Reference
for rs.Next() {
- var y msRowInternal
+ var y msRow
if err = rs.StructScan(&y); err != nil {
return zero, err
}
@@ -148,11 +119,9 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) {
goto loop
}
- msr.Mintages[denomToIdx(y.Denomination)] =
- sqlOr(y.Mintage, MintageUnknown)
- if y.Reference.Valid {
- msr.References = append(msr.References, y.Reference.V)
- }
+ i = denomToIdx(y.Denomination)
+ msr.Mintages[i] = y.Mintage
+ msr.References[i] = y.Reference
}
xs = append(xs, msr)
@@ -162,29 +131,11 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) {
return zero, err
}
- rs, err = db.Queryx(`
- SELECT * FROM mintages_c
- WHERE year = ? AND type = ?
- ORDER BY country, mintmark, number
+ db.SelectContext(context.TODO(), &ys, `
+ SELECT * FROM mintages_c
+ WHERE year = ? and type = ?
+ ORDER BY country, mintmark, number
`, year, typ)
- if err != nil {
- return zero, err
- }
-
- for rs.Next() {
- var y mcRowInternal
- if err = rs.StructScan(&y); err != nil {
- return zero, err
- }
- ys = append(ys, MCYearRow{
- Country: y.Country,
- Name: y.Name,
- Number: y.Number,
- Mintmark: sqlOr(y.Mintmark, ""),
- Mintage: sqlOr(y.Mintage, MintageUnknown),
- Reference: sqlOr(y.Reference, ""),
- })
- }
return YearMintageData{xs, ys}, nil
}
@@ -193,10 +144,10 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData,
var (
zero CountryMintageData
xs []MSCountryRow
- ys []MCCountryRow
+ ys []MCommemorative
)
- rs, err := db.Queryx(`
+ rs, err := db.QueryxContext(context.TODO(), `
SELECT * FROM mintages_s
WHERE country = ? AND type = ?
ORDER BY year, mintmark, denomination
@@ -206,7 +157,7 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData,
}
for rs.Next() {
- var x msRowInternal
+ var x msRow
if err = rs.StructScan(&x); err != nil {
return zero, err
}
@@ -214,20 +165,14 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData,
loop:
msr := MSCountryRow{
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)
+ Mintmark: x.Mintmark,
}
+ i := denomToIdx(x.Denomination)
+ msr.Mintages[i] = x.Mintage
+ msr.References[i] = x.Reference
for rs.Next() {
- var y msRowInternal
+ var y msRow
if err = rs.StructScan(&y); err != nil {
return zero, err
}
@@ -238,11 +183,9 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData,
goto loop
}
- msr.Mintages[denomToIdx(y.Denomination)] =
- sqlOr(y.Mintage, MintageUnknown)
- if y.Reference.Valid {
- msr.References = append(msr.References, y.Reference.V)
- }
+ i = denomToIdx(y.Denomination)
+ msr.Mintages[i] = y.Mintage
+ msr.References[i] = y.Reference
}
xs = append(xs, msr)
@@ -252,40 +195,15 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData,
return zero, err
}
- rs, err = db.Queryx(`
- SELECT * FROM mintages_c
- WHERE country = ? AND type = ?
- ORDER BY year, mintmark, number
+ db.SelectContext(context.TODO(), &ys, `
+ SELECT * FROM mintages_c
+ WHERE country = ? and type = ?
+ ORDER BY year, mintmark, number
`, country, typ)
- if err != nil {
- return zero, err
- }
-
- for rs.Next() {
- var y mcRowInternal
- if err = rs.StructScan(&y); err != nil {
- return zero, err
- }
- ys = append(ys, MCCountryRow{
- Year: y.Year,
- Name: y.Name,
- Number: y.Number,
- Mintmark: sqlOr(y.Mintmark, ""),
- Mintage: sqlOr(y.Mintage, MintageUnknown),
- Reference: sqlOr(y.Reference, ""),
- })
- }
return CountryMintageData{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,
diff --git a/src/http.go b/src/http.go
index 071b25c..241ddcc 100644
--- a/src/http.go
+++ b/src/http.go
@@ -13,9 +13,9 @@ import (
"strings"
"time"
+ . "git.thomasvoss.com/euro-cash.eu/pkg/try"
"golang.org/x/text/collate"
"golang.org/x/text/language"
- . "git.thomasvoss.com/euro-cash.eu/pkg/try"
"git.thomasvoss.com/euro-cash.eu/src/dbx"
"git.thomasvoss.com/euro-cash.eu/src/email"
@@ -169,7 +169,7 @@ func mintageHandler(next http.Handler) http.Handler {
td.CountryMintages, err = dbx.GetMintagesByCountry(td.Code, mt)
case "year":
td.Year, err = strconv.Atoi(r.FormValue("year"))
- if err != nil {
+ if err != nil || td.Year < 1999 {
td.Year = 1999
}
td.YearMintages, err = dbx.GetMintagesByYear(td.Year, mt)
@@ -190,14 +190,14 @@ func mintageHandler(next http.Handler) http.Handler {
slices.SortFunc(td.YearMintages.Standard, func(x, y dbx.MSYearRow) int {
Δ := c.CompareString(x.Country, y.Country)
if Δ == 0 {
- Δ = c.CompareString(x.Mintmark, y.Mintmark)
+ Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V)
}
return Δ
})
- slices.SortFunc(td.YearMintages.Commemorative, func(x, y dbx.MCYearRow) int {
+ slices.SortFunc(td.YearMintages.Commemorative, func(x, y dbx.MCommemorative) int {
Δ := c.CompareString(x.Country, y.Country)
if Δ == 0 {
- Δ = c.CompareString(x.Mintmark, y.Mintmark)
+ Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V)
}
return Δ
})
diff --git a/src/templates/coins-mintages.html.tmpl b/src/templates/coins-mintages.html.tmpl
index 7c041f3..6a8a744 100644
--- a/src/templates/coins-mintages.html.tmpl
+++ b/src/templates/coins-mintages.html.tmpl
@@ -99,11 +99,12 @@
</div>
<button type="submit">{{ .GetC "Filter" "Header/Label" }}</button>
</form>
+
+ {{ if and (eq .FilterBy "country")
+ (gt (len .CountryMintages.Standard) 0) }}
<figure>
<figcaption>{{ .Get "Standard Issue Coins" }}</figcaption>
<div class="overflow-auto">
- {{ if eq .FilterBy "country" }}
-
<table class="mintage-table striped" role="grid">
<thead>
<th>{{ .GetC "Year" "Header/Label" }}</th>
@@ -122,8 +123,8 @@
<tr>
<th scope="row">
{{- .Year -}}
- {{- if ne .Mintmark "" -}}
- &nbsp;<sub><small>{{ .Mintmark }}</small></sub>
+ {{- if .Mintmark.Valid -}}
+ &nbsp;<sub><small>{{ .Mintmark.V }}</small></sub>
{{- end -}}
</th>
{{ range .Mintages }}
@@ -133,9 +134,15 @@
{{ end }}
</tbody>
</table>
+ </div>
+ </figure>
- {{ else if eq .FilterBy "year" }}
+ {{ else if and (eq .FilterBy "year")
+ (gt (len .YearMintages.Standard) 0) }}
+ <figure>
+ <figcaption>{{ .Get "Standard Issue Coins" }}</figcaption>
+ <div class="overflow-auto">
<table class="mintage-table striped" role="grid">
<thead>
<th>{{ .GetC "Country" "Header/Label" }}</th>
@@ -154,8 +161,8 @@
<tr>
<th scope="row">
{{- .Country -}}
- {{- if ne .Mintmark "" -}}
- &nbsp;<sub><small>{{ .Mintmark }}</small></sub>
+ {{- if .Mintmark.Valid -}}
+ &nbsp;<sub><small>{{ .Mintmark.V }}</small></sub>
{{- end -}}
</th>
{{ range .Mintages }}
@@ -165,9 +172,9 @@
{{ end }}
</tbody>
</table>
- {{ end }}
</div>
</figure>
+ {{ end }}
{{ if eq .FilterBy "country" }}
{{ if ne (len .CountryMintages.Commemorative) 0 }}
@@ -185,15 +192,12 @@
<tr>
<th scope="row">
{{- .Year -}}
- {{- if ne .Mintmark "" -}}
- &nbsp;<sub><small>{{ .Mintmark }}</small></sub>
+ {{- if .Mintmark.Valid -}}
+ &nbsp;<sub><small>{{ .Mintmark.V }}</small></sub>
{{- end -}}
</th>
- <!-- TODO: Translate commemorative names -->
- <td>{{ .Name }}</td>
- {{ with .Mintage }}
- {{ template "mintages/mintage-cell" (tuple . $p) }}
- {{ end }}
+ <td>{{ $p.GetC .Name "CC Name" }}</td>
+ {{ template "mintages/mintage-cell" (tuple .Mintage $p) }}
</tr>
{{ end }}
</tbody>
@@ -218,15 +222,13 @@
<tr>
<th scope="row">
{{- .Country -}}
- {{- if ne .Mintmark "" -}}
- &nbsp;<sub><small>{{ .Mintmark }}</small></sub>
+ {{- if .Mintmark.Valid -}}
+ &nbsp;<sub><small>{{ .Mintmark.V }}</small></sub>
{{- end -}}
</th>
<!-- TODO: Translate commemorative names -->
<td>{{ .Name }}</td>
- {{ with .Mintage }}
- {{ template "mintages/mintage-cell" (tuple . $p) }}
- {{ end }}
+ {{ template "mintages/mintage-cell" (tuple .Mintage $p) }}
</tr>
{{ end }}
</tbody>
@@ -271,13 +273,11 @@
{{ define "mintages/mintage-cell" }}
{{ $v := index . 0 }}
{{ $p := index . 1 }}
-{{ if eq $v -1 }}
+{{ if not $v.Valid }}
<td data-numeric>{{ $p.Get "Unknown" }}</td>
-{{ else if eq $v -2 }}
- <td data-numeric class="error">{{ $p.Get "Error" }}</td>
-{{ else if eq $v 0 }}
+{{ else if eq $v.V 0 }}
<td data-numeric>—</td>
{{ else }}
- <td data-numeric>{{ $p.Itoa $v }}</td>
-{{ end }}
+ <td data-numeric>{{ $p.Itoa $v.V }}</td>
{{ end }}
+{{ end }} \ No newline at end of file