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