parse_table_row.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package sql
  2. import (
  3. "errors"
  4. "fmt"
  5. "git.sxidc.com/go-tools/utils/encoding"
  6. "git.sxidc.com/go-tools/utils/reflectutils"
  7. "git.sxidc.com/go-tools/utils/strutils"
  8. "reflect"
  9. "strings"
  10. "time"
  11. )
  12. const (
  13. sqlResultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00"
  14. sqlResultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00"
  15. sqlResultTimeSecFormat = "2006-01-02T15:04:05+08:00"
  16. )
  17. func parseSqlTableRowTimeStr(timeStr string) (time.Time, error) {
  18. var layout string
  19. if strings.HasSuffix(timeStr, ".000000+08:00") {
  20. layout = sqlResultTimeMicroFormat
  21. } else if strings.HasSuffix(timeStr, ".000+08:00") {
  22. layout = sqlResultTimeMilliFormat
  23. } else {
  24. layout = sqlResultTimeSecFormat
  25. }
  26. return time.ParseInLocation(layout, timeStr, time.Local)
  27. }
  28. func ParseSqlTableRow(input any, output any) error {
  29. if input == nil || output == nil {
  30. return nil
  31. }
  32. outputType := reflect.TypeOf(output)
  33. if outputType.Kind() != reflect.Ptr {
  34. return errors.New("输出实体应该为结构的slice或者是结构的指针")
  35. }
  36. if outputType.Kind() == reflect.Ptr {
  37. outputType = outputType.Elem()
  38. }
  39. if outputType.Kind() != reflect.Slice && outputType.Kind() != reflect.Struct {
  40. return errors.New("输出实体应该为结构的slice或者是结构的指针")
  41. }
  42. outputElemType := outputType
  43. if outputType.Kind() == reflect.Slice {
  44. outputElemType = outputType.Elem()
  45. }
  46. fmt.Println(outputElemType.String())
  47. tableRows, ok := input.([]map[string]any)
  48. if !ok {
  49. tableRow, ok := input.(map[string]any)
  50. if !ok {
  51. return errors.New("输入数据应该为[]map[string]any或[]map[string]any")
  52. }
  53. tableRows = []map[string]any{tableRow}
  54. }
  55. outputEntities := reflect.MakeSlice(reflect.SliceOf(outputElemType), 0, 0)
  56. for _, tableRow := range tableRows {
  57. outputEntityValue := reflect.New(outputElemType).Elem().Addr()
  58. outputEntity := outputEntityValue.Interface()
  59. sqlResult, err := ParseSqlResult(outputEntity)
  60. if err != nil {
  61. return err
  62. }
  63. for fieldName, sqlColumn := range sqlResult.ColumnMap {
  64. tableRowValue, ok := tableRow[sqlColumn.Name]
  65. if !ok {
  66. continue
  67. }
  68. fieldValue := sqlColumn.OriginFieldValue
  69. if fieldValue.Type().Kind() == reflect.Ptr {
  70. if fieldValue.IsValid() {
  71. fieldValue.Set(reflect.New(sqlColumn.FieldTypeElem))
  72. }
  73. fieldValue = fieldValue.Elem()
  74. }
  75. outputKind := reflectutils.GroupValueKind(fieldValue)
  76. switch outputKind {
  77. case reflect.Bool:
  78. err := reflectutils.AssignBoolValue(tableRowValue, fieldValue)
  79. if err != nil {
  80. return err
  81. }
  82. case reflect.String:
  83. strValue := tableRowValue.(string)
  84. if strutils.IsStringNotEmpty(sqlColumn.ParseTime) {
  85. parsedTime, err := parseSqlTableRowTimeStr(strValue)
  86. if err != nil {
  87. return err
  88. }
  89. tableRowValue = parsedTime.Format(sqlColumn.ParseTime)
  90. } else if strutils.IsStringNotEmpty(sqlColumn.AESKey) {
  91. decryptedValue, err := encoding.AESDecrypt(strValue, sqlColumn.AESKey)
  92. if err != nil {
  93. return err
  94. }
  95. strValue = decryptedValue
  96. }
  97. err = reflectutils.AssignStringValue(strValue, fieldValue)
  98. if err != nil {
  99. return err
  100. }
  101. case reflect.Int64:
  102. err := reflectutils.AssignIntValue(tableRowValue, fieldValue)
  103. if err != nil {
  104. return err
  105. }
  106. case reflect.Uint64:
  107. err := reflectutils.AssignUintValue(tableRowValue, fieldValue)
  108. if err != nil {
  109. return err
  110. }
  111. case reflect.Float64:
  112. err := reflectutils.AssignFloatValue(tableRowValue, fieldValue)
  113. if err != nil {
  114. return err
  115. }
  116. case reflect.Struct:
  117. if fieldValue.Type() == reflect.TypeOf(time.Time{}) {
  118. parsedTime, err := parseSqlTableRowTimeStr(tableRowValue.(string))
  119. if err != nil {
  120. return err
  121. }
  122. fieldValue.Set(reflect.ValueOf(parsedTime))
  123. continue
  124. }
  125. return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
  126. fieldName, sqlColumn.Name, reflect.TypeOf(tableRowValue).String())
  127. default:
  128. return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
  129. fieldName, sqlColumn.Name, reflect.TypeOf(tableRowValue).String())
  130. }
  131. }
  132. outputEntities = reflect.Append(outputEntities, outputEntityValue.Elem())
  133. }
  134. outputValue := reflect.Indirect(reflect.ValueOf(output))
  135. if outputType.Kind() == reflect.Slice {
  136. outputValue.Set(outputEntities)
  137. } else {
  138. fmt.Println(outputValue.Type().String())
  139. outputValue.Set(outputEntities.Index(0))
  140. }
  141. return nil
  142. }