• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//  compile
2
3// Copyright 2021 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package main
8
9import (
10	"database/sql"
11)
12
13// Collection generic interface which things can be added to.
14type Collection[T any] interface {
15	Add(T)
16}
17
18// Slice generic slice implementation of a Collection
19type Slice[T any] []*T
20
21func (s *Slice[T]) Add(t *T) {
22	*s = append(*s, t)
23}
24
25type Scanner interface {
26	Scan(...interface{}) error
27}
28
29type Mapper[T any] func(s Scanner, t T) error
30
31type Repository[T any] struct {
32	db *sql.DB
33}
34
35func (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
46func (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
58type Actor struct {
59	ActorID   uint16
60	FirstName string
61	LastName  string
62}
63
64type ActorRepository struct {
65	r Repository[Actor]
66}
67
68func (ActorRepository) scan(s Scanner, a *Actor) error {
69	return s.Scan(&a.ActorID, &a.FirstName, &a.LastName)
70}
71
72func (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