Documentation
¶
Overview ¶
Package gorm is an implementation of trm.Transaction interface by Transaction for *gorm.DB.
Example ¶
Example demonstrates the implementation of the Repository pattern by trm.Manager.
//go:build go1.16
// +build go1.16
package main
import (
"context"
"fmt"
_ "github.com/mattn/go-sqlite3"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
trmgorm "github.com/avito-tech/go-transaction-manager/gorm"
"github.com/avito-tech/go-transaction-manager/trm"
"github.com/avito-tech/go-transaction-manager/trm/manager"
"github.com/avito-tech/go-transaction-manager/trm/settings"
)
// Example demonstrates the implementation of the Repository pattern by trm.Manager.
func main() {
db, err := gorm.Open(sqlite.Open("file:test.db?mode=memory"))
checkErr(err)
sqlDB, err := db.DB()
checkErr(err)
defer sqlDB.Close()
// Migrate the schema
checkErr(db.AutoMigrate(&userRow{}))
r := newRepo(db, trmgorm.DefaultCtxGetter)
u := &user{
Username: "username",
}
ctx := context.Background()
trManager := manager.Must(
trmgorm.NewDefaultFactory(db),
manager.WithSettings(trmgorm.MustSettings(
settings.Must(
settings.WithPropagation(trm.PropagationNested))),
),
)
err = trManager.Do(ctx, func(ctx context.Context) error {
if err := r.Save(ctx, u); err != nil {
return err
}
return trManager.Do(ctx, func(ctx context.Context) error {
u.Username = "new_username"
return r.Save(ctx, u)
})
})
checkErr(err)
userFromDB, err := r.GetByID(ctx, u.ID)
checkErr(err)
fmt.Println(userFromDB)
}
type repo struct {
db *gorm.DB
getter *trmgorm.CtxGetter
}
func newRepo(db *gorm.DB, c *trmgorm.CtxGetter) *repo {
return &repo{
db: db,
getter: c,
}
}
type user struct {
ID int64
Username string
}
type userRow struct {
ID int64 `gorm:"primarykey"`
Username string
}
func (r *repo) GetByID(ctx context.Context, id int64) (*user, error) {
var row userRow
db := r.getter.DefaultTrOrDB(ctx, r.db).
WithContext(ctx).Model(userRow{ID: id}).First(&row)
if db.Error != nil {
return nil, db.Error
}
return r.toModel(row), nil
}
func (r *repo) Save(ctx context.Context, u *user) error {
isNew := u.ID == 0
db := r.getter.DefaultTrOrDB(ctx, r.db).WithContext(ctx)
row := r.toRow(u)
if isNew {
db = db.Create(&row)
u.ID = row.ID
} else {
db = db.Save(&row)
}
if db.Error != nil {
return db.Error
}
return nil
}
func (r *repo) toRow(model *user) userRow {
return userRow{
ID: model.ID,
Username: model.Username,
}
}
func (r *repo) toModel(row userRow) *user {
return &user{
ID: row.ID,
Username: row.Username,
}
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
Output: &{1 new_username}
Index ¶
- Variables
- func NewDefaultFactory(db *gorm.DB) trm.TrFactory
- type CtxGetter
- type Opt
- type Settings
- type Transaction
- func (t *Transaction) Begin(ctx context.Context, s trm.Settings) (context.Context, trm.Transaction, error)
- func (t *Transaction) Closed() <-chan struct{}
- func (t *Transaction) Commit(_ context.Context) error
- func (t *Transaction) IsActive() bool
- func (t *Transaction) Rollback(_ context.Context) error
- func (t *Transaction) Transaction() interface{}
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultCtxGetter = NewCtxGetter(trmcontext.DefaultManager)
DefaultCtxGetter is the CtxGetter with settings.DefaultCtxKey.
Functions ¶
Types ¶
type CtxGetter ¶
type CtxGetter struct {
// contains filtered or unexported fields
}
CtxGetter gets Tr from trm.CtxManager by casting trm.Transaction to *gorm.DB.
func NewCtxGetter ¶
func NewCtxGetter(c trm.CtxManager) *CtxGetter
NewCtxGetter returns *CtxGetter to get *gorm.DB from context.Context.
func (*CtxGetter) DefaultTrOrDB ¶
DefaultTrOrDB returns Tr(*gorm.DB) from context.Context or DB(*gorm.DB) otherwise.
type Opt ¶
Opt is a type to configure Settings.
func WithTxOptions ¶
WithTxOptions sets up sql.TxOptions for the Settings.
type Settings ¶
Settings contains settings for Transaction.
func MustSettings ¶
MustSettings returns Settings if stopByErr is nil and panics otherwise.
func NewSettings ¶
NewSettings creates Settings.
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction is trm.Transaction for sqlx.Tx.
func NewTransaction ¶
func NewTransaction( ctx context.Context, opts *sql.TxOptions, db *gorm.DB, ) (context.Context, *Transaction, error)
NewTransaction creates trm.Transaction for sqlx.Tx.
func (*Transaction) Begin ¶
func (t *Transaction) Begin(ctx context.Context, s trm.Settings) (context.Context, trm.Transaction, error)
Begin nested transaction by save point.
func (*Transaction) Closed ¶ added in v1.5.0
func (t *Transaction) Closed() <-chan struct{}
Closed returns a channel that's closed when transaction committed or rolled back.
func (*Transaction) Commit ¶
func (t *Transaction) Commit(_ context.Context) error
Commit closes the trm.Transaction.
func (*Transaction) IsActive ¶
func (t *Transaction) IsActive() bool
IsActive returns true if the transaction started but not committed or rolled back.
func (*Transaction) Rollback ¶
func (t *Transaction) Rollback(_ context.Context) error
Rollback the trm.Transaction.
func (*Transaction) Transaction ¶
func (t *Transaction) Transaction() interface{}
Transaction returns the real transaction sqlx.Tx. trm.NestedTrFactory returns IsActive as true while trm.Transaction is opened.