column.go 3.5 KB

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