feat: article: finish base functions

This commit is contained in:
fallen-angle
2022-02-15 16:49:32 +08:00
parent 72ef5c92c4
commit be5def58fd
13 changed files with 245 additions and 37 deletions

67
utils/orm.go Normal file
View 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))
}

1
utils/reflect.go Normal file
View File

@@ -0,0 +1 @@
package utils

View File

@@ -7,7 +7,14 @@ import (
"github.com/gin-gonic/gin"
)
func Success(c *gin.Context, code int, msg interface{}, data interface{}) {
const (
SUCCESS = "Success"
BAD_REQUEST = "Bad Request"
DATA_NOT_FOUND = "Data not Found"
STATUS_DATA_NOT_FOUND = 210
)
func Success(c *gin.Context, status int, code int, msg interface{}, data interface{}) {
c.JSON(http.StatusOK, models.GinResponse{Code: code, Msg: msg, Data: data})
}
@@ -16,9 +23,29 @@ func Error(c *gin.Context, status int, code int, msg interface{}, data interface
}
func Succ(c *gin.Context, data interface{}) {
Success(c, http.StatusOK, "success", data)
Success(c, http.StatusOK, http.StatusOK, SUCCESS, data)
}
func DataNotFound(c *gin.Context, data interface{}) {
Success(c, http.StatusOK, STATUS_DATA_NOT_FOUND, DATA_NOT_FOUND, data)
}
func Err(c *gin.Context, status int, code int, msg interface{}) {
c.JSON(status, models.GinResponse{Code: code, Msg: msg})
Error(c, status, code, msg, nil)
}
func ServerError(c *gin.Context, code int, msg interface{}) {
Err(c, http.StatusInternalServerError, code, msg)
}
func ServerErr(c *gin.Context, msg interface{}) {
ServerError(c, http.StatusInternalServerError, msg)
}
func RequestError(c *gin.Context, code int, data interface{}) {
Error(c, http.StatusBadRequest, code, BAD_REQUEST, data)
}
func RequestErr(c *gin.Context, data interface{}) {
RequestError(c, http.StatusBadRequest, data)
}

38
utils/set.go Normal file
View File

@@ -0,0 +1,38 @@
package utils
type void struct{}
type Set[T comparable] struct {
setMap map[T]void
}
func NewSet[T comparable](eles ...T) *Set[T] {
set := &Set[T]{setMap: make(map[T]void)}
set.AddAll(eles...)
return set
}
func (set *Set[T]) Add(ele T) *Set[T] {
set.setMap[ele] = void{}
return set
}
func (set *Set[T]) AddAll(eles ...T) *Set[T] {
for _, ele := range eles {
set.Add(ele)
}
return set
}
func (set *Set[T]) Delete(ele T) *Set[T] {
delete(set.setMap, ele)
return set
}
func (set *Set[T]) ToSlice() []T {
var s []T
for k, _ := range set.setMap {
s = append(s, k)
}
return s
}