sql_result.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package sql
  2. import (
  3. "errors"
  4. "git.sxidc.com/go-tools/utils/strutils"
  5. "github.com/iancoleman/strcase"
  6. "reflect"
  7. "strings"
  8. "time"
  9. )
  10. const (
  11. sqlResultDefaultSplitWith = "::"
  12. sqlResultTagPartSeparator = ";"
  13. sqlResultTagPartKeyValueSeparator = ":"
  14. )
  15. const (
  16. sqlResultTagKey = "sqlresult"
  17. sqlResultIgnore = "-"
  18. sqlResultColumn = "column"
  19. sqlResultParseTime = "parseTime"
  20. sqlResultAes = "aes"
  21. sqlResultSplitWith = "splitWith"
  22. )
  23. type Result struct {
  24. ResultElement map[string]any
  25. }
  26. func ParseSqlResultTag(e any) (*Result, error) {
  27. if e == nil {
  28. return nil, errors.New("没有传递实体")
  29. }
  30. entityType := reflect.TypeOf(e)
  31. if entityType.Kind() == reflect.Ptr {
  32. entityType = entityType.Elem()
  33. }
  34. if entityType.Kind() != reflect.Struct {
  35. return nil, errors.New("传递的实体不是结构类型")
  36. }
  37. entityValue := reflect.ValueOf(e)
  38. if entityValue.Kind() == reflect.Ptr {
  39. entityValue = entityValue.Elem()
  40. }
  41. sqlResult := new(Result)
  42. sqlResult.ResultElement = make(map[string]any)
  43. fieldNum := entityType.NumField()
  44. for i := 0; i < fieldNum; i++ {
  45. field := entityType.Field(i)
  46. fieldValue := entityValue.Field(i)
  47. element, err := parseSqlResultElement(field, fieldValue)
  48. if err != nil {
  49. return nil, err
  50. }
  51. if element == nil {
  52. continue
  53. }
  54. sqlResult.ResultElement[field.Name] = element
  55. }
  56. return sqlResult, nil
  57. }
  58. type ResultStruct struct {
  59. ResultTypesAndValues
  60. }
  61. type ResultColumn struct {
  62. Name string
  63. ParseTime string
  64. AESKey string
  65. SplitWith string
  66. ResultTypesAndValues
  67. }
  68. type ResultTypesAndValues struct {
  69. // 原字段的反射结构
  70. OriginFieldType reflect.Type
  71. OriginFieldValue reflect.Value
  72. // 值类型的反射结构
  73. FieldTypeElem reflect.Type
  74. FieldValueElem reflect.Value
  75. }
  76. func parseSqlResultElement(field reflect.StructField, fieldValue reflect.Value) (any, error) {
  77. sqlResultTag := field.Tag.Get(sqlResultTagKey)
  78. if sqlResultTag == sqlResultIgnore {
  79. return nil, nil
  80. }
  81. fieldValueTypeElem := field.Type
  82. if field.Type.Kind() == reflect.Ptr {
  83. fieldValueTypeElem = field.Type.Elem()
  84. }
  85. fieldValueElem := fieldValue
  86. if fieldValue.Kind() == reflect.Ptr {
  87. if !fieldValue.IsValid() || fieldValue.IsNil() {
  88. if !fieldValue.CanSet() {
  89. return nil, nil
  90. }
  91. fieldValue.Set(reflect.New(fieldValueTypeElem).Elem().Addr())
  92. }
  93. fieldValueElem = fieldValue.Elem()
  94. }
  95. if fieldValueTypeElem.Kind() == reflect.Struct && fieldValueTypeElem != reflect.TypeOf(time.Time{}) {
  96. return &ResultStruct{
  97. ResultTypesAndValues: ResultTypesAndValues{
  98. OriginFieldType: field.Type,
  99. OriginFieldValue: fieldValue,
  100. FieldTypeElem: fieldValueTypeElem,
  101. FieldValueElem: fieldValueElem,
  102. },
  103. }, nil
  104. }
  105. sqlColumn := &ResultColumn{
  106. Name: strcase.ToSnake(field.Name),
  107. ParseTime: "",
  108. AESKey: "",
  109. SplitWith: sqlResultDefaultSplitWith,
  110. ResultTypesAndValues: ResultTypesAndValues{
  111. OriginFieldType: field.Type,
  112. OriginFieldValue: fieldValue,
  113. FieldTypeElem: fieldValueTypeElem,
  114. FieldValueElem: fieldValueElem,
  115. },
  116. }
  117. if strutils.IsStringEmpty(sqlResultTag) {
  118. return sqlColumn, nil
  119. }
  120. sqlResultParts := strings.Split(sqlResultTag, sqlResultTagPartSeparator)
  121. if sqlResultParts != nil || len(sqlResultParts) != 0 {
  122. for _, sqlResultPart := range sqlResultParts {
  123. sqlPartKeyValue := strings.SplitN(strings.TrimSpace(sqlResultPart), sqlResultTagPartKeyValueSeparator, 2)
  124. if sqlPartKeyValue != nil && len(sqlPartKeyValue) == 2 && strutils.IsStringNotEmpty(sqlPartKeyValue[1]) {
  125. sqlPartKeyValue[1] = strings.Trim(sqlPartKeyValue[1], "'")
  126. }
  127. switch sqlPartKeyValue[0] {
  128. case sqlResultColumn:
  129. sqlColumn.Name = sqlPartKeyValue[1]
  130. case sqlResultParseTime:
  131. sqlColumn.ParseTime = sqlPartKeyValue[1]
  132. case sqlResultAes:
  133. if len(sqlPartKeyValue[1]) != 32 {
  134. return nil, errors.New("AES密钥长度应该为32个字节")
  135. }
  136. sqlColumn.AESKey = sqlPartKeyValue[1]
  137. case sqlResultSplitWith:
  138. if strutils.IsStringEmpty(sqlPartKeyValue[1]) {
  139. return nil, errors.New(sqlResultDefaultSplitWith + "没有赋值分隔符")
  140. }
  141. if fieldValueTypeElem.Kind() != reflect.Slice || fieldValueTypeElem.Elem().Kind() != reflect.String {
  142. return nil, errors.New(sqlResultDefaultSplitWith + "应该添加在[]string字段上")
  143. }
  144. sqlColumn.SplitWith = sqlPartKeyValue[1]
  145. default:
  146. continue
  147. }
  148. }
  149. }
  150. return sqlColumn, nil
  151. }