package f5 import ( "os" "bufio" "strings" "reflect" "fmt" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/jsonpb" ) type MetaClass struct { FileName string Idx int RawMeta interface{} WrapMeta interface{} PrimKey string SecKey string } type MetaMgr struct { metaClasses *[]MetaClass rawList []interface{} wrapList []interface{} wrapIdHash []map[int64]interface{} wrapNameHash []map[string]interface{} } func (this *MetaMgr) Init() { } func (this *MetaMgr) UnInit() { } func (this *MetaMgr) RegisterMetaClasses(metaClasses *[]MetaClass) { this.metaClasses = metaClasses } func (this *MetaMgr) Load() { this.rawList = make([]interface{}, len(*this.metaClasses)) this.wrapList = make([]interface{}, len(*this.metaClasses)) this.wrapIdHash = make([]map[int64]interface{}, len(*this.metaClasses)) this.wrapNameHash = make([]map[string]interface{}, len(*this.metaClasses)) this.loadRawMetaTable() this.bindPrimKey() } func (this *MetaMgr) loadRawMetaTable() { for key, val := range *this.metaClasses { rawMeta, _ := this.loadJson(&val) values := rawMeta.Elem().FieldByName("Values") wrapMetaType := reflect.TypeOf(val.WrapMeta) wrapMetaList := reflect.MakeSlice(reflect.SliceOf(wrapMetaType), 0, values.Len()) for i := 0; i < values.Len(); i++ { val := values.Index(i) wrapMeta := reflect.New(reflect.TypeOf(wrapMetaList.Interface()).Elem().Elem()) clsName := reflect.TypeOf(val.Elem().Interface()).Name() clsField := wrapMeta.Elem().FieldByName(clsName) clsField.Set(val) wrapMetaList = reflect.Append(wrapMetaList, wrapMeta) } this.rawList[key] = rawMeta this.wrapList[key] = wrapMetaList.Interface() this.wrapIdHash[key] = map[int64]interface{}{} this.wrapNameHash[key] = map[string]interface{}{} } } func (this *MetaMgr) bindPrimKey() { for key, val := range *this.metaClasses { wrapMetaList := reflect.ValueOf(this.wrapList[key]) for i := 0; i < wrapMetaList.Len(); i++ { wrapMeta := wrapMetaList.Index(i) if val.PrimKey == "" { this.wrapIdHash[key][int64(i + 1)] = wrapMeta.Interface() continue } primVal := wrapMeta.Elem().FieldByName(val.PrimKey) secVal := wrapMeta.Elem().FieldByName(val.SecKey) if fieldVal, ok := primVal.Interface().(*string); ok { this.wrapNameHash[key][*fieldVal] = wrapMeta } else if fieldVal, ok := primVal.Interface().(*int32); ok { if val.SecKey == "" { this.wrapIdHash[key][int64(*fieldVal)] = wrapMeta.Interface() } else { if subFieldVal, ok := secVal.Interface().(*int32); ok { this.wrapIdHash[key][int64(*subFieldVal)] = wrapMeta.Interface() } else { } } } } } fmt.Println("ok") } func (this *MetaMgr) loadJson(metaClass *MetaClass) (reflect.Value, error) { f, _ := os.Open(metaClass.FileName) data, _ := bufio.NewReader(f).ReadString(0) data = "{\"values\":" + data data += "}" u := jsonpb.Unmarshaler{AllowUnknownFields: true} msgType := reflect.TypeOf(metaClass.RawMeta).Elem() msg := reflect.New(msgType) msgPb := msg.Interface().(proto.Message) err := u.Unmarshal(strings.NewReader(data), msgPb) return msg, err } func (this *MetaMgr) GetMetaById(idx int, id int32) interface{} { return this.GetMetaById64(idx, int64(id)) } func (this *MetaMgr) GetMetaById64(idx int, id int64) interface{} { if idx >=0 && idx < len(this.wrapIdHash) { idHash := this.wrapIdHash[idx] if v, ok := idHash[id]; ok { return reflect.ValueOf(v).Interface() } else { return nil } } return nil } func (this *MetaMgr) GetMetaByName(idx int, name string) interface{} { if idx >=0 && idx < len(this.wrapNameHash) { nameHash := this.wrapNameHash[idx] if v, ok := nameHash[name]; ok { return v } else { return nil } } return nil } func (this *MetaMgr) GetMetaList(idx int) interface{} { if idx >=0 && idx < len(this.wrapList) { return this.wrapList[idx] } return nil }