github.com/wfusion/gofusion@v1.1.14/db/softdelete/deletedat.go (about)

     1  package softdelete
     2  
     3  import (
     4  	"log"
     5  	"sync"
     6  	"syscall"
     7  
     8  	"github.com/pkg/errors"
     9  	"gorm.io/gorm"
    10  	"gorm.io/gorm/clause"
    11  
    12  	"github.com/wfusion/gofusion/common/utils"
    13  	"github.com/wfusion/gofusion/common/utils/gomonkey"
    14  	"github.com/wfusion/gofusion/config"
    15  )
    16  
    17  var (
    18  	PatchGormDeleteAtOnce = new(sync.Once)
    19  )
    20  
    21  func PatchGormDeleteAt() (patches *gomonkey.Patches) {
    22  	PatchGormDeleteAtOnce.Do(func() {
    23  		pid := syscall.Getpid()
    24  		_, err := utils.Catch(func() {
    25  			patches = gomonkey.ApplyMethod(gorm.SoftDeleteDeleteClause{},
    26  				"ModifyStatement", gormSoftDeleteDeleteClauseModifyStatement)
    27  			log.Printf("%v [Gofusion] %s patch gorm.SoftDeleteDeleteClause success", pid, config.ComponentDB)
    28  		})
    29  		if err != nil {
    30  			log.Printf("%v [Gofusion] %s patch gorm.SoftDeleteDeleteClause failed: %s",
    31  				pid, config.ComponentDB, errors.Cause(err))
    32  		}
    33  	})
    34  
    35  	return
    36  }
    37  
    38  func gormSoftDeleteDeleteClauseModifyStatement(sd gorm.SoftDeleteDeleteClause, stmt *gorm.Statement) {
    39  	if stmt.Statement.Unscoped || stmt.SQL.Len() > 0 {
    40  		return
    41  	}
    42  
    43  	curTime := stmt.DB.NowFunc()
    44  	setClauses := clause.Set{{Column: clause.Column{Name: sd.Field.DBName}, Value: curTime}}
    45  	if clauses, ok := stmt.Clauses[setClauses.Name()]; ok {
    46  		if exprClauses, ok := clauses.Expression.(clause.Set); ok {
    47  			setClauses = append(setClauses, exprClauses...)
    48  		}
    49  	}
    50  	stmt.AddClause(setClauses)
    51  	stmt.SetColumn(sd.Field.DBName, curTime, true)
    52  
    53  	gorm.SoftDeleteQueryClause(sd).ModifyStatement(stmt)
    54  }