column.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package core
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. "time"
  7. )
  8. const (
  9. TWOSIDES = iota + 1
  10. ONLYTODB
  11. ONLYFROMDB
  12. )
  13. // database column
  14. type Column struct {
  15. Name string
  16. FieldName string
  17. SQLType SQLType
  18. Length int
  19. Length2 int
  20. Nullable bool
  21. Default string
  22. Indexes map[string]bool
  23. IsPrimaryKey bool
  24. IsAutoIncrement bool
  25. MapType int
  26. IsCreated bool
  27. IsUpdated bool
  28. IsDeleted bool
  29. IsCascade bool
  30. IsVersion bool
  31. fieldPath []string
  32. DefaultIsEmpty bool
  33. EnumOptions map[string]int
  34. SetOptions map[string]int
  35. DisableTimeZone bool
  36. TimeZone *time.Location // column specified time zone
  37. }
  38. func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
  39. return &Column{
  40. Name: name,
  41. FieldName: fieldName,
  42. SQLType: sqlType,
  43. Length: len1,
  44. Length2: len2,
  45. Nullable: nullable,
  46. Default: "",
  47. Indexes: make(map[string]bool),
  48. IsPrimaryKey: false,
  49. IsAutoIncrement: false,
  50. MapType: TWOSIDES,
  51. IsCreated: false,
  52. IsUpdated: false,
  53. IsDeleted: false,
  54. IsCascade: false,
  55. IsVersion: false,
  56. fieldPath: nil,
  57. DefaultIsEmpty: false,
  58. EnumOptions: make(map[string]int),
  59. }
  60. }
  61. // generate column description string according dialect
  62. func (col *Column) String(d Dialect) string {
  63. sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
  64. sql += d.SqlType(col) + " "
  65. if col.IsPrimaryKey {
  66. sql += "PRIMARY KEY "
  67. if col.IsAutoIncrement {
  68. sql += d.AutoIncrStr() + " "
  69. }
  70. }
  71. if d.ShowCreateNull() {
  72. if col.Nullable {
  73. sql += "NULL "
  74. } else {
  75. sql += "NOT NULL "
  76. }
  77. }
  78. if col.Default != "" {
  79. sql += "DEFAULT " + col.Default + " "
  80. }
  81. return sql
  82. }
  83. func (col *Column) StringNoPk(d Dialect) string {
  84. sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
  85. sql += d.SqlType(col) + " "
  86. if d.ShowCreateNull() {
  87. if col.Nullable {
  88. sql += "NULL "
  89. } else {
  90. sql += "NOT NULL "
  91. }
  92. }
  93. if col.Default != "" {
  94. sql += "DEFAULT " + col.Default + " "
  95. }
  96. return sql
  97. }
  98. // return col's filed of struct's value
  99. func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
  100. dataStruct := reflect.Indirect(reflect.ValueOf(bean))
  101. return col.ValueOfV(&dataStruct)
  102. }
  103. func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
  104. var fieldValue reflect.Value
  105. if col.fieldPath == nil {
  106. col.fieldPath = strings.Split(col.FieldName, ".")
  107. }
  108. if dataStruct.Type().Kind() == reflect.Map {
  109. keyValue := reflect.ValueOf(col.fieldPath[len(col.fieldPath)-1])
  110. fieldValue = dataStruct.MapIndex(keyValue)
  111. return &fieldValue, nil
  112. } else if dataStruct.Type().Kind() == reflect.Interface {
  113. structValue := reflect.ValueOf(dataStruct.Interface())
  114. dataStruct = &structValue
  115. }
  116. level := len(col.fieldPath)
  117. fieldValue = dataStruct.FieldByName(col.fieldPath[0])
  118. for i := 0; i < level-1; i++ {
  119. if !fieldValue.IsValid() {
  120. break
  121. }
  122. if fieldValue.Kind() == reflect.Struct {
  123. fieldValue = fieldValue.FieldByName(col.fieldPath[i+1])
  124. } else if fieldValue.Kind() == reflect.Ptr {
  125. if fieldValue.IsNil() {
  126. fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
  127. }
  128. fieldValue = fieldValue.Elem().FieldByName(col.fieldPath[i+1])
  129. } else {
  130. return nil, fmt.Errorf("field %v is not valid", col.FieldName)
  131. }
  132. }
  133. if !fieldValue.IsValid() {
  134. return nil, fmt.Errorf("field %v is not valid", col.FieldName)
  135. }
  136. return &fieldValue, nil
  137. }