|
|
|
package stardb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"reflect"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (star *StarRows) setAllRefValue(stc interface{}, skey string, rows int) error {
|
|
|
|
t := reflect.TypeOf(stc)
|
|
|
|
v := reflect.ValueOf(stc)
|
|
|
|
if t.Kind() == reflect.Ptr {
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
if t.Kind() != reflect.Ptr && !v.CanSet() {
|
|
|
|
return errors.New("interface{} is not writable")
|
|
|
|
}
|
|
|
|
if t.Kind() == reflect.Ptr {
|
|
|
|
t = t.Elem()
|
|
|
|
}
|
|
|
|
if v.Kind() != reflect.Struct {
|
|
|
|
return errors.New("interface{} is not a struct")
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
tp := t.Field(i)
|
|
|
|
srFrd := v.Field(i)
|
|
|
|
seg := tp.Tag.Get(skey)
|
|
|
|
if seg == "" && !tp.IsExported() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if srFrd.Kind() == reflect.Ptr && reflect.TypeOf(srFrd.Interface()).Elem().Kind() == reflect.Struct {
|
|
|
|
if seg == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if seg == "---" {
|
|
|
|
sp := reflect.New(reflect.TypeOf(srFrd.Interface()).Elem()).Interface()
|
|
|
|
star.setAllRefValue(sp, skey, rows)
|
|
|
|
v.Field(i).Set(reflect.ValueOf(sp))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if srFrd.Kind() == reflect.Struct {
|
|
|
|
if seg == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if seg == "---" {
|
|
|
|
sp := reflect.New(reflect.TypeOf(v.Field(i).Interface())).Interface()
|
|
|
|
star.setAllRefValue(sp, skey, rows)
|
|
|
|
v.Field(i).Set(reflect.ValueOf(sp).Elem())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, ok := star.Row(rows).columnref[seg]; !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
myInt64 := star.Row(rows).MustInt64(seg)
|
|
|
|
myUint64 := star.Row(rows).MustUint64(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)))
|
|
|
|
case reflect.Slice, reflect.Array:
|
|
|
|
if t.Field(i).Type.Elem().Kind() == reflect.Uint8 {
|
|
|
|
v.Field(i).SetBytes(star.Row(rows).MustBytes(seg))
|
|
|
|
}
|
|
|
|
case reflect.Interface, reflect.Struct, reflect.Ptr:
|
|
|
|
inf := star.Row(rows).Result[star.columnref[seg]]
|
|
|
|
switch vtype := inf.(type) {
|
|
|
|
case time.Time:
|
|
|
|
v.Field(i).Set(reflect.ValueOf(vtype))
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
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 t.Kind() == reflect.Ptr {
|
|
|
|
if v.IsNil() {
|
|
|
|
return nil, errors.New("ptr interface{} is nil")
|
|
|
|
}
|
|
|
|
t = t.Elem()
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
if v.Kind() != reflect.Struct {
|
|
|
|
return nil, errors.New("interface{} is not a struct")
|
|
|
|
}
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
tp := t.Field(i)
|
|
|
|
srFrd := v.Field(i)
|
|
|
|
seg := tp.Tag.Get(skey)
|
|
|
|
if seg == "" && !tp.IsExported() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if srFrd.Kind() == reflect.Ptr && reflect.TypeOf(srFrd.Interface()).Elem().Kind() == reflect.Struct {
|
|
|
|
if srFrd.IsNil() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if seg == "---" {
|
|
|
|
res, err := getAllRefValue(reflect.ValueOf(srFrd.Elem().Interface()).Interface(), skey)
|
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
for k, v := range res {
|
|
|
|
result[k] = v
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if v.Field(i).Kind() == reflect.Struct {
|
|
|
|
res, err := getAllRefValue(v.Field(i).Interface(), skey)
|
|
|
|
if seg == "---" {
|
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
for k, v := range res {
|
|
|
|
result[k] = v
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
v := reflect.ValueOf(stc)
|
|
|
|
if t.Kind() == reflect.Ptr {
|
|
|
|
if v.IsNil() {
|
|
|
|
return []string{}, errors.New("ptr interface{} is nil")
|
|
|
|
}
|
|
|
|
t = t.Elem()
|
|
|
|
v = v.Elem()
|
|
|
|
}
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
srFrd := v.Field(i)
|
|
|
|
profile := t.Field(i)
|
|
|
|
seg := profile.Tag.Get(skey)
|
|
|
|
if seg == "" && !profile.IsExported() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if srFrd.Kind() == reflect.Ptr && reflect.TypeOf(srFrd.Interface()).Elem().Kind() == reflect.Struct {
|
|
|
|
if srFrd.IsNil() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if seg == "---" {
|
|
|
|
res, err := getAllRefKey(reflect.ValueOf(srFrd.Elem().Interface()).Interface(), skey)
|
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
for _, v := range res {
|
|
|
|
result = append(result, v)
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if v.Field(i).Kind() == reflect.Struct && seg == "---" {
|
|
|
|
res, err := getAllRefKey(v.Field(i).Interface(), skey)
|
|
|
|
if err != nil {
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
for _, v := range res {
|
|
|
|
result = append(result, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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.CanSet() {
|
|
|
|
isWritable = true
|
|
|
|
}
|
|
|
|
if v.Kind() == reflect.Struct {
|
|
|
|
isStruct = true
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|