123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- package sql
- import (
- "errors"
- "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/ds-sdk/sdk"
- "reflect"
- "strings"
- "time"
- )
- func ParseSqlResult(input any, output any) error {
- if input == nil || output == nil {
- return nil
- }
-
- outputType := reflect.TypeOf(output)
- if outputType.Kind() != reflect.Ptr {
- return errors.New("输出实体应该为结构的slice或者是结构的指针")
- }
-
- if outputType.Kind() == reflect.Ptr {
- outputType = outputType.Elem()
- }
-
- if outputType.Kind() != reflect.Slice && outputType.Kind() != reflect.Struct {
- return errors.New("输出实体应该为结构的slice或者是结构的指针")
- }
-
- outputElemType := outputType
- if outputElemType.Kind() == reflect.Slice {
- outputElemType = outputElemType.Elem()
- }
-
- if outputElemType.Kind() != reflect.Struct {
- return errors.New("输出实体slice应该为结构的slice指针")
- }
-
- tableRows, ok := input.([]sdk.SqlResult)
- if !ok {
- tableRow, ok := input.(sdk.SqlResult)
- if !ok {
- return errors.New("输入数据应该为[]sdk.SqlResult或[]sdk.SqlResult")
- }
- tableRows = []sdk.SqlResult{tableRow}
- }
-
- outputEntities := reflect.MakeSlice(reflect.SliceOf(outputElemType), 0, 0)
- for _, tableRow := range tableRows {
-
- outputEntityValue := reflect.New(outputElemType).Elem().Addr()
- outputEntity := outputEntityValue.Interface()
- sqlResult, err := ParseSqlResultTag(outputEntity)
- if err != nil {
- return err
- }
- err = formOutputEntity(tableRow, sqlResult)
- if err != nil {
- return err
- }
-
- outputEntities = reflect.Append(outputEntities, outputEntityValue.Elem())
- }
-
- outputValue := reflect.Indirect(reflect.ValueOf(output))
- if !outputValue.CanSet() {
- return nil
- }
- if outputType.Kind() == reflect.Slice {
- outputValue.Set(outputEntities)
- } else {
- outputValue.Set(outputEntities.Index(0))
- }
- return nil
- }
- func formOutputEntity(tableRow sdk.SqlResult, sqlResult *Result) error {
- for fieldName, resultElement := range sqlResult.ResultElement {
- switch element := resultElement.(type) {
- case *Result:
- err := formOutputEntity(tableRow, element)
- if err != nil {
- return err
- }
- case *ResultColumn:
- tableRowValue, ok := tableRow[element.Name]
- if !ok {
- continue
- }
-
- fieldTypeElem := element.FieldTypeElem
- fieldValueElem := element.FieldValueElem
- outputKind := reflectutils.GroupValueKind(fieldValueElem)
- if !fieldValueElem.CanSet() {
- continue
- }
- switch outputKind {
- case reflect.Bool:
- err := reflectutils.AssignBoolValue(tableRowValue, fieldValueElem)
- if err != nil {
- return err
- }
- case reflect.String:
- strValue := tableRowValue.(string)
- if strutils.IsStringNotEmpty(element.ParseTime) {
- parsedTime, err := sdk.ParseSqlResultTimeStr(strValue)
- if err != nil {
- return err
- }
- strValue = parsedTime.Format(element.ParseTime)
- } else if strutils.IsStringNotEmpty(element.AESKey) {
- if strutils.IsStringNotEmpty(strValue) {
- decryptedValue, err := encoding.AESDecrypt(strValue, element.AESKey)
- if err != nil {
- return err
- }
- strValue = decryptedValue
- }
- }
- err := reflectutils.AssignStringValue(strValue, fieldValueElem)
- if err != nil {
- return err
- }
- case reflect.Int64:
- err := reflectutils.AssignInt64Value(tableRowValue, fieldValueElem)
- if err != nil {
- return err
- }
- case reflect.Uint64:
- err := reflectutils.AssignUint64Value(tableRowValue, fieldValueElem)
- if err != nil {
- return err
- }
- case reflect.Float64:
- err := reflectutils.AssignFloat64Value(tableRowValue, fieldValueElem)
- if err != nil {
- return err
- }
- case reflect.Struct:
- if fieldValueElem.Type() == reflect.TypeOf(time.Time{}) {
- parsedTime, err := sdk.ParseSqlResultTimeStr(tableRowValue.(string))
- if err != nil {
- return err
- }
- fieldValueElem.Set(reflect.ValueOf(parsedTime))
- continue
- }
- return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
- fieldName, element.Name, fieldTypeElem.String())
- case reflect.Slice:
- if fieldTypeElem.Elem().Kind() != reflect.String {
- return errors.New("slice仅支持[]string")
- }
- strValue, ok := tableRowValue.(string)
- if !ok {
- return errors.New("slice仅支持[]string")
- }
- strParts := strings.Split(strValue, element.SplitWith)
- if strParts == nil || len(strParts) == 0 {
- return nil
- }
- valSlice := fieldValueElem
- if valSlice.IsNil() {
- valSlice = reflect.MakeSlice(fieldTypeElem, 0, 0)
- }
- for _, strPart := range strParts {
- valSlice = reflect.Append(valSlice, reflect.ValueOf(strPart))
- }
- fieldValueElem.Set(valSlice)
- default:
- return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
- fieldName, element.Name, fieldTypeElem.String())
- }
- default:
- return errors.New("不支持的元素类型")
- }
- }
- return nil
- }
|