소스 검색

完成sql result tag开发

yjp 1 년 전
부모
커밋
d9141d6e0b

+ 2 - 2
api/api.go

@@ -2,8 +2,8 @@ package api
 
 import (
 	"context"
-	"errors"
 	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
 	"github.com/gin-gonic/gin"
 	"net/http"
 )
@@ -49,7 +49,7 @@ func New(opts ...Option) *Api {
 
 func (api *Api) Start() error {
 	err := api.server.ListenAndServe()
-	if err != nil && !errors.Is(err, http.ErrServerClosed) {
+	if err != nil && !fserr.Is(err, http.ErrServerClosed) {
 		return err
 	}
 

+ 5 - 3
infrastructure/database/sql_tpl/sql_tpl.go

@@ -1,6 +1,8 @@
 package sql_tpl
 
-import "errors"
+import (
+	"git.sxidc.com/service-supports/fserr"
+)
 
 const InsertTpl = `
 INSERT INTO
@@ -66,7 +68,7 @@ func (params InsertBatchExecuteParams) Map() (map[string]any, error) {
 		}
 
 		if len(columns) != len(tableRow.columnValues) {
-			return nil, errors.New("列数不匹配,保证每个TableRow的Add数量一致")
+			return nil, fserr.New("列数不匹配,保证每个TableRow的Add数量一致")
 		}
 
 		columnAndValueMap := make(map[string]any, 0)
@@ -104,7 +106,7 @@ type DeleteExecuteParams struct {
 
 func (params DeleteExecuteParams) Map() (map[string]any, error) {
 	if params.Conditions == nil {
-		return nil, errors.New("没有传递删除条件")
+		return nil, fserr.New("没有传递删除条件")
 	}
 
 	if params.Conditions.err != nil {

+ 6 - 6
infrastructure/database/sql_tpl/value.go

@@ -1,9 +1,9 @@
 package sql_tpl
 
 import (
-	"errors"
 	"git.sxidc.com/go-tools/utils/encoding"
 	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
 	"reflect"
 	"strconv"
 	"strings"
@@ -35,11 +35,11 @@ func parseValue(value any, opts ...AfterParsedStrValueOption) (string, error) {
 	valueValue := reflect.ValueOf(value)
 
 	if !valueValue.IsValid() {
-		return "", errors.New("无效值")
+		return "", fserr.New("无效值")
 	}
 
 	if valueValue.Kind() == reflect.Pointer && valueValue.IsNil() {
-		return "", errors.New("空值")
+		return "", fserr.New("空值")
 	}
 
 	if valueValue.Kind() == reflect.Pointer {
@@ -128,7 +128,7 @@ func parseValue(value any, opts ...AfterParsedStrValueOption) (string, error) {
 			return parsedValue, nil
 		}
 	default:
-		return "", errors.New("不支持的类型")
+		return "", fserr.New("不支持的类型")
 	}
 
 	for _, opt := range opts {
@@ -147,7 +147,7 @@ func parseSliceValues(values any, opts ...AfterParsedStrValueOption) (string, er
 	sliceValue := reflect.ValueOf(values)
 
 	if !sliceValue.IsValid() {
-		return "", errors.New("无效值")
+		return "", fserr.New("无效值")
 	}
 
 	if sliceValue.Kind() == reflect.Pointer && sliceValue.IsNil() {
@@ -159,7 +159,7 @@ func parseSliceValues(values any, opts ...AfterParsedStrValueOption) (string, er
 	}
 
 	if sliceValue.Kind() != reflect.Slice {
-		return "", errors.New("传递的不是slice")
+		return "", fserr.New("传递的不是slice")
 	}
 
 	parsedValues := make([]string, 0)

+ 4 - 4
tag/sql/sql_mapping/tag.go

@@ -1,9 +1,9 @@
 package sql_mapping
 
 import (
-	"errors"
 	"git.sxidc.com/go-tools/utils/reflectutils"
 	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
 	"github.com/iancoleman/strcase"
 	"reflect"
 	"strings"
@@ -126,7 +126,7 @@ func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
 			switch tagPartKeyValue[0] {
 			case tagPartColumn:
 				if strutils.IsStringEmpty(tagPartKeyValue[1]) {
-					return nil, errors.New("column没有赋值列名")
+					return nil, fserr.New("column没有赋值列名")
 				}
 
 				tag.Name = tagPartKeyValue[1]
@@ -144,13 +144,13 @@ func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
 				}
 			case tagPartAes:
 				if len(tagPartKeyValue[1]) != 32 {
-					return nil, errors.New("AES密钥长度应该为32个字节")
+					return nil, fserr.New("AES密钥长度应该为32个字节")
 				}
 
 				tag.AESKey = tagPartKeyValue[1]
 			case tagPartJoinWith:
 				if strutils.IsStringEmpty(tagPartKeyValue[1]) {
-					return nil, errors.New(tagPartJoinWith + "没有赋值分隔符")
+					return nil, fserr.New(tagPartJoinWith + "没有赋值分隔符")
 				}
 
 				tag.JoinWith = tagPartKeyValue[1]

+ 7 - 12
tag/sql/sql_mapping/usage.go

@@ -53,13 +53,13 @@ func defaultCallback(fields *[]Field) OnParsedFieldTagFunc {
 		switch entityFieldKind {
 		case reflect.Struct:
 			if !reflectutils.IsValueTime(entityFieldElemValue) {
-				return fserr.New(fieldName + "Error: 解析tag内部错误,除time.Time类型之外的结构被回调")
+				return fserr.New(fieldName + " Error: 解析tag内部错误,除time.Time类型之外的结构被回调")
 			}
 
 			entityFieldValue = entityFieldElemValue.Interface().(time.Time).Format(timeWriteFormat)
 		case reflect.Slice:
 			if !reflectutils.IsSliceValueOf(entityFieldElemValue, reflect.String) {
-				return fserr.New(fieldName + "Error: slice仅支持[]string")
+				return fserr.New(fieldName + " Error: slice仅支持[]string")
 			}
 
 			entityFieldValue = strings.Join(entityFieldElemValue.Interface().([]string), tag.JoinWith)
@@ -82,21 +82,16 @@ func defaultCallback(fields *[]Field) OnParsedFieldTagFunc {
 func toSqlValue(value any, tag *Tag) (string, error) {
 	switch v := value.(type) {
 	case string:
-		retValue, err := postDeal(v, tag)
+		retValue, err := dealStringValue(v, tag)
 		if err != nil {
 			return "", err
 		}
 
-		return retValue, nil
+		return "'" + retValue + "'", nil
 	default:
-		var sqlValue string
-
-		err := reflectutils.AssignStringValue(v, reflect.ValueOf(sqlValue))
-		if err != nil {
-			return "", err
-		}
+		var retValue string
 
-		retValue, err := postDeal(sqlValue, tag)
+		err := reflectutils.AssignStringValue(v, reflect.ValueOf(retValue))
 		if err != nil {
 			return "", err
 		}
@@ -105,7 +100,7 @@ func toSqlValue(value any, tag *Tag) (string, error) {
 	}
 }
 
-func postDeal(value string, tag *Tag) (string, error) {
+func dealStringValue(value string, tag *Tag) (string, error) {
 	retValue := value
 
 	if strutils.IsStringNotEmpty(tag.Trim) {

+ 5 - 4
tag/sql/sql_result/tag.go

@@ -1,12 +1,13 @@
 package sql_result
 
 import (
-	"errors"
 	"git.sxidc.com/go-tools/utils/reflectutils"
 	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
 	"github.com/iancoleman/strcase"
 	"reflect"
 	"strings"
+	"time"
 )
 
 const (
@@ -91,7 +92,7 @@ func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
 
 	tag := &Tag{
 		Name:      strcase.ToSnake(field.Name),
-		ParseTime: "",
+		ParseTime: time.DateTime,
 		AESKey:    "",
 		SplitWith: defaultSplitWith,
 	}
@@ -115,13 +116,13 @@ func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
 				tag.ParseTime = tagPartKeyValue[1]
 			case tagPartAes:
 				if len(tagPartKeyValue[1]) != 32 {
-					return nil, errors.New("AES密钥长度应该为32个字节")
+					return nil, fserr.New("AES密钥长度应该为32个字节")
 				}
 
 				tag.AESKey = tagPartKeyValue[1]
 			case tagPartSplitWith:
 				if strutils.IsStringEmpty(tagPartKeyValue[1]) {
-					return nil, errors.New(defaultSplitWith + "没有赋值分隔符")
+					return nil, fserr.New(defaultSplitWith + "没有赋值分隔符")
 				}
 
 				tag.SplitWith = tagPartKeyValue[1]

+ 158 - 0
tag/sql/sql_result/usage.go

@@ -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
+}