field.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package schema
  2. import (
  3. "database/sql/driver"
  4. "reflect"
  5. "strconv"
  6. "sync"
  7. "time"
  8. )
  9. type DataType string
  10. const (
  11. Bool DataType = "bool"
  12. Int = "int"
  13. Uint = "uint"
  14. Float = "float"
  15. String = "string"
  16. Time = "time"
  17. Bytes = "bytes"
  18. )
  19. type Field struct {
  20. Name string
  21. DBName string
  22. BindNames []string
  23. DataType DataType
  24. DBDataType string
  25. PrimaryKey bool
  26. AutoIncrement bool
  27. Creatable bool
  28. Updatable bool
  29. HasDefaultValue bool
  30. DefaultValue string
  31. NotNull bool
  32. Unique bool
  33. Comment string
  34. Size int
  35. Precision int
  36. FieldType reflect.Type
  37. StructField reflect.StructField
  38. Tag reflect.StructTag
  39. TagSettings map[string]string
  40. Schema *Schema
  41. EmbeddedSchema *Schema
  42. }
  43. func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
  44. field := &Field{
  45. Name: fieldStruct.Name,
  46. BindNames: []string{fieldStruct.Name},
  47. FieldType: fieldStruct.Type,
  48. StructField: fieldStruct,
  49. Creatable: true,
  50. Updatable: true,
  51. Tag: fieldStruct.Tag,
  52. TagSettings: parseTagSetting(fieldStruct.Tag),
  53. }
  54. for field.FieldType.Kind() == reflect.Ptr {
  55. field.FieldType = field.FieldType.Elem()
  56. }
  57. fieldValue := reflect.New(field.FieldType)
  58. // if field is valuer, used its value or first fields as data type
  59. if valuer, isValuer := fieldValue.Interface().(driver.Valuer); isValuer {
  60. var overrideFieldValue bool
  61. if v, err := valuer.Value(); v != nil && err == nil {
  62. overrideFieldValue = true
  63. fieldValue = reflect.ValueOf(v)
  64. }
  65. if field.FieldType.Kind() == reflect.Struct {
  66. for i := 0; i < field.FieldType.NumField(); i++ {
  67. if !overrideFieldValue {
  68. newFieldType := field.FieldType.Field(i).Type
  69. for newFieldType.Kind() == reflect.Ptr {
  70. newFieldType = newFieldType.Elem()
  71. }
  72. fieldValue = reflect.New(newFieldType)
  73. overrideFieldValue = true
  74. }
  75. // copy tag settings from valuer
  76. for key, value := range parseTagSetting(field.FieldType.Field(i).Tag) {
  77. if _, ok := field.TagSettings[key]; !ok {
  78. field.TagSettings[key] = value
  79. }
  80. }
  81. }
  82. }
  83. }
  84. // setup permission
  85. if _, ok := field.TagSettings["-"]; ok {
  86. field.Creatable = false
  87. field.Updatable = false
  88. }
  89. if dbName, ok := field.TagSettings["COLUMN"]; ok {
  90. field.DBName = dbName
  91. }
  92. if val, ok := field.TagSettings["PRIMARYKEY"]; ok && checkTruth(val) {
  93. field.PrimaryKey = true
  94. }
  95. if val, ok := field.TagSettings["AUTOINCREMENT"]; ok && checkTruth(val) {
  96. field.AutoIncrement = true
  97. field.HasDefaultValue = true
  98. }
  99. if v, ok := field.TagSettings["DEFAULT"]; ok {
  100. field.HasDefaultValue = true
  101. field.DefaultValue = v
  102. }
  103. if num, ok := field.TagSettings["SIZE"]; ok {
  104. field.Size, _ = strconv.Atoi(num)
  105. }
  106. if p, ok := field.TagSettings["PRECISION"]; ok {
  107. field.Precision, _ = strconv.Atoi(p)
  108. }
  109. if val, ok := field.TagSettings["NOT NULL"]; ok && checkTruth(val) {
  110. field.NotNull = true
  111. }
  112. if val, ok := field.TagSettings["UNIQUE"]; ok && checkTruth(val) {
  113. field.Unique = true
  114. }
  115. if val, ok := field.TagSettings["COMMENT"]; ok {
  116. field.Comment = val
  117. }
  118. if val, ok := field.TagSettings["TYPE"]; ok {
  119. field.DBDataType = val
  120. }
  121. switch fieldValue.Kind() {
  122. case reflect.Bool:
  123. field.DataType = Bool
  124. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  125. field.DataType = Int
  126. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  127. field.DataType = Uint
  128. case reflect.Float32, reflect.Float64:
  129. field.DataType = Float
  130. case reflect.String:
  131. field.DataType = String
  132. case reflect.Struct:
  133. if _, ok := fieldValue.Interface().(time.Time); ok {
  134. field.DataType = Time
  135. }
  136. case reflect.Array, reflect.Slice:
  137. if fieldValue.Type().Elem() == reflect.TypeOf(uint8(0)) {
  138. field.DataType = Bytes
  139. }
  140. }
  141. if field.Size == 0 {
  142. switch fieldValue.Kind() {
  143. case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64, reflect.Float64:
  144. field.Size = 64
  145. case reflect.Int8, reflect.Uint8:
  146. field.Size = 8
  147. case reflect.Int16, reflect.Uint16:
  148. field.Size = 16
  149. case reflect.Int32, reflect.Uint32, reflect.Float32:
  150. field.Size = 32
  151. }
  152. }
  153. if _, ok := field.TagSettings["EMBEDDED"]; ok || fieldStruct.Anonymous {
  154. field.EmbeddedSchema, schema.err = Parse(fieldValue, sync.Map{}, schema.namer)
  155. for _, ef := range field.EmbeddedSchema.Fields {
  156. ef.BindNames = append([]string{fieldStruct.Name}, ef.BindNames...)
  157. if prefix, ok := field.TagSettings["EMBEDDEDPREFIX"]; ok {
  158. ef.DBName = prefix + ef.DBName
  159. }
  160. for k, v := range field.TagSettings {
  161. ef.TagSettings[k] = v
  162. }
  163. }
  164. }
  165. return field
  166. }