github.com/profzone/eden-framework@v1.0.10/pkg/sqlx/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  }