123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- 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[T any](input any) (T, error) {
- var zero T
- if input == nil {
- return zero, nil
- }
-
- tableRows, ok := input.([]sdk.SqlResult)
- if !ok {
- tableRow, ok := input.(sdk.SqlResult)
- if !ok {
- return zero, errors.New("输入数据应该为sdk.SqlResult或[]sdk.SqlResult")
- }
- tableRows = []sdk.SqlResult{tableRow}
- }
-
- typeCheckErr := errors.New("可以接受的类型为struct, *struct, []struct, []*struct")
- outputType := reflect.TypeOf(zero)
- fmt.Println("Output Type:", outputType.String())
- if outputType.Kind() != reflect.Struct && outputType.Kind() != reflect.Ptr && outputType.Kind() != reflect.Slice {
- return zero, typeCheckErr
- } else if outputType.Kind() == reflect.Ptr && outputType.Elem().Kind() != reflect.Struct {
- return zero, typeCheckErr
- } else if outputType.Kind() == reflect.Slice &&
- (outputType.Elem().Kind() != reflect.Struct && outputType.Elem().Kind() != reflect.Ptr) {
- return zero, typeCheckErr
- } else if outputType.Kind() == reflect.Slice &&
- outputType.Elem().Kind() == reflect.Ptr && outputType.Elem().Elem().Kind() != reflect.Struct {
- return zero, typeCheckErr
- }
- var outputValue reflect.Value
- if outputType.Kind() == reflect.Struct || outputType.Kind() == reflect.Ptr {
- outputValue = reflect.New(outputType).Elem()
- } else {
- outputValue = reflect.MakeSlice(outputType, 0, 0)
- }
- for _, tableRow := range tableRows {
-
- var outputEntity any
- if outputType.Kind() == reflect.Struct {
- outputEntity = outputValue.Addr().Interface()
- } else if outputType.Kind() == reflect.Ptr {
- outputEntity = reflect.New(outputType.Elem()).Interface()
- } else {
- if outputType.Elem().Kind() == reflect.Struct {
- outputEntity = reflect.New(outputType.Elem()).Interface()
- } else {
- outputValueElemPtr := reflect.New(outputType.Elem()).Elem()
- outputValueElemPtr.Set(reflect.New(outputType.Elem().Elem()))
- outputEntity = outputValueElemPtr.Interface()
- }
- }
- sqlResult, err := ParseSqlResultTag(outputEntity)
- if err != nil {
- return zero, err
- }
- err = formOutputEntity(tableRow, sqlResult)
- if err != nil {
- return zero, err
- }
- if outputType.Kind() == reflect.Ptr {
- outputValue = reflect.ValueOf(outputEntity)
- } else if outputType.Kind() == reflect.Slice {
- if outputType.Elem().Kind() == reflect.Struct {
- outputValue = reflect.Append(outputValue, reflect.ValueOf(outputEntity).Elem())
- } else {
- outputValue = reflect.Append(outputValue, reflect.ValueOf(outputEntity))
- }
- }
- }
- output, ok := outputValue.Interface().(T)
- if !ok {
- return zero, errors.New("输出类型不匹配")
- }
- return output, 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
- }
|