Source file
test/typeparam/issue47896.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "database/sql"
11 )
12
13
14 type Collection[T any] interface {
15 Add(T)
16 }
17
18
19 type Slice[T any] []*T
20
21 func (s *Slice[T]) Add(t *T) {
22 *s = append(*s, t)
23 }
24
25 type Scanner interface {
26 Scan(...interface{}) error
27 }
28
29 type Mapper[T any] func(s Scanner, t T) error
30
31 type Repository[T any] struct {
32 db *sql.DB
33 }
34
35 func (r *Repository[T]) scan(rows *sql.Rows, m Mapper[*T], c Collection[*T]) error {
36 for rows.Next() {
37 t := new(T)
38 if err := m(rows, t); err != nil {
39 return err
40 }
41 c.Add(t)
42 }
43 return rows.Err()
44 }
45
46 func (r *Repository[T]) query(query string, m Mapper[*T], c Collection[*T]) error {
47 rows, err := r.db.Query(query)
48 if err != nil {
49 return err
50 }
51 if err := r.scan(rows, m, c); err != nil {
52 rows.Close()
53 return err
54 }
55 return rows.Close()
56 }
57
58 type Actor struct {
59 ActorID uint16
60 FirstName string
61 LastName string
62 }
63
64 type ActorRepository struct {
65 r Repository[Actor]
66 }
67
68 func (ActorRepository) scan(s Scanner, a *Actor) error {
69 return s.Scan(&a.ActorID, &a.FirstName, &a.LastName)
70 }
71
72 func (r *ActorRepository) SelectAll(c Collection[*Actor]) error {
73 return r.r.query("SELECT `actor_id`, `first_name`, `last_name` FROM `actor` LIMIT 10", r.scan, c)
74 }
75
View as plain text