feat: article: finish base functions
This commit is contained in:
67
utils/orm.go
Normal file
67
utils/orm.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/clause"
|
||||
"nCovTrack-Backend/global"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
var colNameReg, _ = regexp.Compile(".*column:(.*);?")
|
||||
var uniqueKeyReg, _ = regexp.Compile(".*(primaryKey|unique).*")
|
||||
|
||||
func getNotZeroFields[T any](model T) []string {
|
||||
t := reflect.TypeOf(model)
|
||||
v := reflect.ValueOf(model)
|
||||
var notZeroFields []string
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
if !v.Field(i).IsZero() {
|
||||
colName := colNameReg.FindSubmatch([]byte(t.Field(i).Tag.Get("gorm")))
|
||||
if len(colName) != 2 {
|
||||
panic("Model Tag regex error")
|
||||
}
|
||||
notZeroFields = append(notZeroFields, string(colName[1]))
|
||||
}
|
||||
}
|
||||
return notZeroFields
|
||||
}
|
||||
|
||||
func Upsert[T any](model *T, forceUpdateFiled ...string) (ok bool) {
|
||||
t := reflect.TypeOf(model).Elem()
|
||||
v := reflect.ValueOf(model).Elem()
|
||||
var uniqueKeyField []clause.Column
|
||||
notZeroField := NewSet(forceUpdateFiled...).Add("modify_time")
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
gormTag := t.Field(i).Tag.Get("gorm")
|
||||
if uniqueKey(gormTag) {
|
||||
uniqueKeyField = append(uniqueKeyField, clause.Column{Name: columnName(gormTag)})
|
||||
continue
|
||||
}
|
||||
if !v.Field(i).IsZero() {
|
||||
notZeroField.Add(columnName(gormTag))
|
||||
} else if t.Field(i).Type.Name() == "Time" {
|
||||
v.Field(i).Set(reflect.ValueOf(time.Now()))
|
||||
}
|
||||
}
|
||||
tx := global.Db.Clauses(clause.OnConflict{
|
||||
Columns: uniqueKeyField,
|
||||
DoUpdates: clause.AssignmentColumns(notZeroField.ToSlice()),
|
||||
}, clause.Returning{}).Create(model)
|
||||
if tx.Error != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func columnName(gormTag string) string {
|
||||
colNames := colNameReg.FindSubmatch([]byte(gormTag))
|
||||
if len(colNames) != 2 {
|
||||
panic("Model tag regex error")
|
||||
}
|
||||
return string(colNames[1])
|
||||
}
|
||||
|
||||
func uniqueKey(gormTag string) bool {
|
||||
return uniqueKeyReg.Match([]byte(gormTag))
|
||||
}
|
||||
Reference in New Issue
Block a user