From 17e044dee27451fabe9f0bb9570f01104f3c1390 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 16 Aug 2023 17:05:40 +0200 Subject: [PATCH] QueryData: keep both variants of scan method: call by value, call by reference (pointer) --- storage/sql/sql.go | 31 ++++++++++++++++++++++--------- tests/storage_test.go | 13 +++++++++++-- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/storage/sql/sql.go b/storage/sql/sql.go index 45f5b86..6c797e0 100644 --- a/storage/sql/sql.go +++ b/storage/sql/sql.go @@ -10,17 +10,18 @@ type Cfg struct { Driver, Connstr string } +type Storage struct { + *sql.DB +} + type Rows = sql.Rows type rowsProc = func(*sql.Rows) error -type scanner interface{ Scan(*Rows) error } -type sccon[T any] interface { +type scn[T any] interface{ Scan(*Rows) (T, error) } +type scp interface{ ScanP(*Rows) error } +type scpcon[T any] interface { *T - scanner -} - -type Storage struct { - *sql.DB + scp } func Open(cfg *Cfg) *Storage { @@ -32,11 +33,23 @@ func Open(cfg *Cfg) *Storage { return &Storage{db} } -func QueryData[P sccon[T], T any](db *Storage, q string, args ...interface{}) []T { +func QueryData[T scn[T]](db *Storage, q string, args ...interface{}) []T { + var data []T + var rec T + proc := func(r *sql.Rows) error { + rec, err := rec.Scan(r) + data = append(data, rec) + return err + } + db.Query(proc, q, args...) // ?? check error + return data +} + +func QueryDataP[P scpcon[T], T any](db *Storage, q string, args ...interface{}) []T { var data []T rp := P(new(T)) proc := func(r *sql.Rows) error { - err := rp.Scan(r) + err := rp.ScanP(r) data = append(data, *rp) return err } diff --git a/tests/storage_test.go b/tests/storage_test.go index 52a2c1f..eec5dea 100644 --- a/tests/storage_test.go +++ b/tests/storage_test.go @@ -35,14 +35,23 @@ type greet struct { label string } -func (g *greet) Scan(rows *sql.Rows) error { +func (g greet) Scan(rows *sql.Rows) (greet, error) { + err := rows.Scan(&g.id, &g.label) + return g, err +} + +func (g *greet) ScanP(rows *sql.Rows) error { return rows.Scan(&g.id, &g.label) } func BaseTest(t *testing.T, cfg *sql.Cfg, db *sql.Storage) { db.Exec(insert) //data := sql.QueryCol[string](db, query, 2) - data := sql.QueryData[*greet](db, query) + data := sql.QueryData[greet](db, query) + t.AssertEqual(len(data), 2) + t.AssertEqual(data[0].label, "Hello World") + t.AssertEqual(data[1].label, "Good Afternoon") + data = sql.QueryDataP[*greet](db, query) t.AssertEqual(len(data), 2) t.AssertEqual(data[0].label, "Hello World") t.AssertEqual(data[1].label, "Good Afternoon")