You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

table.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2019 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package schemas
  5. import (
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. )
  11. // Table represents a database table
  12. type Table struct {
  13. Name string
  14. Type reflect.Type
  15. columnsSeq []string
  16. columnsMap map[string][]*Column
  17. columns []*Column
  18. Indexes map[string]*Index
  19. PrimaryKeys []string
  20. AutoIncrement string
  21. Created map[string]bool
  22. Updated string
  23. Deleted string
  24. Version string
  25. StoreEngine string
  26. Charset string
  27. Comment string
  28. }
  29. // NewEmptyTable creates an empty table
  30. func NewEmptyTable() *Table {
  31. return NewTable("", nil)
  32. }
  33. // NewTable creates a new Table object
  34. func NewTable(name string, t reflect.Type) *Table {
  35. return &Table{Name: name, Type: t,
  36. columnsSeq: make([]string, 0),
  37. columns: make([]*Column, 0),
  38. columnsMap: make(map[string][]*Column),
  39. Indexes: make(map[string]*Index),
  40. Created: make(map[string]bool),
  41. PrimaryKeys: make([]string, 0),
  42. }
  43. }
  44. // Columns returns table's columns
  45. func (table *Table) Columns() []*Column {
  46. return table.columns
  47. }
  48. // ColumnsSeq returns table's column names according sequence
  49. func (table *Table) ColumnsSeq() []string {
  50. return table.columnsSeq
  51. }
  52. func (table *Table) columnsByName(name string) []*Column {
  53. for k, cols := range table.columnsMap {
  54. if strings.EqualFold(k, name) {
  55. return cols
  56. }
  57. }
  58. return nil
  59. }
  60. // GetColumn returns column according column name, if column not found, return nil
  61. func (table *Table) GetColumn(name string) *Column {
  62. cols := table.columnsByName(name)
  63. if cols != nil {
  64. return cols[0]
  65. }
  66. return nil
  67. }
  68. // GetColumnIdx returns column according name and idx
  69. func (table *Table) GetColumnIdx(name string, idx int) *Column {
  70. cols := table.columnsByName(name)
  71. if cols != nil && idx < len(cols) {
  72. return cols[idx]
  73. }
  74. return nil
  75. }
  76. // PKColumns reprents all primary key columns
  77. func (table *Table) PKColumns() []*Column {
  78. columns := make([]*Column, len(table.PrimaryKeys))
  79. for i, name := range table.PrimaryKeys {
  80. columns[i] = table.GetColumn(name)
  81. }
  82. return columns
  83. }
  84. func (table *Table) ColumnType(name string) reflect.Type {
  85. t, _ := table.Type.FieldByName(name)
  86. return t.Type
  87. }
  88. func (table *Table) AutoIncrColumn() *Column {
  89. return table.GetColumn(table.AutoIncrement)
  90. }
  91. func (table *Table) VersionColumn() *Column {
  92. return table.GetColumn(table.Version)
  93. }
  94. func (table *Table) UpdatedColumn() *Column {
  95. return table.GetColumn(table.Updated)
  96. }
  97. func (table *Table) DeletedColumn() *Column {
  98. return table.GetColumn(table.Deleted)
  99. }
  100. // AddColumn adds a column to table
  101. func (table *Table) AddColumn(col *Column) {
  102. table.columnsSeq = append(table.columnsSeq, col.Name)
  103. table.columns = append(table.columns, col)
  104. colName := strings.ToLower(col.Name)
  105. if c, ok := table.columnsMap[colName]; ok {
  106. table.columnsMap[colName] = append(c, col)
  107. } else {
  108. table.columnsMap[colName] = []*Column{col}
  109. }
  110. if col.IsPrimaryKey {
  111. table.PrimaryKeys = append(table.PrimaryKeys, col.Name)
  112. }
  113. if col.IsAutoIncrement {
  114. table.AutoIncrement = col.Name
  115. }
  116. if col.IsCreated {
  117. table.Created[col.Name] = true
  118. }
  119. if col.IsUpdated {
  120. table.Updated = col.Name
  121. }
  122. if col.IsDeleted {
  123. table.Deleted = col.Name
  124. }
  125. if col.IsVersion {
  126. table.Version = col.Name
  127. }
  128. }
  129. // AddIndex adds an index or an unique to table
  130. func (table *Table) AddIndex(index *Index) {
  131. table.Indexes[index.Name] = index
  132. }
  133. // IDOfV get id from one value of struct
  134. func (table *Table) IDOfV(rv reflect.Value) (PK, error) {
  135. v := reflect.Indirect(rv)
  136. pk := make([]interface{}, len(table.PrimaryKeys))
  137. for i, col := range table.PKColumns() {
  138. var err error
  139. fieldName := col.FieldName
  140. for {
  141. parts := strings.SplitN(fieldName, ".", 2)
  142. if len(parts) == 1 {
  143. break
  144. }
  145. v = v.FieldByName(parts[0])
  146. if v.Kind() == reflect.Ptr {
  147. v = v.Elem()
  148. }
  149. if v.Kind() != reflect.Struct {
  150. return nil, fmt.Errorf("Unsupported read value of column %s from field %s", col.Name, col.FieldName)
  151. }
  152. fieldName = parts[1]
  153. }
  154. pkField := v.FieldByName(fieldName)
  155. switch pkField.Kind() {
  156. case reflect.String:
  157. pk[i], err = col.ConvertID(pkField.String())
  158. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  159. pk[i], err = col.ConvertID(strconv.FormatInt(pkField.Int(), 10))
  160. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  161. // id of uint will be converted to int64
  162. pk[i], err = col.ConvertID(strconv.FormatUint(pkField.Uint(), 10))
  163. }
  164. if err != nil {
  165. return nil, err
  166. }
  167. }
  168. return PK(pk), nil
  169. }