OSDN Git Service

feat: init cross_tx keepers (#146)
[bytom/vapor.git] / vendor / github.com / jinzhu / gorm / field.go
1 package gorm
2
3 import (
4         "database/sql"
5         "database/sql/driver"
6         "errors"
7         "fmt"
8         "reflect"
9 )
10
11 // Field model field definition
12 type Field struct {
13         *StructField
14         IsBlank bool
15         Field   reflect.Value
16 }
17
18 // Set set a value to the field
19 func (field *Field) Set(value interface{}) (err error) {
20         if !field.Field.IsValid() {
21                 return errors.New("field value not valid")
22         }
23
24         if !field.Field.CanAddr() {
25                 return ErrUnaddressable
26         }
27
28         reflectValue, ok := value.(reflect.Value)
29         if !ok {
30                 reflectValue = reflect.ValueOf(value)
31         }
32
33         fieldValue := field.Field
34         if reflectValue.IsValid() {
35                 if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
36                         fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
37                 } else {
38                         if fieldValue.Kind() == reflect.Ptr {
39                                 if fieldValue.IsNil() {
40                                         fieldValue.Set(reflect.New(field.Struct.Type.Elem()))
41                                 }
42                                 fieldValue = fieldValue.Elem()
43                         }
44
45                         if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
46                                 fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
47                         } else if scanner, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
48                                 v := reflectValue.Interface()
49                                 if valuer, ok := v.(driver.Valuer); ok {
50                                         if v, err = valuer.Value(); err == nil {
51                                                 err = scanner.Scan(v)
52                                         }
53                                 } else {
54                                         err = scanner.Scan(v)
55                                 }
56                         } else {
57                                 err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
58                         }
59                 }
60         } else {
61                 field.Field.Set(reflect.Zero(field.Field.Type()))
62         }
63
64         field.IsBlank = isBlank(field.Field)
65         return err
66 }