package orm import ( "fmt" "reflect" "strings" ) func panik(err error) { if err != nil { panic(err) } } func nameOf(i interface{}) string { v := reflect.ValueOf(i) var n string switch v.Kind() { case reflect.Slice, reflect.Map: if v.Type().Elem().Kind() == reflect.Pointer { n = v.Type().Elem().Elem().Name() } case reflect.Pointer: n = nameOf(reflect.Indirect(v).Interface()) default: n = v.Type().Name() } return n } func valueOf(i interface{}) reflect.Value { v := reflect.ValueOf(i) if v.Type().Kind() == reflect.Slice || v.Type().Kind() == reflect.Map { in := v.Type().Elem() switch in.Kind() { case reflect.Pointer: v = reflect.New(in.Elem()).Elem() default: v = reflect.New(in).Elem() } } else if v.Type().Kind() == reflect.Pointer { v = valueOf(reflect.Indirect(v).Interface()) } return v } func iFace(input interface{}) interface{} { return reflect.ValueOf(input).Interface() } func iFaceSlice(input interface{}) []interface{} { ret := make([]interface{}, 0) fv := reflect.ValueOf(input) if fv.Type().Kind() != reflect.Slice { return ret } for i := 0; i < fv.Len(); i++ { ret = append(ret, fv.Index(i).Interface()) } return ret } func coerceInt(input reflect.Value, dst reflect.Value) interface{} { if input.Type().Kind() == reflect.Pointer { input = input.Elem() } if dst.Type().Kind() == reflect.Pointer { dst = dst.Elem() } if input.Type().ConvertibleTo(dst.Type()) { return input.Convert(dst.Type()).Interface() } return nil } func getNested(field string, value reflect.Value) (*reflect.Type, *reflect.Value, error) { if strings.HasPrefix(field, ".") || strings.HasSuffix(field, ".") { return nil, nil, fmt.Errorf("Malformed field name %s passed", field) } dots := strings.Split(field, ".") if value.Kind() != reflect.Struct { return nil, nil, fmt.Errorf("This value is not a struct!") } ref := value if ref.Kind() == reflect.Pointer { ref = ref.Elem() } fv := ref.FieldByName(dots[0]) ft := fv.Type() if len(dots) > 1 { return getNested(strings.Join(dots[1:], "."), fv) } else { return &ft, &fv, nil } } func makeSettable(rval reflect.Value, value interface{}) reflect.Value { if !rval.CanSet() { nv := reflect.New(rval.Type()) nv.Elem().Set(reflect.ValueOf(value)) return nv } return rval }