go-transaction-manager

Форк
0
140 строк · 2.5 Кб
1
package gorm_test
2

3
import (
4
	"context"
5
	"fmt"
6

7
	_ "github.com/mattn/go-sqlite3"
8
	"gorm.io/driver/sqlite"
9
	"gorm.io/gorm"
10

11
	trmgorm "github.com/avito-tech/go-transaction-manager/drivers/gorm/v2"
12

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

18
// Example demonstrates the implementation of the Repository pattern by trm.Manager.
19
func Example() {
20
	db, err := gorm.Open(sqlite.Open("file:test.drivers?mode=memory"))
21
	checkErr(err)
22

23
	sqlDB, err := db.DB()
24
	checkErr(err)
25

26
	defer sqlDB.Close()
27

28
	// Migrate the schema
29
	checkErr(db.AutoMigrate(&userRow{}))
30

31
	r := newRepo(db, trmgorm.DefaultCtxGetter)
32

33
	u := &user{
34
		Username: "username",
35
	}
36

37
	ctx := context.Background()
38
	trManager := manager.Must(
39
		trmgorm.NewDefaultFactory(db),
40
		manager.WithSettings(trmgorm.MustSettings(
41
			settings.Must(
42
				settings.WithPropagation(trm.PropagationNested))),
43
		),
44
	)
45

46
	err = trManager.Do(ctx, func(ctx context.Context) error {
47
		if err := r.Save(ctx, u); err != nil {
48
			return err
49
		}
50

51
		return trManager.Do(ctx, func(ctx context.Context) error {
52
			u.Username = "new_username"
53

54
			return r.Save(ctx, u)
55
		})
56
	})
57
	checkErr(err)
58

59
	userFromDB, err := r.GetByID(ctx, u.ID)
60
	checkErr(err)
61

62
	fmt.Println(userFromDB)
63

64
	// Output: &{1 new_username}
65
}
66

67
type repo struct {
68
	db     *gorm.DB
69
	getter *trmgorm.CtxGetter
70
}
71

72
func newRepo(db *gorm.DB, c *trmgorm.CtxGetter) *repo {
73
	return &repo{
74
		db:     db,
75
		getter: c,
76
	}
77
}
78

79
type user struct {
80
	ID       int64
81
	Username string
82
}
83

84
type userRow struct {
85
	ID       int64 `gorm:"primarykey"`
86
	Username string
87
}
88

89
func (r *repo) GetByID(ctx context.Context, id int64) (*user, error) {
90
	var row userRow
91
	db := r.getter.DefaultTrOrDB(ctx, r.db).
92
		WithContext(ctx).Model(userRow{ID: id}).First(&row)
93

94
	if db.Error != nil {
95
		return nil, db.Error
96
	}
97

98
	return r.toModel(row), nil
99
}
100

101
func (r *repo) Save(ctx context.Context, u *user) error {
102
	isNew := u.ID == 0
103

104
	db := r.getter.DefaultTrOrDB(ctx, r.db).WithContext(ctx)
105

106
	row := r.toRow(u)
107
	if isNew {
108
		db = db.Create(&row)
109

110
		u.ID = row.ID
111
	} else {
112
		db = db.Save(&row)
113
	}
114

115
	if db.Error != nil {
116
		return db.Error
117
	}
118

119
	return nil
120
}
121

122
func (r *repo) toRow(model *user) userRow {
123
	return userRow{
124
		ID:       model.ID,
125
		Username: model.Username,
126
	}
127
}
128

129
func (r *repo) toModel(row userRow) *user {
130
	return &user{
131
		ID:       row.ID,
132
		Username: row.Username,
133
	}
134
}
135

136
func checkErr(err error) {
137
	if err != nil {
138
		panic(err)
139
	}
140
}
141

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

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

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

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