go-transaction-manager
140 строк · 2.5 Кб
1package gorm_test2
3import (4"context"5"fmt"6
7_ "github.com/mattn/go-sqlite3"8"gorm.io/driver/sqlite"9"gorm.io/gorm"10
11trmgorm "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.
19func Example() {20db, err := gorm.Open(sqlite.Open("file:test.drivers?mode=memory"))21checkErr(err)22
23sqlDB, err := db.DB()24checkErr(err)25
26defer sqlDB.Close()27
28// Migrate the schema29checkErr(db.AutoMigrate(&userRow{}))30
31r := newRepo(db, trmgorm.DefaultCtxGetter)32
33u := &user{34Username: "username",35}36
37ctx := context.Background()38trManager := manager.Must(39trmgorm.NewDefaultFactory(db),40manager.WithSettings(trmgorm.MustSettings(41settings.Must(42settings.WithPropagation(trm.PropagationNested))),43),44)45
46err = trManager.Do(ctx, func(ctx context.Context) error {47if err := r.Save(ctx, u); err != nil {48return err49}50
51return trManager.Do(ctx, func(ctx context.Context) error {52u.Username = "new_username"53
54return r.Save(ctx, u)55})56})57checkErr(err)58
59userFromDB, err := r.GetByID(ctx, u.ID)60checkErr(err)61
62fmt.Println(userFromDB)63
64// Output: &{1 new_username}65}
66
67type repo struct {68db *gorm.DB69getter *trmgorm.CtxGetter70}
71
72func newRepo(db *gorm.DB, c *trmgorm.CtxGetter) *repo {73return &repo{74db: db,75getter: c,76}77}
78
79type user struct {80ID int6481Username string82}
83
84type userRow struct {85ID int64 `gorm:"primarykey"`86Username string87}
88
89func (r *repo) GetByID(ctx context.Context, id int64) (*user, error) {90var row userRow91db := r.getter.DefaultTrOrDB(ctx, r.db).92WithContext(ctx).Model(userRow{ID: id}).First(&row)93
94if db.Error != nil {95return nil, db.Error96}97
98return r.toModel(row), nil99}
100
101func (r *repo) Save(ctx context.Context, u *user) error {102isNew := u.ID == 0103
104db := r.getter.DefaultTrOrDB(ctx, r.db).WithContext(ctx)105
106row := r.toRow(u)107if isNew {108db = db.Create(&row)109
110u.ID = row.ID111} else {112db = db.Save(&row)113}114
115if db.Error != nil {116return db.Error117}118
119return nil120}
121
122func (r *repo) toRow(model *user) userRow {123return userRow{124ID: model.ID,125Username: model.Username,126}127}
128
129func (r *repo) toModel(row userRow) *user {130return &user{131ID: row.ID,132Username: row.Username,133}134}
135
136func checkErr(err error) {137if err != nil {138panic(err)139}140}
141