github.com/kunlun-qilian/sqlx/v3@v3.0.0/task.go (about) 1 package sqlx 2 3 import ( 4 "fmt" 5 "runtime/debug" 6 7 "github.com/go-courier/logr" 8 "github.com/pkg/errors" 9 ) 10 11 type Task func(db DBExecutor) error 12 13 func (task Task) Run(db DBExecutor) (err error) { 14 defer func() { 15 if e := recover(); e != nil { 16 err = fmt.Errorf("panic: %s; calltrace:%s", fmt.Sprint(e), string(debug.Stack())) 17 } 18 }() 19 return task(db) 20 } 21 22 func NewTasks(db DBExecutor) *Tasks { 23 return &Tasks{ 24 db: db, 25 } 26 } 27 28 type Tasks struct { 29 db DBExecutor 30 tasks []Task 31 } 32 33 func (tasks Tasks) With(task ...Task) *Tasks { 34 tasks.tasks = append(tasks.tasks, task...) 35 return &tasks 36 } 37 38 func (tasks *Tasks) Do() (err error) { 39 if len(tasks.tasks) == 0 { 40 return nil 41 } 42 43 db := tasks.db 44 45 log := logr.FromContext(db.Context()) 46 47 if maybeTx, ok := db.(MaybeTxExecutor); ok { 48 inTxScope := false 49 50 if !maybeTx.IsTx() { 51 db, err = maybeTx.Begin() 52 if err != nil { 53 return err 54 } 55 maybeTx = db.(MaybeTxExecutor) 56 inTxScope = true 57 } 58 59 for _, task := range tasks.tasks { 60 if runErr := task.Run(db); runErr != nil { 61 if inTxScope { 62 // err will bubble up,just handle and rollback in outermost layer 63 log.Error(errors.Wrap(err, "SQL FAILED")) 64 if rollBackErr := maybeTx.Rollback(); rollBackErr != nil { 65 log.Warn(errors.Wrap(rollBackErr, "ROLLBACK FAILED")) 66 err = rollBackErr 67 return 68 } 69 } 70 return runErr 71 } 72 } 73 74 if inTxScope { 75 if commitErr := maybeTx.Commit(); commitErr != nil { 76 log.Warn(errors.Wrap(commitErr, "TRANSACTION COMMIT FAILED")) 77 return commitErr 78 } 79 } 80 81 } 82 return nil 83 }