ParseField parses reflect.StructField to Field
(fieldStruct reflect.StructField)
| 104 | |
| 105 | // ParseField parses reflect.StructField to Field |
| 106 | func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { |
| 107 | var ( |
| 108 | err error |
| 109 | tagSetting = ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";") |
| 110 | ) |
| 111 | |
| 112 | field := &Field{ |
| 113 | Name: fieldStruct.Name, |
| 114 | DBName: tagSetting["COLUMN"], |
| 115 | BindNames: []string{fieldStruct.Name}, |
| 116 | EmbeddedBindNames: []string{fieldStruct.Name}, |
| 117 | FieldType: fieldStruct.Type, |
| 118 | IndirectFieldType: fieldStruct.Type, |
| 119 | StructField: fieldStruct, |
| 120 | Tag: fieldStruct.Tag, |
| 121 | TagSettings: tagSetting, |
| 122 | Schema: schema, |
| 123 | Creatable: true, |
| 124 | Updatable: true, |
| 125 | Readable: true, |
| 126 | PrimaryKey: utils.CheckTruth(tagSetting["PRIMARYKEY"], tagSetting["PRIMARY_KEY"]), |
| 127 | AutoIncrement: utils.CheckTruth(tagSetting["AUTOINCREMENT"]), |
| 128 | HasDefaultValue: utils.CheckTruth(tagSetting["AUTOINCREMENT"]), |
| 129 | NotNull: utils.CheckTruth(tagSetting["NOT NULL"], tagSetting["NOTNULL"]), |
| 130 | Unique: utils.CheckTruth(tagSetting["UNIQUE"]), |
| 131 | Comment: tagSetting["COMMENT"], |
| 132 | AutoIncrementIncrement: DefaultAutoIncrementIncrement, |
| 133 | } |
| 134 | |
| 135 | for field.IndirectFieldType.Kind() == reflect.Ptr { |
| 136 | field.IndirectFieldType = field.IndirectFieldType.Elem() |
| 137 | } |
| 138 | |
| 139 | fieldValue := reflect.New(field.IndirectFieldType) |
| 140 | // if field is valuer, used its value or first field as data type |
| 141 | valuer, isValuer := fieldValue.Interface().(driver.Valuer) |
| 142 | if isValuer { |
| 143 | if _, ok := fieldValue.Interface().(GormDataTypeInterface); !ok { |
| 144 | if v, err := valuer.Value(); reflect.ValueOf(v).IsValid() && err == nil { |
| 145 | fieldValue = reflect.ValueOf(v) |
| 146 | } |
| 147 | |
| 148 | // Use the field struct's first field type as data type, e.g: use `string` for sql.NullString |
| 149 | var getRealFieldValue func(reflect.Value) |
| 150 | getRealFieldValue = func(v reflect.Value) { |
| 151 | var ( |
| 152 | rv = reflect.Indirect(v) |
| 153 | rvType = rv.Type() |
| 154 | ) |
| 155 | |
| 156 | if rv.Kind() == reflect.Struct && !rvType.ConvertibleTo(TimeReflectType) { |
| 157 | for i := 0; i < rvType.NumField(); i++ { |
| 158 | for key, value := range ParseTagSetting(rvType.Field(i).Tag.Get("gorm"), ";") { |
| 159 | if _, ok := field.TagSettings[key]; !ok { |
| 160 | field.TagSettings[key] = value |
| 161 | } |
| 162 | } |
| 163 | } |
no test coverage detected