package stardb import ( "errors" "reflect" ) func (star *StarRows) setAllRefValue(stc interface{}, skey string, rows int) error { t := reflect.TypeOf(stc) v := reflect.ValueOf(stc).Elem() if t.Kind() != reflect.Ptr || !v.CanSet() { return errors.New("interface{} is not writable") } if v.Kind() != reflect.Struct { return errors.New("interface{} is not a struct") } t = t.Elem() for i := 0; i < t.NumField(); i++ { tp := t.Field(i) seg := tp.Tag.Get(skey) if seg == "" { continue } if _, ok := star.Row(rows).columnref[seg]; !ok { continue } myInt64 := star.Row(rows).MustInt64(seg) myUint64 := uint64(star.Row(rows).MustInt64(seg)) switch v.Field(i).Kind() { case reflect.String: v.Field(i).SetString(star.Row(rows).MustString(seg)) case reflect.Int64: v.Field(i).SetInt(myInt64) case reflect.Int32: v.Field(i).SetInt(int64(star.Row(rows).MustInt32(seg))) case reflect.Int16: v.Field(i).SetInt(int64(int16(myInt64))) case reflect.Int8: v.Field(i).SetInt(int64(int8(myInt64))) case reflect.Uint64: v.Field(i).SetUint(myUint64) case reflect.Uint32: v.Field(i).SetUint(uint64(uint32(myUint64))) case reflect.Uint16: v.Field(i).SetUint(uint64(uint16(myUint64))) case reflect.Uint8: v.Field(i).SetUint(uint64(uint8(myUint64))) case reflect.Bool: v.Field(i).SetBool(star.Row(rows).MustBool(seg)) case reflect.Float64: v.Field(i).SetFloat(star.Row(rows).MustFloat64(seg)) case reflect.Float32: v.Field(i).SetFloat(float64(star.Row(rows).MustFloat32(seg))) default: } } return nil } func setAllRefValue(stc interface{}, skey string, kv map[string]interface{}) error { t := reflect.TypeOf(stc) v := reflect.ValueOf(stc).Elem() if t.Kind() != reflect.Ptr || !v.CanSet() { return errors.New("interface{} is not writable") } if v.Kind() != reflect.Struct { return errors.New("interface{} is not a struct") } t = t.Elem() for i := 0; i < t.NumField(); i++ { tp := t.Field(i) seg := tp.Tag.Get(skey) if seg == "" { continue } if _, ok := kv[seg]; !ok { continue } v.Field(i).Set(reflect.ValueOf(kv[seg])) } return nil } func setRefValue(stc interface{}, skey, key string, value interface{}) error { t := reflect.TypeOf(stc) v := reflect.ValueOf(stc).Elem() if t.Kind() != reflect.Ptr || !v.CanSet() { return errors.New("interface{} is not writable") } if v.Kind() != reflect.Struct { return errors.New("interface{} is not a struct") } t = t.Elem() for i := 0; i < t.NumField(); i++ { tp := t.Field(i) seg := tp.Tag.Get(skey) if seg == "" || key != seg { continue } v.Field(i).Set(reflect.ValueOf(value)) } return nil } func getAllRefValue(stc interface{}, skey string) (map[string]interface{}, error) { result := make(map[string]interface{}) t := reflect.TypeOf(stc) v := reflect.ValueOf(stc) if v.Kind() != reflect.Struct { return nil, errors.New("interface{} is not a struct") } if t.Kind() == reflect.Ptr { t = t.Elem() v = v.Elem() } for i := 0; i < t.NumField(); i++ { tp := t.Field(i) seg := tp.Tag.Get(skey) if seg == "" { continue } value := v.Field(i) if !value.CanInterface() { continue } result[seg] = value.Interface() } return result, nil } func getAllRefKey(stc interface{}, skey string) ([]string, error) { var result []string _, isStruct := isWritableStruct(stc) if !isStruct { return []string{}, errors.New("interface{} is not a struct") } t := reflect.TypeOf(stc) if t.Kind() == reflect.Ptr { t = t.Elem() } for i := 0; i < t.NumField(); i++ { profile := t.Field(i) seg := profile.Tag.Get(skey) if seg != "" { result = append(result, seg) } } return result, nil } func isWritableStruct(stc interface{}) (isWritable bool, isStruct bool) { t := reflect.TypeOf(stc) v := reflect.ValueOf(stc) if t.Kind() == reflect.Ptr && v.Elem().CanSet() { isWritable = true } if v.Kind() == reflect.Struct { isStruct = true } return }