|
|
@@ -0,0 +1,158 @@
|
|
|
+package sql_result
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "git.sxidc.com/go-tools/utils/encoding"
|
|
|
+ "git.sxidc.com/go-tools/utils/reflectutils"
|
|
|
+ "git.sxidc.com/go-tools/utils/strutils"
|
|
|
+ "git.sxidc.com/service-supports/fserr"
|
|
|
+ "reflect"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ sqlResultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00"
|
|
|
+ sqlResultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00"
|
|
|
+ sqlResultTimeSecFormat = "2006-01-02T15:04:05+08:00"
|
|
|
+)
|
|
|
+
|
|
|
+func DefaultUsage(result map[string]any, e any) error {
|
|
|
+ if result == nil || len(result) == 0 {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ err := UseTag(e, defaultCallback(result))
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func defaultCallback(result map[string]any) OnParsedFieldTagFunc {
|
|
|
+ return func(fieldName string, entityFieldElemValue reflect.Value, tag *Tag) error {
|
|
|
+ resultValue, ok := result[tag.Name]
|
|
|
+ if !ok {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if resultValue == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ entityFieldKind := reflectutils.GroupValueKind(entityFieldElemValue)
|
|
|
+
|
|
|
+ switch entityFieldKind {
|
|
|
+ case reflect.Bool:
|
|
|
+ return reflectutils.AssignBoolValue(resultValue, entityFieldElemValue)
|
|
|
+ case reflect.String:
|
|
|
+ strValue := resultValue.(string)
|
|
|
+
|
|
|
+ // 实体字段是字符串类型,接收到的是数据库时间格式
|
|
|
+ parsedTime, err := parseTimeStringResult(strValue)
|
|
|
+ if err == nil {
|
|
|
+ // 转换成功说明是时间字符串
|
|
|
+ strValue = parsedTime.Format(tag.ParseTime)
|
|
|
+ }
|
|
|
+
|
|
|
+ parsedValue, err := dealStringResultValue(strValue, tag)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return reflectutils.AssignStringValue(parsedValue, entityFieldElemValue)
|
|
|
+ case reflect.Int64:
|
|
|
+ return reflectutils.AssignInt64Value(resultValue, entityFieldElemValue)
|
|
|
+ case reflect.Uint64:
|
|
|
+ return reflectutils.AssignUint64Value(resultValue, entityFieldElemValue)
|
|
|
+ case reflect.Float64:
|
|
|
+ return reflectutils.AssignFloat64Value(resultValue, entityFieldElemValue)
|
|
|
+ case reflect.Struct:
|
|
|
+ // 实体字段是time.Time,接收到的是数据库时间格式
|
|
|
+ if reflectutils.IsValueTime(entityFieldElemValue) {
|
|
|
+ parsedTime, err := parseTimeStringResult(resultValue.(string))
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ entityFieldElemValue.Set(reflect.ValueOf(parsedTime))
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
|
|
|
+ fieldName, tag.Name, entityFieldElemValue.Type().String())
|
|
|
+ case reflect.Slice:
|
|
|
+ if reflectutils.IsSliceValueOf(entityFieldElemValue, reflect.String) {
|
|
|
+ return fserr.New(fieldName + " Error: slice仅支持[]string")
|
|
|
+ }
|
|
|
+
|
|
|
+ strValue, ok := resultValue.(string)
|
|
|
+ if !ok {
|
|
|
+ return fserr.New("Result Type Error: slice仅支持[]string")
|
|
|
+ }
|
|
|
+
|
|
|
+ strParts := strings.Split(strValue, tag.SplitWith)
|
|
|
+ if strParts == nil || len(strParts) == 0 {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ valSlice := entityFieldElemValue
|
|
|
+ if valSlice.IsNil() {
|
|
|
+ valSlice = reflect.MakeSlice(entityFieldElemValue.Type(), 0, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, strPart := range strParts {
|
|
|
+ valSlice = reflect.Append(valSlice, reflect.ValueOf(strPart))
|
|
|
+ }
|
|
|
+
|
|
|
+ entityFieldElemValue.Set(valSlice)
|
|
|
+ return nil
|
|
|
+ default:
|
|
|
+ return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
|
|
|
+ fieldName, tag.Name, entityFieldElemValue.Type().String())
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func parseTimeStringResult(timeStr string) (time.Time, error) {
|
|
|
+ var layout string
|
|
|
+
|
|
|
+ if strings.HasSuffix(timeStr, ".000000+08:00") {
|
|
|
+ layout = sqlResultTimeMicroFormat
|
|
|
+ } else if strings.HasSuffix(timeStr, ".000+08:00") {
|
|
|
+ layout = sqlResultTimeMilliFormat
|
|
|
+ } else {
|
|
|
+ layout = sqlResultTimeSecFormat
|
|
|
+ }
|
|
|
+
|
|
|
+ return time.ParseInLocation(layout, timeStr, time.Local)
|
|
|
+}
|
|
|
+
|
|
|
+func dealStringResultValue(value string, tag *Tag) (string, error) {
|
|
|
+ retValue := value
|
|
|
+
|
|
|
+ if strutils.IsStringNotEmpty(tag.AESKey) {
|
|
|
+ decryptedValue, err := encoding.AESDecrypt(retValue, tag.AESKey)
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ retValue = decryptedValue
|
|
|
+ }
|
|
|
+
|
|
|
+ if strutils.IsStringNotEmpty(tag.Trim) {
|
|
|
+ retValue = strings.Trim(retValue, tag.Trim)
|
|
|
+ } else {
|
|
|
+ if strutils.IsStringNotEmpty(tag.TrimPrefix) {
|
|
|
+ retValue = strings.TrimPrefix(retValue, tag.TrimPrefix)
|
|
|
+ }
|
|
|
+
|
|
|
+ if strutils.IsStringNotEmpty(tag.TrimSuffix) {
|
|
|
+ retValue = strings.TrimSuffix(retValue, tag.TrimSuffix)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return retValue, nil
|
|
|
+}
|