go-transaction-manager

Форк
0
125 строк · 2.4 Кб
1
//go:build with_real_db
2
// +build with_real_db
3

4
package pgxv4_test
5

6
import (
7
	"context"
8
	"fmt"
9

10
	"github.com/jackc/pgx/v4/pgxpool"
11

12
	trmpgx "github.com/avito-tech/go-transaction-manager/drivers/pgxv4/v2"
13

14
	"github.com/avito-tech/go-transaction-manager/trm/v2/manager"
15
)
16

17
// Example demonstrates the implementation of the Repository pattern by trm.Manager.
18
func Example() {
19
	ctx := context.Background()
20

21
	uri := fmt.Sprintf("postgres://%s:%s@%s:%d/%s",
22
		"user", "pass", "localhost", 5432, "db",
23
	)
24

25
	pool, err := pgxpool.Connect(ctx, uri)
26
	checkErr(err)
27

28
	defer pool.Close()
29

30
	sqlStmt := `CREATE TABLE IF NOT EXISTS users_v4 (user_id SERIAL, username TEXT)`
31
	_, err = pool.Exec(ctx, sqlStmt)
32
	checkErr(err, sqlStmt)
33

34
	r := newRepo(pool, trmpgx.DefaultCtxGetter)
35
	trManager := manager.Must(trmpgx.NewDefaultFactory(pool))
36

37
	u := &user{
38
		Username: "username",
39
	}
40

41
	err = trManager.Do(ctx, func(ctx context.Context) error {
42
		if err := r.Save(ctx, u); err != nil {
43
			return err
44
		}
45

46
		return trManager.Do(ctx, func(ctx context.Context) error {
47
			u.Username = "new_username"
48

49
			return r.Save(ctx, u)
50
		})
51
	})
52
	checkErr(err)
53

54
	userFromDB, err := r.GetByID(ctx, u.ID)
55
	checkErr(err)
56

57
	fmt.Println(userFromDB)
58

59
	// Output: &{1 new_username}
60
}
61

62
type repo struct {
63
	db     *pgxpool.Pool
64
	getter *trmpgx.CtxGetter
65
}
66

67
func newRepo(db *pgxpool.Pool, c *trmpgx.CtxGetter) *repo {
68
	repo := &repo{
69
		db:     db,
70
		getter: c,
71
	}
72

73
	return repo
74
}
75

76
type user struct {
77
	ID       int64
78
	Username string
79
}
80

81
func (r *repo) GetByID(ctx context.Context, id int64) (*user, error) {
82
	query := `SELECT * FROM users_v4 WHERE user_id=$1`
83

84
	conn := r.getter.DefaultTrOrDB(ctx, r.db)
85
	row := conn.QueryRow(ctx, query, id)
86

87
	user := &user{}
88

89
	err := row.Scan(&user.ID, &user.Username)
90
	if err != nil {
91
		return nil, err
92
	}
93

94
	return user, nil
95
}
96

97
func (r *repo) Save(ctx context.Context, u *user) error {
98
	isNew := u.ID == 0
99
	conn := r.getter.DefaultTrOrDB(ctx, r.db)
100

101
	if !isNew {
102
		query := `UPDATE users_v4 SET username = $1 WHERE user_id = $2`
103

104
		if _, err := conn.Exec(ctx, query, u.Username, u.ID); err != nil {
105
			return err
106
		}
107

108
		return nil
109
	}
110

111
	query := `INSERT INTO users_v4 (username) VALUES ($1) RETURNING user_id`
112

113
	err := conn.QueryRow(ctx, query, u.Username).Scan(&u.ID)
114
	if err != nil {
115
		return err
116
	}
117

118
	return nil
119
}
120

121
func checkErr(err error, args ...interface{}) {
122
	if err != nil {
123
		panic(fmt.Sprint(append([]interface{}{err}, args...)...))
124
	}
125
}
126

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.