diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..6116ef778 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,44 @@ +name: 'test backend' +on: + push: + paths: ['**.go', 'go.mod', '.github/workflows/*'] + pr: + paths: ['**.go', 'go.mod', '.github/workflows/*'] + +jobs: + # Uncomment to get a debug shell. + # debug: {runs-on: 'ubuntu-latest', steps: [{uses: 'actions/checkout@v4'}, {uses: 'mxschmitt/action-tmate@v3'}]} + + test: + name: 'test (linux)' + runs-on: 'ubuntu-latest' + steps: + - uses: 'actions/checkout@v4' + - name: 'test (linux)' + run: | + # Quick exit on compile errors. + go build -race ./cmd/goatcounter || exit 1 + + # Make sure it at least compiles on macOS, Windows, and arm64 + GOARCH=arm64 go build ./cmd/goatcounter + GOARCH=arm64 GOOS=darwin go build ./cmd/goatcounter + GOOS=windows go build ./cmd/goatcounter + + go test -race -timeout=3m ./... + + docker compose up -d --wait + export PGHOST=localhost + export PGPORT=5433 + export PGDATABASE=goatcounter + export PGUSER=goatcounter + export PGPASSWORD=goatcounter + export PGSSLMODE=disable + go test -race -timeout=3m -tags pgsql ./... + + staticcheck: + name: 'staticcheck' + runs-on: 'ubuntu-latest' + steps: + - uses: 'actions/checkout@v4' + - uses: 'dominikh/staticcheck-action@v1.3.1' + with: {version: '2024.1'} diff --git a/acme/acme_test.go b/acme/acme_test.go index b2eb72b64..41f8d4cfe 100644 --- a/acme/acme_test.go +++ b/acme/acme_test.go @@ -50,7 +50,7 @@ func TestSetup(t *testing.T) { haveACME := acmeH != nil if tlsC != nil { - t.Logf(zruntime.FuncName(tlsC.GetCertificate)) + t.Log(zruntime.FuncName(tlsC.GetCertificate)) } if haveTLS != tt.wantTLS { t.Errorf("have TLS %t; want %t", haveTLS, tt.wantTLS) diff --git a/api_token.go b/api_token.go index ff826e384..843236f3e 100644 --- a/api_token.go +++ b/api_token.go @@ -153,7 +153,7 @@ func (t *APIToken) Insert(ctx context.Context) error { t.ID, err = zdb.InsertID(ctx, "api_token_id", `insert into api_tokens (site_id, user_id, name, token, permissions, created_at) values (?)`, - zdb.L{t.SiteID, GetUser(ctx).ID, t.Name, t.Token, t.Permissions, t.CreatedAt}) + []any{t.SiteID, GetUser(ctx).ID, t.Name, t.Token, t.Permissions, t.CreatedAt}) return errors.Wrap(err, "APIToken.Insert") } @@ -226,7 +226,7 @@ func (t *APITokens) Find(ctx context.Context, ident []string) error { {{:ids api_token_id in (:ids) or}} {{:strs! 0=1}} {{:strs token in (:strs)}}`, - zdb.P{"ids": ids, "strs": strs}) + map[string]any{"ids": ids, "strs": strs}) return errors.Wrap(err, "APITokens.Find") } diff --git a/cmd/goatcounter/old.go b/cmd/goatcounter/old.go deleted file mode 100644 index 83c39e0b5..000000000 --- a/cmd/goatcounter/old.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright © Martin Tournoij – This file is part of GoatCounter and published -// under the terms of a slightly modified EUPL v1.2 license, which can be found -// in the LICENSE file or at https://license.goatcounter.com - -//go:build !go1.18 -// +build !go1.18 - -package main - -// Make sure people don't try to build GoatCounter with older versions of Go, as -// that will introduce some runtime problems (e.g. using %w). -func init() { - "You need Go 1.18 or newer to compile GoatCounter" -} diff --git a/cmd/goatcounter/pg_test.go b/cmd/goatcounter/pg_test.go index 702673e6b..8b5a6d91b 100644 --- a/cmd/goatcounter/pg_test.go +++ b/cmd/goatcounter/pg_test.go @@ -3,7 +3,6 @@ // in the LICENSE file or at https://license.goatcounter.com //go:build testpg -// +build testpg package main diff --git a/cmd/goatcounter/serve.go b/cmd/goatcounter/serve.go index eaa2dd1ee..92ec7360d 100644 --- a/cmd/goatcounter/serve.go +++ b/cmd/goatcounter/serve.go @@ -500,7 +500,7 @@ func flagErrors(errors string, v *zvalidate.Validator) { subject = subject[i+7:] } - err := blackmail.Send(fmt.Sprintf(subject), + err := blackmail.Send(subject, blackmail.From("", from), blackmail.To(to), blackmail.BodyText([]byte(msg))) diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 000000000..4a653d567 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,14 @@ +name: 'goatcounter' + +volumes: + postgres-data: {} + +services: + postgres: + image: 'postgres:16-alpine' + ports: ['127.0.0.1:5433:5432'] # 5433 instead of default 5432 + volumes: ['postgres-data:/var/lib/postgresql/data'] + environment: + 'POSTGRES_USER': 'goatcounter' + 'POSTGRES_PASSWORD': 'goatcounter' + 'POSTGRES_DATABASE': 'goatcounter' diff --git a/gctest/pg.go b/gctest/pg.go index f87678da6..b408f6b8e 100644 --- a/gctest/pg.go +++ b/gctest/pg.go @@ -3,7 +3,6 @@ // in the LICENSE file or at https://license.goatcounter.com //go:build testpg -// +build testpg package gctest diff --git a/gen.go b/gen.go index 3f8e8689c..a0b4770a9 100644 --- a/gen.go +++ b/gen.go @@ -3,7 +3,6 @@ // in the LICENSE file or at https://license.goatcounter.com //go:build go_run_only -// +build go_run_only package main diff --git a/handlers/api_test.go b/handlers/api_test.go index b594e68f6..837639574 100644 --- a/handlers/api_test.go +++ b/handlers/api_test.go @@ -433,7 +433,7 @@ func TestAPICount(t *testing.T) { } if d := ztest.Diff(have, tt.want); d != "" { - t.Errorf(d) + t.Error(d) } }) } diff --git a/handlers/user.go b/handlers/user.go index 259620619..cd94a12d3 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -170,7 +170,7 @@ func (h user) requestLogin(w http.ResponseWriter, r *http.Request) error { return err } - if user.Password == nil || len(user.Password) == 0 { + if len(user.Password) == 0 { zhttp.FlashError(w, T(r.Context(), "error/login-no-password|There is no password set for %(email); please reset it", args.Email)) return zhttp.SeeOther(w, "/user/forgot?email="+url.QueryEscape(args.Email)) } diff --git a/helper.go b/helper.go index 5ee1a37f5..8d847ddd2 100644 --- a/helper.go +++ b/helper.go @@ -110,7 +110,7 @@ func NewBufferKey(ctx context.Context) (string, error) { return err } - err = zdb.Exec(ctx, `insert into store (key, value) values ('buffer-secret', :s)`, zdb.P{"s": secret}) + err = zdb.Exec(ctx, `insert into store (key, value) values ('buffer-secret', :s)`, map[string]any{"s": secret}) return err }) if err != nil { diff --git a/helper_cgo.go b/helper_cgo.go index ddac62d33..a76ba62ed 100644 --- a/helper_cgo.go +++ b/helper_cgo.go @@ -3,7 +3,6 @@ // in the LICENSE file or at https://license.goatcounter.com //go:build cgo -// +build cgo package goatcounter diff --git a/hit.go b/hit.go index 5c450ed37..ccc0eb5e8 100644 --- a/hit.go +++ b/hit.go @@ -365,7 +365,7 @@ func (h *Hits) TestList(ctx context.Context, siteOnly bool) error { left join sizes using (size_id) {{:site_only where hits.site_id = :site}} order by hit_id asc`, - zdb.P{ + map[string]any{ "site": MustGetSite(ctx).ID, "site_only": siteOnly, }) diff --git a/hit_list.go b/hit_list.go index 9d260f496..d94df2acd 100644 --- a/hit_list.go +++ b/hit_list.go @@ -58,7 +58,7 @@ type HitListStat struct { // PathCount gets the visit count for one path. func (h *HitList) PathCount(ctx context.Context, path string, rng ztime.Range) error { - err := zdb.Get(ctx, h, "load:hit_list.PathCount", zdb.P{ + err := zdb.Get(ctx, h, "load:hit_list.PathCount", map[string]any{ "site": MustGetSite(ctx).ID, "path": path, "start": rng.Start, @@ -76,7 +76,7 @@ func (h *HitList) SiteTotalUTC(ctx context.Context, rng ztime.Range) error { where site_id = :site {{:start and hour >= :start}} {{:end and hour <= :end}} - `, zdb.P{ + `, map[string]any{ "site": MustGetSite(ctx).ID, "start": rng.Start, "end": rng.End, @@ -88,7 +88,7 @@ type HitLists []HitList // ListPathsLike lists all paths matching the like pattern. func (h *HitLists) ListPathsLike(ctx context.Context, search string, matchTitle, matchCase bool) error { - err := zdb.Select(ctx, h, "load:hit_list.ListPathsLike", zdb.P{ + err := zdb.Select(ctx, h, "load:hit_list.ListPathsLike", map[string]any{ "site": MustGetSite(ctx).ID, "search": search, "match_title": matchTitle, @@ -109,7 +109,7 @@ func (h *HitLists) List( // List the pages for this time period; this gets the path_id, path, title. var more bool { - err := zdb.Select(ctx, h, "load:hit_list.List-counts", zdb.P{ + err := zdb.Select(ctx, h, "load:hit_list.List-counts", map[string]any{ "site": site.ID, "start": rng.Start, "end": rng.End, @@ -147,7 +147,7 @@ func (h *HitLists) List( paths[i] = hh[i].PathID } - err := zdb.Select(ctx, &st, "load:hit_list.List-stats", zdb.P{ + err := zdb.Select(ctx, &st, "load:hit_list.List-stats", map[string]any{ "site": site.ID, "start": rng.Start.Format("2006-01-02"), "end": rng.End.Format("2006-01-02"), @@ -198,7 +198,7 @@ func (h *HitList) Totals(ctx context.Context, rng ztime.Range, pathFilter []int6 Hour time.Time `db:"hour"` Total int `db:"total"` } - err := zdb.Select(ctx, &tc, "load:hit_list.Totals", zdb.P{ + err := zdb.Select(ctx, &tc, "load:hit_list.Totals", map[string]any{ "site": site.ID, "start": rng.Start, "end": rng.End, @@ -429,7 +429,7 @@ func GetTotalCount(ctx context.Context, rng ztime.Range, pathFilter []int64, noE user := MustGetUser(ctx) var t TotalCount - err := zdb.Get(ctx, &t, "load:hit_list.GetTotalCount", zdb.P{ + err := zdb.Get(ctx, &t, "load:hit_list.GetTotalCount", map[string]any{ "site": site.ID, "start": rng.Start, "end": rng.End, @@ -462,7 +462,7 @@ func (h HitLists) Diff(ctx context.Context, rng, prev ztime.Range) ([]float64, e } var diffs []float64 - err := zdb.Select(ctx, &diffs, "load:hit_list.DiffTotal", zdb.P{ + err := zdb.Select(ctx, &diffs, "load:hit_list.DiffTotal", map[string]any{ "site": MustGetSite(ctx).ID, "start": rng.Start, "end": rng.End, diff --git a/hit_stats.go b/hit_stats.go index a302e603b..b0eee5959 100644 --- a/hit_stats.go +++ b/hit_stats.go @@ -47,7 +47,7 @@ func asUTCDate(u *User, t time.Time) string { // total number of hits. func (h *HitStats) ListTopRefs(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { site := MustGetSite(ctx) - err := zdb.Select(ctx, &h.Stats, "load:ref.ListTopRefs.sql", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:ref.ListTopRefs.sql", map[string]any{ "site": site.ID, "start": rng.Start, "end": rng.End, @@ -71,7 +71,7 @@ func (h *HitStats) ListTopRefs(ctx context.Context, rng ztime.Range, pathFilter // ListTopRef lists all paths by referrer. func (h *HitStats) ListTopRef(ctx context.Context, ref string, rng ztime.Range, pathFilter []int64, limit, offset int) error { - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ByRef", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ByRef", map[string]any{ "site": MustGetSite(ctx).ID, "start": rng.Start, "end": rng.End, @@ -90,7 +90,7 @@ func (h *HitStats) ListTopRef(ctx context.Context, ref string, rng ztime.Range, // ListBrowsers lists all browser statistics for the given time period. func (h *HitStats) ListBrowsers(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListBrowsers", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListBrowsers", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -108,7 +108,7 @@ func (h *HitStats) ListBrowsers(ctx context.Context, rng ztime.Range, pathFilter // ListBrowser lists all the versions for one browser. func (h *HitStats) ListBrowser(ctx context.Context, browser string, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListBrowser", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListBrowser", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -127,7 +127,7 @@ func (h *HitStats) ListBrowser(ctx context.Context, browser string, rng ztime.Ra // ListSystems lists OS statistics for the given time period. func (h *HitStats) ListSystems(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSystems", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSystems", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -145,7 +145,7 @@ func (h *HitStats) ListSystems(ctx context.Context, rng ztime.Range, pathFilter // ListSystem lists all the versions for one system. func (h *HitStats) ListSystem(ctx context.Context, system string, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSystem", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSystem", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -173,7 +173,7 @@ const ( // ListSizes lists all device sizes. func (h *HitStats) ListSizes(ctx context.Context, rng ztime.Range, pathFilter []int64) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSizes", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSizes", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -238,7 +238,7 @@ func (h *HitStats) ListSize(ctx context.Context, id string, rng ztime.Range, pat } user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSize", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListSize", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -265,7 +265,7 @@ func (h *HitStats) ListSize(ctx context.Context, id string, rng ztime.Range, pat // ListLocations lists all location statistics for the given time period. func (h *HitStats) ListLocations(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLocations", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLocations", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -283,7 +283,7 @@ func (h *HitStats) ListLocations(ctx context.Context, rng ztime.Range, pathFilte // ListLocation lists all divisions for a location func (h *HitStats) ListLocation(ctx context.Context, country string, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLocation", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLocation", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -302,7 +302,7 @@ func (h *HitStats) ListLocation(ctx context.Context, country string, rng ztime.R // ListLanguages lists all language statistics for the given time period. func (h *HitStats) ListLanguages(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLanguages", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListLanguages", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -320,7 +320,7 @@ func (h *HitStats) ListLanguages(ctx context.Context, rng ztime.Range, pathFilte // ListCampaigns lists all campaigns statistics for the given time period. func (h *HitStats) ListCampaigns(ctx context.Context, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListCampaigns", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListCampaigns", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), @@ -338,7 +338,7 @@ func (h *HitStats) ListCampaigns(ctx context.Context, rng ztime.Range, pathFilte // ListCampaign lists all statistics for a campaign. func (h *HitStats) ListCampaign(ctx context.Context, campaign int64, rng ztime.Range, pathFilter []int64, limit, offset int) error { user := MustGetUser(ctx) - err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListCampaign", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:hit_stats.ListCampaign", map[string]any{ "site": MustGetSite(ctx).ID, "start": asUTCDate(user, rng.Start), "end": asUTCDate(user, rng.End), diff --git a/memstore.go b/memstore.go index dcbbcd634..8ecda2e62 100644 --- a/memstore.go +++ b/memstore.go @@ -306,7 +306,7 @@ func (m *ms) processHit(ctx context.Context, h *Hit) bool { return true } -// Maximum length of sessions; exported here for tests. +// SessionTime is the maximum length of sessions; exported here for tests. var SessionTime = 8 * time.Hour // For 10k sessions this takes about 5ms on my laptop; that's a small enough diff --git a/path.go b/path.go index a49f27aa3..e7020b177 100644 --- a/path.go +++ b/path.go @@ -141,7 +141,7 @@ type Paths []Path // List all paths for a site. func (p *Paths) List(ctx context.Context, siteID, after int64, limit int) (bool, error) { - err := zdb.Select(ctx, p, "load:paths.List", zdb.P{ + err := zdb.Select(ctx, p, "load:paths.List", map[string]any{ "site": siteID, "after": after, "limit": limit + 1, @@ -164,7 +164,7 @@ func (p *Paths) List(ctx context.Context, siteID, after int64, limit int) (bool, // if matchTitle is true it will match the title as well. func PathFilter(ctx context.Context, filter string, matchTitle bool) ([]int64, error) { var paths []int64 - err := zdb.Select(ctx, &paths, "load:paths.PathFilter", zdb.P{ + err := zdb.Select(ctx, &paths, "load:paths.PathFilter", map[string]any{ "site": MustGetSite(ctx).ID, "filter": "%" + filter + "%", "match_title": matchTitle, diff --git a/ref.go b/ref.go index 860ad7da3..0227c49fa 100644 --- a/ref.go +++ b/ref.go @@ -257,7 +257,7 @@ func cleanRefURL(ref string, refURL *url.URL) (string, bool) { // ListRefsByPath lists all references for a pathID. func (h *HitStats) ListRefsByPathID(ctx context.Context, pathID int64, rng ztime.Range, limit, offset int) error { - err := zdb.Select(ctx, &h.Stats, "load:ref.ListRefsByPathID.sql", zdb.P{ + err := zdb.Select(ctx, &h.Stats, "load:ref.ListRefsByPathID.sql", map[string]any{ "site": MustGetSite(ctx).ID, "start": rng.Start, "end": rng.End, diff --git a/run-ci b/run-ci deleted file mode 100755 index cadbb5b24..000000000 --- a/run-ci +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# mick-image: go - -e=0 -set -x - -go run ./cmd/check ./... || e=1 -go test -race -timeout=3m ./... || e=1 -go test -race -timeout=3m -tags pgsql ./... || e=1 - -# Make sure it at least compiles on macOS, Windows, and arm64 -trap 'rm goatcounter goatcounter.exe' EXIT -GOOS=darwin go build ./cmd/goatcounter || e=1 -GOOS=windows go build ./cmd/goatcounter || e=1 -GOARCH=arm64 go build ./cmd/goatcounter || e=1 - -exit $e diff --git a/site.go b/site.go index 003c7dce6..34d7cb9c4 100644 --- a/site.go +++ b/site.go @@ -187,7 +187,7 @@ func (s *Site) Insert(ctx context.Context) error { s.ID, err = zdb.InsertID(ctx, "site_id", `insert into sites ( parent, code, cname, link_domain, settings, user_defaults, created_at, first_hit_at, cname_setup_at) values (?)`, - zdb.L{s.Parent, s.Code, s.Cname, s.LinkDomain, s.Settings, s.UserDefaults, s.CreatedAt, s.CreatedAt, s.CnameSetupAt}) + []any{s.Parent, s.Code, s.Cname, s.LinkDomain, s.Settings, s.UserDefaults, s.CreatedAt, s.CreatedAt, s.CnameSetupAt}) if err != nil && zdb.ErrUnique(err) { return guru.New(400, "this site already exists: code or domain must be unique") } @@ -394,11 +394,11 @@ func (s Site) Exists(ctx context.Context) (int64, error) { var ( id int64 query = `select site_id from sites where lower(code) = lower($1) and site_id != $2 limit 1` - params = zdb.L{s.Code, s.ID} + params = []any{s.Code, s.ID} ) if s.Cname != nil { query = `select site_id from sites where lower(cname) = lower($1) and site_id != $2 limit 1` - params = zdb.L{s.Cname, s.ID} + params = []any{s.Cname, s.ID} } err := zdb.Get(ctx, &id, query, params...) @@ -562,7 +562,7 @@ func (s Site) IDOrParent() int64 { func (s Site) DeleteAll(ctx context.Context) error { return zdb.TX(ctx, func(ctx context.Context) error { for _, t := range append(statTables, "campaign_stats", "hit_counts", "ref_counts", "hits", "paths") { - err := zdb.Exec(ctx, `delete from `+t+` where site_id=:id`, zdb.P{"id": s.ID}) + err := zdb.Exec(ctx, `delete from `+t+` where site_id=:id`, map[string]any{"id": s.ID}) if err != nil { return errors.Wrap(err, "Site.DeleteAll: delete "+t) } @@ -706,7 +706,7 @@ func (s *Sites) Find(ctx context.Context, ident []string) error { {{:ids site_id in (:ids) or}} {{:strs! 0=1}} {{:strs cname in (:strs)}}`, - zdb.P{"ids": ids, "strs": strs}) + map[string]any{"ids": ids, "strs": strs}) return errors.Wrap(err, "Sites.Find") } diff --git a/staticcheck.conf b/staticcheck.conf new file mode 100644 index 000000000..ddc0ba237 --- /dev/null +++ b/staticcheck.conf @@ -0,0 +1 @@ +checks = ['all', '-ST1000', '-ST1003', '-ST1020', '-ST1021', '-SA9003', '-U1000', '-SA5008'] diff --git a/user.go b/user.go index 72c57dbf3..e209b6c2f 100644 --- a/user.go +++ b/user.go @@ -153,7 +153,7 @@ func (u *User) Insert(ctx context.Context, allowBlankPassword bool) error { } query := `insert into users ` - args := zdb.L{u.Site, u.Email, u.Password, u.TOTPSecret, u.Settings, u.Access, u.CreatedAt, u.LastReportAt} + args := []any{u.Site, u.Email, u.Password, u.TOTPSecret, u.Settings, u.Access, u.CreatedAt, u.LastReportAt} if u.EmailVerified { query += ` (site_id, email, password, totp_secret, settings, access, created_at, last_report_at, email_verified) values (?)` args = append(args, 1) @@ -585,7 +585,7 @@ func (u *Users) Find(ctx context.Context, ident []string) error { {{:ids user_id in (:ids) or}} {{:strs! 0=1}} {{:strs email in (:strs)}}`, - zdb.P{"ids": ids, "strs": strs}) + map[string]any{"ids": ids, "strs": strs}) return errors.Wrap(err, "Users.Find") } diff --git a/user_agent_test.go b/user_agent_test.go index 05c0e80dc..ec035312d 100644 --- a/user_agent_test.go +++ b/user_agent_test.go @@ -31,7 +31,7 @@ func TestUserAgentGetOrInsert(t *testing.T) { zdb.DumpString(ctx, `select systems.name || ' ' || systems.version as system from systems;`) out = strings.ReplaceAll(out, " \n", "\n") // TODO: fix in zdb if d := ztest.Diff(out, want); d != "" { - t.Errorf(d) + t.Error(d) } }