You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

61 lines
1.3 KiB

package persist
import (
"fmt"
"reflect"
"strings"
)
// ReflectGormData todo cache data type info
func ReflectGormData(data any) (table string, columns []string, values map[string]any, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("%T parse gorm data error %v", data, r)
}
}()
values = make(map[string]any)
refValue := reflect.ValueOf(data)
refType := reflect.TypeOf(data)
tableNameM := refValue.MethodByName("TableName")
if !tableNameM.IsValid() {
err = fmt.Errorf("type %T not has method TableName", data)
return
}
rsp := tableNameM.Call(nil)
table = rsp[0].Interface().(string)
if refValue.Kind() == reflect.Ptr {
refValue = refValue.Elem()
}
if refType.Kind() == reflect.Ptr {
refType = refType.Elem()
}
for i := 0; i < refType.NumField(); i++ {
field := refType.Field(i)
value := refValue.Field(i).Interface()
// value
tag := field.Tag.Get("gorm")
column := getGormTagColumnName(tag)
if column == "" || strings.HasPrefix(column, "-") { // 忽略字段
continue
}
columns = append(columns, column)
values[column] = value
}
return
}
func getGormTagColumnName(tag string) (column string) {
i1 := strings.Index(tag, "column:")
if i1 < 0 {
return
}
i2 := strings.Index(tag[i1+7:], ";")
if i2 < 0 {
return tag[i1+7:]
}
return tag[i1+7 : i2+7]
}