data_mapping.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package data_mapping
  2. import (
  3. "errors"
  4. "github.com/iancoleman/strcase"
  5. "reflect"
  6. "strings"
  7. )
  8. type DataMapping struct {
  9. Name string
  10. SqlMapping *SqlMapping
  11. }
  12. func ParseDataMapping(e any) (*DataMapping, error) {
  13. if e == nil {
  14. return nil, errors.New("没有传递实体")
  15. }
  16. entityType := reflect.TypeOf(e)
  17. if entityType.Kind() == reflect.Ptr {
  18. entityType = entityType.Elem()
  19. }
  20. if entityType.Kind() != reflect.Struct {
  21. return nil, errors.New("传递的不是实体结构")
  22. }
  23. sqlMapping, err := parseSqlMapping(entityType)
  24. if err != nil {
  25. return nil, err
  26. }
  27. return &DataMapping{
  28. Name: entityType.String(),
  29. SqlMapping: sqlMapping,
  30. }, nil
  31. }
  32. const (
  33. sqlMappingTagPartSeparator = ";"
  34. sqlMappingTagPartKeyValueSeparator = ":"
  35. )
  36. const (
  37. sqlMappingTagKey = "sqlmapping"
  38. sqlMappingIgnore = "-"
  39. sqlMappingColumn = "column"
  40. sqlMappingKey = "key"
  41. sqlMappingNotUpdate = "notUpdate"
  42. sqlMappingUpdateClear = "updateClear"
  43. sqlMappingNotQuery = "notQuery"
  44. sqlMappingQueryConditionCallback = "queryConditionCallback"
  45. )
  46. type SqlMapping struct {
  47. ColumnMap map[string]SqlColumn
  48. }
  49. func parseSqlMapping(entityType reflect.Type) (*SqlMapping, error) {
  50. sqlMapping := new(SqlMapping)
  51. sqlMapping.ColumnMap = make(map[string]SqlColumn)
  52. fieldNum := entityType.NumField()
  53. for i := 0; i < fieldNum; i++ {
  54. sqlColumn, err := parseSqlColumn(entityType.Field(i))
  55. if err != nil {
  56. return nil, err
  57. }
  58. if sqlColumn == nil {
  59. continue
  60. }
  61. sqlMapping.ColumnMap[sqlColumn.Name] = *sqlColumn
  62. }
  63. return sqlMapping, nil
  64. }
  65. type SqlColumn struct {
  66. Name string
  67. IsKey bool
  68. CanUpdate bool
  69. CanUpdateClear bool
  70. CanQuery bool
  71. NeedQueryConditionCallback bool
  72. }
  73. func parseSqlColumn(field reflect.StructField) (*SqlColumn, error) {
  74. sqlColumn := &SqlColumn{
  75. Name: strcase.ToSnake(field.Name),
  76. IsKey: false,
  77. CanUpdate: true,
  78. CanUpdateClear: false,
  79. CanQuery: true,
  80. NeedQueryConditionCallback: false,
  81. }
  82. sqlMappingTag, ok := field.Tag.Lookup(sqlMappingTagKey)
  83. if !ok {
  84. return sqlColumn, nil
  85. }
  86. if sqlMappingTag == sqlMappingIgnore {
  87. return nil, nil
  88. }
  89. sqlMappingParts := strings.Split(sqlMappingTag, sqlMappingTagPartSeparator)
  90. if sqlMappingParts != nil || len(sqlMappingParts) != 0 {
  91. for _, sqlMappingPart := range sqlMappingParts {
  92. sqlPartKeyValue := strings.Split(strings.TrimSpace(sqlMappingPart), sqlMappingTagPartKeyValueSeparator)
  93. switch sqlPartKeyValue[0] {
  94. case sqlMappingColumn:
  95. sqlColumn.Name = strings.TrimSpace(sqlPartKeyValue[1])
  96. case sqlMappingKey:
  97. sqlColumn.IsKey = true
  98. sqlColumn.CanUpdate = false
  99. case sqlMappingNotUpdate:
  100. sqlColumn.CanUpdate = false
  101. case sqlMappingUpdateClear:
  102. sqlColumn.CanUpdateClear = true
  103. case sqlMappingNotQuery:
  104. sqlColumn.CanQuery = false
  105. case sqlMappingQueryConditionCallback:
  106. sqlColumn.NeedQueryConditionCallback = true
  107. default:
  108. continue
  109. }
  110. }
  111. }
  112. return sqlColumn, nil
  113. }