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