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