sql_result.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package sql
  2. import (
  3. "errors"
  4. "github.com/iancoleman/strcase"
  5. "reflect"
  6. "strings"
  7. )
  8. const (
  9. sqlResultTagPartSeparator = ";"
  10. sqlResultTagPartKeyValueSeparator = ":"
  11. )
  12. const (
  13. sqlResultTagKey = "sqlresult"
  14. sqlResultIgnore = "-"
  15. sqlResultColumn = "column"
  16. sqlResultParseTime = "parseTime"
  17. sqlResultAes = "aes"
  18. )
  19. type Result struct {
  20. ColumnMap map[string]ResultColumn
  21. }
  22. func ParseSqlResult(e any) (*Result, error) {
  23. if e == nil {
  24. return nil, errors.New("没有传递实体")
  25. }
  26. entityType := reflect.TypeOf(e)
  27. if entityType.Kind() == reflect.Ptr {
  28. entityType = entityType.Elem()
  29. }
  30. if entityType.Kind() != reflect.Struct {
  31. return nil, errors.New("传递的实体不是结构类型")
  32. }
  33. entityValue := reflect.ValueOf(e)
  34. if entityValue.Kind() == reflect.Ptr {
  35. entityValue = entityValue.Elem()
  36. }
  37. sqlResult := new(Result)
  38. sqlResult.ColumnMap = make(map[string]ResultColumn)
  39. fieldNum := entityType.NumField()
  40. for i := 0; i < fieldNum; i++ {
  41. field := entityType.Field(i)
  42. fieldValue := entityValue.Field(i)
  43. column, err := parseSqlResultColumn(field, fieldValue)
  44. if err != nil {
  45. return nil, err
  46. }
  47. if column == nil {
  48. continue
  49. }
  50. sqlResult.ColumnMap[field.Name] = *column
  51. }
  52. return sqlResult, nil
  53. }
  54. type ResultColumn struct {
  55. Name string
  56. ParseTime string
  57. AESKey string
  58. // 原字段的反射结构
  59. OriginFieldType reflect.Type
  60. OriginFieldValue reflect.Value
  61. // 值类型的反射结构
  62. FieldTypeElem reflect.Type
  63. FieldValueElem reflect.Value
  64. }
  65. func parseSqlResultColumn(field reflect.StructField, fieldValue reflect.Value) (*ResultColumn, error) {
  66. valueFieldType := field.Type
  67. valueFieldValue := fieldValue
  68. if valueFieldType.Kind() == reflect.Ptr {
  69. valueFieldType = valueFieldType.Elem()
  70. if !valueFieldValue.IsValid() || valueFieldValue.IsNil() || valueFieldValue.IsZero() {
  71. valueFieldValue = reflect.Zero(valueFieldType)
  72. } else {
  73. valueFieldValue = fieldValue.Elem()
  74. }
  75. }
  76. sqlColumn := &ResultColumn{
  77. Name: strcase.ToSnake(field.Name),
  78. ParseTime: "",
  79. AESKey: "",
  80. OriginFieldType: field.Type,
  81. OriginFieldValue: fieldValue,
  82. FieldTypeElem: valueFieldType,
  83. FieldValueElem: valueFieldValue,
  84. }
  85. sqlResultTag, ok := field.Tag.Lookup(sqlResultTagKey)
  86. if !ok {
  87. return sqlColumn, nil
  88. }
  89. if sqlResultTag == sqlResultIgnore {
  90. return nil, nil
  91. }
  92. sqlResultParts := strings.Split(sqlResultTag, sqlResultTagPartSeparator)
  93. if sqlResultParts != nil || len(sqlResultParts) != 0 {
  94. for _, sqlResultPart := range sqlResultParts {
  95. sqlPartKeyValue := strings.SplitN(strings.TrimSpace(sqlResultPart), sqlResultTagPartKeyValueSeparator, 2)
  96. switch sqlPartKeyValue[0] {
  97. case sqlResultColumn:
  98. sqlColumn.Name = strings.TrimSpace(sqlPartKeyValue[1])
  99. case sqlResultParseTime:
  100. sqlColumn.ParseTime = strings.TrimSpace(sqlPartKeyValue[1])
  101. case sqlResultAes:
  102. if len(strings.TrimSpace(sqlPartKeyValue[1])) != 32 {
  103. return nil, errors.New("AES密钥长度应该为32个字节")
  104. }
  105. sqlColumn.AESKey = strings.TrimSpace(sqlPartKeyValue[1])
  106. default:
  107. continue
  108. }
  109. }
  110. }
  111. return sqlColumn, nil
  112. }