reflect.go (1480B)
1 package schema 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "net" 7 "reflect" 8 "time" 9 ) 10 11 var ( 12 bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() 13 timePtrType = reflect.TypeOf((*time.Time)(nil)) 14 timeType = timePtrType.Elem() 15 ipType = reflect.TypeOf((*net.IP)(nil)).Elem() 16 ipNetType = reflect.TypeOf((*net.IPNet)(nil)).Elem() 17 jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem() 18 19 driverValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem() 20 queryAppenderType = reflect.TypeOf((*QueryAppender)(nil)).Elem() 21 jsonMarshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() 22 ) 23 24 func indirectType(t reflect.Type) reflect.Type { 25 if t.Kind() == reflect.Ptr { 26 t = t.Elem() 27 } 28 return t 29 } 30 31 func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) { 32 if len(index) == 1 { 33 return v.Field(index[0]), true 34 } 35 36 for i, idx := range index { 37 if i > 0 { 38 if v.Kind() == reflect.Ptr { 39 if v.IsNil() { 40 return v, false 41 } 42 v = v.Elem() 43 } 44 } 45 v = v.Field(idx) 46 } 47 return v, true 48 } 49 50 func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value { 51 if len(index) == 1 { 52 return v.Field(index[0]) 53 } 54 55 for i, idx := range index { 56 if i > 0 { 57 v = indirectNil(v) 58 } 59 v = v.Field(idx) 60 } 61 return v 62 } 63 64 func indirectNil(v reflect.Value) reflect.Value { 65 if v.Kind() == reflect.Ptr { 66 if v.IsNil() { 67 v.Set(reflect.New(v.Type().Elem())) 68 } 69 v = v.Elem() 70 } 71 return v 72 }