From 4f4d0dec0b29f4cba537a7417c1ab01c5693a214 Mon Sep 17 00:00:00 2001 From: liwei1dao Date: Tue, 12 Jul 2022 11:03:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0redis=E7=9A=84=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lego/base/rpcx/service.go | 7 ++ lego/sys/codec/codec.go | 89 +++++++++++++++++++++- lego/sys/codec/core.go | 25 +++++- lego/sys/codec/core/core.go | 21 ++++- lego/sys/codec/factory/factory.go | 31 +++++++- lego/sys/codec/factory/factory_array.go | 58 +++++++++++--- lego/sys/codec/factory/factory_map.go | 53 +++++++++++++ lego/sys/codec/factory/factory_optional.go | 48 +++++++----- lego/sys/codec/factory/factory_slice.go | 80 +++++++++++++++---- lego/sys/codec/factory/factory_struct.go | 4 +- lego/sys/codec/options.go | 7 ++ lego/sys/codec/sys_test.go | 20 ++++- lego/sys/mgo/mgo.go | 6 +- lego/sys/redis/cluster/core.go | 11 +-- lego/sys/redis/cluster/hash.go | 16 ++-- lego/sys/redis/cluster/list.go | 50 ++++++------ lego/sys/redis/cluster/set.go | 10 +-- lego/sys/redis/cluster/string.go | 30 ++++---- lego/sys/redis/cluster/zset.go | 10 +-- lego/sys/redis/core/core.go | 12 +++ lego/sys/redis/options.go | 22 ++---- lego/sys/redis/redis.go | 64 +++++++++++----- lego/sys/redis/single/core.go | 11 +-- lego/sys/redis/single/hash.go | 16 ++-- lego/sys/redis/single/list.go | 50 ++++++------ lego/sys/redis/single/set.go | 10 +-- lego/sys/redis/single/string.go | 30 ++++---- lego/sys/redis/single/zset.go | 10 +-- lego/sys/redis/sys_test.go | 1 - sys/db/benchmark/query_test.go | 15 +++- 30 files changed, 592 insertions(+), 225 deletions(-) create mode 100644 lego/sys/redis/core/core.go diff --git a/lego/base/rpcx/service.go b/lego/base/rpcx/service.go index f59d47964..4d7d22abe 100644 --- a/lego/base/rpcx/service.go +++ b/lego/base/rpcx/service.go @@ -8,6 +8,7 @@ import ( "go_dreamfactory/lego/base" "go_dreamfactory/lego/core" "go_dreamfactory/lego/core/cbase" + "go_dreamfactory/lego/sys/codec" "go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/rpcx" @@ -84,6 +85,12 @@ func (this *RPCXService) InitSys() { } else { log.Infof("Sys event Init success !") } + //初始化编码Codec + if err := codec.OnInit(this.opts.Setting.Sys["codec"]); err != nil { + log.Panicf(fmt.Sprintf("Sys codec Init err:%v", err)) + } else { + log.Infof("Sys codec Init success !") + } //初始化rpcx系统 if err := rpcx.OnInit(this.opts.Setting.Sys["rpcx"], rpcx.SetServiceTag(this.GetTag()), rpcx.SetServiceId(this.GetId()), rpcx.SetServiceType(this.GetType()), rpcx.SetServiceVersion(this.GetVersion()), rpcx.SetServiceAddr(fmt.Sprintf("%s:%d", this.GetIp(), this.GetPort()))); err != nil { log.Panicf(fmt.Sprintf("Sys rpcx Init err:%v", err)) diff --git a/lego/sys/codec/codec.go b/lego/sys/codec/codec.go index 7878c23e7..3fa30b128 100644 --- a/lego/sys/codec/codec.go +++ b/lego/sys/codec/codec.go @@ -1,6 +1,9 @@ package codec import ( + "errors" + "fmt" + "reflect" "sync" "go_dreamfactory/lego/sys/codec/core" @@ -136,7 +139,7 @@ func (this *Codec) MarshalJson(val interface{}, option ...core.ExecuteOption) (b } //解码json到对象 -func (this *Codec) UnmarshalJson(data []byte, v interface{}) error { +func (this *Codec) UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error { extra := this.BorrowExtractor(data) defer this.ReturnExtractor(extra) extra.ReadVal(v) @@ -145,12 +148,92 @@ func (this *Codec) UnmarshalJson(data []byte, v interface{}) error { //编码对象到mapjson func (this *Codec) MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) { + if nil == val { + err = errors.New("val is null") + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := this.GetEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = this.EncoderOf(typ) + } + if encoderMapJson, ok := encoder.(core.IEncoderMapJson); !ok { + err = fmt.Errorf("val type:%T not support MarshalMapJson", val) + } else { + ret, err = encoderMapJson.EncodeToMapJson(reflect2.PtrOf(val)) + } return } //解码mapjson到对象 -func (this *Codec) UnmarshalMapString(data []byte, v interface{}) error { - return nil +func (this *Codec) UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) { + cacheKey := reflect2.RTypeOf(val) + decoder := this.GetDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(val) + if typ == nil || typ.Kind() != reflect.Ptr { + err = errors.New("can only unmarshal into pointer") + return + } + decoder = this.DecoderOf(typ) + } + ptr := reflect2.PtrOf(val) + if ptr == nil { + err = errors.New("can not read into nil pointer") + return + } + if decoderMapJson, ok := decoder.(core.IDecoderMapJson); !ok { + err = fmt.Errorf("val type:%T not support MarshalMapJson", val) + } else { + err = decoderMapJson.DecodeForMapJson(ptr, data) + } + return +} + +//编码对象到sliceJson +func (this *Codec) MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) { + if nil == val { + err = errors.New("val is null") + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := this.GetEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = this.EncoderOf(typ) + } + if encoderMapJson, ok := encoder.(core.IEncoderSliceJson); !ok { + err = fmt.Errorf("val type:%T not support MarshalMapJson", val) + } else { + ret, err = encoderMapJson.EncodeToSliceJson(reflect2.PtrOf(val)) + } + return +} + +//解码sliceJson到对象 +func (this *Codec) UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) { + cacheKey := reflect2.RTypeOf(val) + decoder := this.GetDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(val) + if typ == nil || typ.Kind() != reflect.Ptr { + err = errors.New("can only unmarshal into pointer") + return + } + decoder = this.DecoderOf(typ) + } + ptr := reflect2.PtrOf(val) + if ptr == nil { + err = errors.New("can not read into nil pointer") + return + } + if decoderMapJson, ok := decoder.(core.IDecoderSliceJson); !ok { + err = fmt.Errorf("val type:%T not support UnmarshalSliceJson", val) + } else { + err = decoderMapJson.DecodeForSliceJson(ptr, data) + } + return } ///日志*********************************************************************** diff --git a/lego/sys/codec/core.go b/lego/sys/codec/core.go index 69f61d93e..69255ec36 100644 --- a/lego/sys/codec/core.go +++ b/lego/sys/codec/core.go @@ -7,7 +7,11 @@ import ( type ( ISys interface { MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error) - UnmarshalJson(data []byte, v interface{}) error + UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error + MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) + UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) + MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) + UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) } ) @@ -22,3 +26,22 @@ func NewSys(option ...core.Option) (sys ISys, err error) { sys, err = newSys(newOptionsByOption(option...)) return } + +func MarshalJson(v interface{}, option ...core.ExecuteOption) ([]byte, error) { + return defsys.MarshalJson(v, option...) +} +func UnmarshalJson(data []byte, v interface{}, option ...core.ExecuteOption) error { + return defsys.UnmarshalJson(data, v, option...) +} +func MarshalMapJson(val interface{}, option ...core.ExecuteOption) (ret map[string]string, err error) { + return defsys.MarshalMapJson(val, option...) +} +func UnmarshalMapJson(data map[string]string, val interface{}, option ...core.ExecuteOption) (err error) { + return defsys.UnmarshalMapJson(data, val, option...) +} +func MarshalSliceJson(val interface{}, option ...core.ExecuteOption) (ret []string, err error) { + return defsys.MarshalSliceJson(val, option...) +} +func UnmarshalSliceJson(data []string, val interface{}, option ...core.ExecuteOption) (err error) { + return defsys.UnmarshalSliceJson(data, val) +} diff --git a/lego/sys/codec/core/core.go b/lego/sys/codec/core/core.go index 8bed721ad..d569e4ea0 100644 --- a/lego/sys/codec/core/core.go +++ b/lego/sys/codec/core/core.go @@ -111,15 +111,32 @@ type ( Error() error SetErr(err error) } - //编码器 + //Json 编码器 IEncoder interface { IsEmpty(ptr unsafe.Pointer) bool Encode(ptr unsafe.Pointer, stream IStream) } - //解码器 + //MapJson 编码器 + IEncoderMapJson interface { + EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) + } + //SliceJson 编码器 + IEncoderSliceJson interface { + EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) + } + + //Json 解码器 IDecoder interface { Decode(ptr unsafe.Pointer, extra IExtractor) } + //MapJson 解码器 + IDecoderMapJson interface { + DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) + } + //MapJson 解码器 + IDecoderSliceJson interface { + DecodeForSliceJson(ptr unsafe.Pointer, extra []string) (err error) + } //空校验 CheckIsEmpty interface { IsEmpty(ptr unsafe.Pointer) bool diff --git a/lego/sys/codec/factory/factory.go b/lego/sys/codec/factory/factory.go index 5099c9c0f..4876ec615 100644 --- a/lego/sys/codec/factory/factory.go +++ b/lego/sys/codec/factory/factory.go @@ -113,6 +113,20 @@ func _createDecoderOfType(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { } } +// string +func BytesToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +func StringToBytes(s string) []byte { + return *(*[]byte)(unsafe.Pointer( + &struct { + string + Cap int + }{s, len(s)}, + )) +} + //根节点 ------------------------------------------------------------------- type rootDecoder struct { decoder core.IDecoder @@ -143,12 +157,21 @@ type onePtrEncoder struct { encoder core.IEncoder } -func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +func (this *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return this.encoder.IsEmpty(unsafe.Pointer(&ptr)) } -func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +func (this *onePtrEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { + this.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func (this *onePtrEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) { + if encoderMapJson, ok := this.encoder.(core.IEncoderMapJson); !ok { + err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.encoder) + return + } else { + return encoderMapJson.EncodeToMapJson(ptr) + } } //错误节点 ------------------------------------------------------------------ diff --git a/lego/sys/codec/factory/factory_array.go b/lego/sys/codec/factory/factory_array.go index 0bb52f99e..34453632f 100644 --- a/lego/sys/codec/factory/factory_array.go +++ b/lego/sys/codec/factory/factory_array.go @@ -1,6 +1,7 @@ package factory import ( + "errors" "fmt" "io" "unsafe" @@ -13,7 +14,7 @@ import ( func decoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { arrayType := typ.(*reflect2.UnsafeArrayType) decoder := DecoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem()) - return &arrayDecoder{arrayType, decoder} + return &arrayDecoder{ctx.ICodec, arrayType, decoder} } func encoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { @@ -22,35 +23,54 @@ func encoderOfArray(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { return emptyArrayEncoder{} } encoder := EncoderOfType(ctx.Append("[arrayElem]"), arrayType.Elem()) - return &arrayEncoder{arrayType, encoder} + return &arrayEncoder{ctx.ICodec, arrayType, encoder} } //array------------------------------------------------------------------------------------------------------------------------------- type arrayEncoder struct { + codec core.ICodec arrayType *reflect2.UnsafeArrayType elemEncoder core.IEncoder } -func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { +func (this *arrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { stream.WriteArrayStart() elemPtr := unsafe.Pointer(ptr) - encoder.elemEncoder.Encode(elemPtr, stream) - for i := 1; i < encoder.arrayType.Len(); i++ { + this.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < this.arrayType.Len(); i++ { stream.WriteMemberSplit() - elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) + elemPtr = this.arrayType.UnsafeGetIndex(ptr, i) + this.elemEncoder.Encode(elemPtr, stream) } stream.WriteArrayEnd() if stream.Error() != nil && stream.Error() != io.EOF { - stream.SetErr(fmt.Errorf("%v: %s", encoder.arrayType, stream.Error().Error())) + stream.SetErr(fmt.Errorf("%v: %s", this.arrayType, stream.Error().Error())) } } -func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { +func (this *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } +//编码对象到json数组 +func (this *arrayEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) { + ret = make([]string, this.arrayType.Len()) + stream := this.codec.BorrowStream() + for i := 1; i < this.arrayType.Len(); i++ { + elemPtr := this.arrayType.UnsafeGetIndex(ptr, i) + this.elemEncoder.Encode(elemPtr, stream) + if stream.Error() != nil && stream.Error() != io.EOF { + err = stream.Error() + return + } + ret[i] = BytesToString(stream.Buffer()) + stream.Reset(512) + } + return +} + type arrayDecoder struct { + codec core.ICodec arrayType *reflect2.UnsafeArrayType elemDecoder core.IDecoder } @@ -83,6 +103,26 @@ func (this *arrayDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { } } +func (this *arrayDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) { + arrayType := this.arrayType + if data == nil { + err = errors.New("extra is nil") + return + } + extra := this.codec.BorrowExtractor([]byte{}) + arrayType.UnsafeGetIndex(ptr, len(data)) + for i, v := range data { + elemPtr := arrayType.UnsafeGetIndex(ptr, i) + extra.ResetBytes(StringToBytes(v)) + this.elemDecoder.Decode(elemPtr, extra) + if extra.Error() != nil && extra.Error() != io.EOF { + err = extra.Error() + return + } + } + return +} + type emptyArrayEncoder struct{} func (this emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { diff --git a/lego/sys/codec/factory/factory_map.go b/lego/sys/codec/factory/factory_map.go index 4bbfb6444..f694a62fd 100644 --- a/lego/sys/codec/factory/factory_map.go +++ b/lego/sys/codec/factory/factory_map.go @@ -2,6 +2,7 @@ package factory import ( "fmt" + "io" "reflect" "unsafe" @@ -15,6 +16,7 @@ func decoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { keyDecoder := decoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key()) elemDecoder := DecoderOfType(ctx.Append("[mapElem]"), mapType.Elem()) return &mapDecoder{ + codec: ctx.ICodec, mapType: mapType, keyType: mapType.Key(), elemType: mapType.Elem(), @@ -26,6 +28,7 @@ func decoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { func encoderOfMap(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { mapType := typ.(*reflect2.UnsafeMapType) return &mapEncoder{ + codec: ctx.ICodec, mapType: mapType, keyEncoder: encoderOfMapKey(ctx.Append("[mapKey]"), mapType.Key()), elemEncoder: EncoderOfType(ctx.Append("[mapElem]"), mapType.Elem()), @@ -75,6 +78,7 @@ func encoderOfMapKey(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { //Map-------------------------------------------------------------------------------------------------------------------------------------- type mapEncoder struct { + codec core.ICodec mapType *reflect2.UnsafeMapType keyEncoder core.IEncoder elemEncoder core.IEncoder @@ -99,12 +103,37 @@ func (this *mapEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { stream.WriteObjectEnd() } +func (this *mapEncoder) EncodeToMapString(ptr unsafe.Pointer) (ret map[string]string, err error) { + ret = make(map[string]string) + keystream := this.codec.BorrowStream() + elemstream := this.codec.BorrowStream() + iter := this.mapType.UnsafeIterate(ptr) + for i := 0; iter.HasNext(); i++ { + key, elem := iter.UnsafeNext() + this.keyEncoder.Encode(key, keystream) + if keystream.Error() != nil && keystream.Error() != io.EOF { + err = keystream.Error() + return + } + this.elemEncoder.Encode(elem, elemstream) + if elemstream.Error() != nil && elemstream.Error() != io.EOF { + err = elemstream.Error() + return + } + ret[BytesToString(keystream.Buffer())] = BytesToString(elemstream.Buffer()) + keystream.Reset(512) + elemstream.Reset(512) + } + return +} + func (this *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { iter := this.mapType.UnsafeIterate(ptr) return !iter.HasNext() } type mapDecoder struct { + codec core.ICodec mapType *reflect2.UnsafeMapType keyType reflect2.Type elemType reflect2.Type @@ -150,6 +179,30 @@ func (this *mapDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { extra.ReadObjectEnd() } +//解码对象从MapJson 中 +func (this *mapDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) { + keyext := this.codec.BorrowExtractor([]byte{}) + elemext := this.codec.BorrowExtractor([]byte{}) + for k, v := range extra { + keyext.ResetBytes(StringToBytes(k)) + key := this.keyType.UnsafeNew() + this.keyDecoder.Decode(key, keyext) + if keyext.Error() != nil && keyext.Error() != io.EOF { + err = keyext.Error() + return + } + elemext.ResetBytes(StringToBytes(v)) + elem := this.elemType.UnsafeNew() + this.elemDecoder.Decode(elem, elemext) + this.mapType.UnsafeSetIndex(ptr, key, elem) + if elemext.Error() != nil && elemext.Error() != io.EOF { + err = elemext.Error() + return + } + } + return +} + //NumericMap------------------------------------------------------------------------------------------------------------------------------- type numericMapKeyDecoder struct { decoder core.IDecoder diff --git a/lego/sys/codec/factory/factory_optional.go b/lego/sys/codec/factory/factory_optional.go index 2bdbf218b..433be370a 100644 --- a/lego/sys/codec/factory/factory_optional.go +++ b/lego/sys/codec/factory/factory_optional.go @@ -1,6 +1,7 @@ package factory import ( + "fmt" "unsafe" "go_dreamfactory/lego/sys/codec/core" @@ -29,16 +30,16 @@ type OptionalDecoder struct { ValueDecoder core.IDecoder } -func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { +func (this *OptionalDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { if extra.ReadNil() { *((*unsafe.Pointer)(ptr)) = nil } else { if *((*unsafe.Pointer)(ptr)) == nil { - newPtr := decoder.ValueType.UnsafeNew() - decoder.ValueDecoder.Decode(newPtr, extra) + newPtr := this.ValueType.UnsafeNew() + this.ValueDecoder.Decode(newPtr, extra) *((*unsafe.Pointer)(ptr)) = newPtr } else { - decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), extra) + this.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), extra) } } } @@ -47,37 +48,46 @@ type OptionalEncoder struct { ValueEncoder core.IEncoder } -func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { +func (this *OptionalEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { if *((*unsafe.Pointer)(ptr)) == nil { stream.WriteNil() } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + this.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) } } -func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { +func (this *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { return *((*unsafe.Pointer)(ptr)) == nil } +func (this *OptionalEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) { + if encoderMapJson, ok := this.ValueEncoder.(core.IEncoderMapJson); !ok { + err = fmt.Errorf("encoder %T not support EncodeToMapJson", this.ValueEncoder) + return + } else { + return encoderMapJson.EncodeToMapJson(ptr) + } +} + //reference-------------------------------------------------------------------------------------------------------------------- type referenceEncoder struct { encoder core.IEncoder } -func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { - encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +func (this *referenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { + this.encoder.Encode(unsafe.Pointer(&ptr), stream) } -func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +func (this *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return this.encoder.IsEmpty(unsafe.Pointer(&ptr)) } type referenceDecoder struct { decoder core.IDecoder } -func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { - decoder.decoder.Decode(unsafe.Pointer(&ptr), extra) +func (this *referenceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { + this.decoder.Decode(unsafe.Pointer(&ptr), extra) } //dereference-------------------------------------------------------------------------------------------------------------------- @@ -100,28 +110,28 @@ type dereferenceEncoder struct { ValueEncoder core.IEncoder } -func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { +func (this *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { if *((*unsafe.Pointer)(ptr)) == nil { stream.WriteNil() } else { - encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + this.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) } } -func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { +func (this *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { dePtr := *((*unsafe.Pointer)(ptr)) if dePtr == nil { return true } - return encoder.ValueEncoder.IsEmpty(dePtr) + return this.ValueEncoder.IsEmpty(dePtr) } -func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { +func (this *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { deReferenced := *((*unsafe.Pointer)(ptr)) if deReferenced == nil { return true } - isEmbeddedPtrNil, converted := encoder.ValueEncoder.(core.IsEmbeddedPtrNil) + isEmbeddedPtrNil, converted := this.ValueEncoder.(core.IsEmbeddedPtrNil) if !converted { return false } diff --git a/lego/sys/codec/factory/factory_slice.go b/lego/sys/codec/factory/factory_slice.go index 456e613ec..96871b600 100644 --- a/lego/sys/codec/factory/factory_slice.go +++ b/lego/sys/codec/factory/factory_slice.go @@ -1,6 +1,7 @@ package factory import ( + "errors" "fmt" "io" "unsafe" @@ -13,53 +14,80 @@ import ( func decoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IDecoder { sliceType := typ.(*reflect2.UnsafeSliceType) decoder := DecoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem()) - return &sliceDecoder{sliceType, decoder} + return &sliceDecoder{ctx.ICodec, sliceType, decoder} } func encoderOfSlice(ctx *core.Ctx, typ reflect2.Type) core.IEncoder { sliceType := typ.(*reflect2.UnsafeSliceType) encoder := EncoderOfType(ctx.Append("[sliceElem]"), sliceType.Elem()) - return &sliceEncoder{sliceType, encoder} + return &sliceEncoder{ctx.ICodec, sliceType, encoder} } type sliceEncoder struct { + codec core.ICodec sliceType *reflect2.UnsafeSliceType elemEncoder core.IEncoder } -func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { - if encoder.sliceType.UnsafeIsNil(ptr) { +func (this *sliceEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { + if this.sliceType.UnsafeIsNil(ptr) { stream.WriteNil() return } - length := encoder.sliceType.UnsafeLengthOf(ptr) + length := this.sliceType.UnsafeLengthOf(ptr) if length == 0 { stream.WriteEmptyArray() return } stream.WriteArrayStart() - encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) + this.elemEncoder.Encode(this.sliceType.UnsafeGetIndex(ptr, 0), stream) for i := 1; i < length; i++ { stream.WriteMemberSplit() - elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) - encoder.elemEncoder.Encode(elemPtr, stream) + elemPtr := this.sliceType.UnsafeGetIndex(ptr, i) + this.elemEncoder.Encode(elemPtr, stream) } stream.WriteArrayEnd() if stream.Error() != nil && stream.Error() != io.EOF { - stream.SetErr(fmt.Errorf("%v: %s", encoder.sliceType, stream.Error().Error())) + stream.SetErr(fmt.Errorf("%v: %s", this.sliceType, stream.Error().Error())) } } -func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { - return encoder.sliceType.UnsafeLengthOf(ptr) == 0 +func (this *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return this.sliceType.UnsafeLengthOf(ptr) == 0 +} + +//编码对象到json数组 +func (this *sliceEncoder) EncodeToSliceJson(ptr unsafe.Pointer) (ret []string, err error) { + if this.sliceType.UnsafeIsNil(ptr) { + err = errors.New("val is nil") + return + } + length := this.sliceType.UnsafeLengthOf(ptr) + ret = make([]string, length) + if length == 0 { + return + } + stream := this.codec.BorrowStream() + for i := 1; i < length; i++ { + elemPtr := this.sliceType.UnsafeGetIndex(ptr, i) + this.elemEncoder.Encode(elemPtr, stream) + if stream.Error() != nil && stream.Error() != io.EOF { + err = stream.Error() + return + } + ret[i] = BytesToString(stream.Buffer()) + stream.Reset(512) + } + return } type sliceDecoder struct { + codec core.ICodec sliceType *reflect2.UnsafeSliceType elemDecoder core.IDecoder } -func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { - sliceType := decoder.sliceType +func (this *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { + sliceType := this.sliceType if extra.ReadNil() { sliceType.UnsafeSetNil(ptr) return @@ -73,19 +101,39 @@ func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, extra core.IExtractor) { } sliceType.UnsafeGrow(ptr, 1) elemPtr := sliceType.UnsafeGetIndex(ptr, 0) - decoder.elemDecoder.Decode(elemPtr, extra) + this.elemDecoder.Decode(elemPtr, extra) length := 1 for extra.ReadMemberSplit() { idx := length length += 1 sliceType.UnsafeGrow(ptr, length) elemPtr = sliceType.UnsafeGetIndex(ptr, idx) - decoder.elemDecoder.Decode(elemPtr, extra) + this.elemDecoder.Decode(elemPtr, extra) } if extra.ReadArrayEnd() { return } if extra.Error() != nil && extra.Error() != io.EOF { - extra.SetErr(fmt.Errorf("%v: %s", decoder.sliceType, extra.Error().Error())) + extra.SetErr(fmt.Errorf("%v: %s", this.sliceType, extra.Error().Error())) } } + +func (this *sliceDecoder) DecodeForSliceJson(ptr unsafe.Pointer, data []string) (err error) { + sliceType := this.sliceType + if data == nil { + err = errors.New("extra is nil") + return + } + extra := this.codec.BorrowExtractor([]byte{}) + sliceType.UnsafeGrow(ptr, len(data)) + for i, v := range data { + elemPtr := sliceType.UnsafeGetIndex(ptr, i) + extra.ResetBytes(StringToBytes(v)) + this.elemDecoder.Decode(elemPtr, extra) + if extra.Error() != nil && extra.Error() != io.EOF { + err = extra.Error() + return + } + } + return +} diff --git a/lego/sys/codec/factory/factory_struct.go b/lego/sys/codec/factory/factory_struct.go index a3b653bbc..06ecb764f 100644 --- a/lego/sys/codec/factory/factory_struct.go +++ b/lego/sys/codec/factory/factory_struct.go @@ -273,7 +273,7 @@ func (this *structEncoder) Encode(ptr unsafe.Pointer, stream core.IStream) { } } -func (this *structEncoder) EncodeToMapString(ptr unsafe.Pointer) (ret map[string]string, err error) { +func (this *structEncoder) EncodeToMapJson(ptr unsafe.Pointer) (ret map[string]string, err error) { ret = make(map[string]string) stream := this.codec.BorrowStream() for _, field := range this.fields { @@ -348,7 +348,7 @@ func (this *structDecoder) decodeField(ptr unsafe.Pointer, extra core.IExtractor } //解码对象从MapJson 中 -func (this *structDecoder) DecodeForMapString(ptr unsafe.Pointer, extra map[string]string) (err error) { +func (this *structDecoder) DecodeForMapJson(ptr unsafe.Pointer, extra map[string]string) (err error) { var fieldDecoder *structFieldDecoder ext := this.codec.BorrowExtractor([]byte{}) for k, v := range extra { diff --git a/lego/sys/codec/options.go b/lego/sys/codec/options.go index 40c2cfc37..28b5cd723 100644 --- a/lego/sys/codec/options.go +++ b/lego/sys/codec/options.go @@ -2,6 +2,7 @@ package codec import ( "go_dreamfactory/lego/sys/codec/core" + "go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/utils/mapstructure" ) @@ -15,6 +16,9 @@ func newOptions(config map[string]interface{}, opts ...core.Option) core.Options for _, o := range opts { o(&options) } + if options.Debug && options.Log == nil { + options.Log = log.Clone() + } return options } @@ -25,5 +29,8 @@ func newOptionsByOption(opts ...core.Option) core.Options { for _, o := range opts { o(&options) } + if options.Debug && options.Log == nil { + options.Log = log.Clone() + } return options } diff --git a/lego/sys/codec/sys_test.go b/lego/sys/codec/sys_test.go index 3ec432333..50bb7bca4 100644 --- a/lego/sys/codec/sys_test.go +++ b/lego/sys/codec/sys_test.go @@ -19,7 +19,7 @@ type Test1Data struct { Value int } -func Test_sys(t *testing.T) { +func Test_sys_json(t *testing.T) { if err := log.OnInit(nil); err != nil { fmt.Printf("log init err:%v", err) return @@ -34,3 +34,21 @@ func Test_sys(t *testing.T) { fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err) } } + +func Test_sys_mapjson(t *testing.T) { + if err := log.OnInit(nil); err != nil { + fmt.Printf("log init err:%v", err) + return + } + if sys, err := codec.NewSys(); err != nil { + fmt.Printf("gin init err:%v", err) + } else { + m := map[string]interface{}{"liwe": 123, "aasd": "123"} + fmt.Printf("codec Marshal m:%s err:%v", m, err) + d, err := sys.MarshalMapJson(&TestData{Name: "http://liwei1dao.com?asd=1&dd=1", Value: 10, Array: []interface{}{1, "dajiahao", &Test1Data{Name: "liwe1dao", Value: 123}}, Data: map[string]interface{}{"hah": 1, "asd": 999}}) + fmt.Printf("codec Marshal d:%s err:%v", d, err) + data := &TestData{} + err = sys.UnmarshalMapJson(d, data) + fmt.Printf("codec UnmarshalJson data:%v err:%v", data, err) + } +} diff --git a/lego/sys/mgo/mgo.go b/lego/sys/mgo/mgo.go index f35e2fa7d..47bd1b5b6 100644 --- a/lego/sys/mgo/mgo.go +++ b/lego/sys/mgo/mgo.go @@ -9,7 +9,6 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "go.mongodb.org/mongo-driver/mongo/readconcern" "go.mongodb.org/mongo-driver/mongo/readpref" ) @@ -31,12 +30,12 @@ func (this *Mongodb) init() (err error) { // return fmt.Errorf("数据库设置辅助节点 err=%s", err.Error()) // } // wc := writeconcern.New(writeconcern.W(1)) - readconcern.Majority() + // readconcern.Majority() //链接mongo服务 opt := options.Client().ApplyURI(this.options.MongodbUrl) // opt.SetLocalThreshold(3 * time.Second) //只使用与mongo操作耗时小于3秒的 // opt.SetMaxConnIdleTime(5 * time.Second) //指定连接可以保持空闲的最大毫秒数 - opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数 + // opt.SetMaxPoolSize(this.options.MaxPoolSize) //使用最大的连接数 // opt.SetReadPreference(want) //表示只使用辅助节点 // opt.SetReadConcern(readconcern.Majority()) //指定查询应返回实例的最新数据确认为,已写入副本集中的大多数成员 // opt.SetWriteConcern(wc) //请求确认写操作传播到大多数mongod实例 @@ -48,7 +47,6 @@ func (this *Mongodb) init() (err error) { return fmt.Errorf("数据库不可用 err=%s", err.Error()) } this.Database = client.Database(this.options.MongodbDatabase) - } return } diff --git a/lego/sys/redis/cluster/core.go b/lego/sys/redis/cluster/core.go index 3c5148b85..bfc85f786 100644 --- a/lego/sys/redis/cluster/core.go +++ b/lego/sys/redis/cluster/core.go @@ -2,15 +2,14 @@ package cluster import ( "context" - "go_dreamfactory/lego/utils/codec" + "go_dreamfactory/lego/sys/redis/core" "time" "github.com/go-redis/redis/v8" ) func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration, - encode codec.IEncoder, - decode codec.IDecoder, + codec core.ICodec, ) (sys *Redis, err error) { var ( client *redis.ClusterClient @@ -22,8 +21,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration, sys = &Redis{ client: client, timeOut: timeOut, - encode: encode, - decode: decode, + codec: codec, } _, err = sys.Ping() return @@ -32,8 +30,7 @@ func NewSys(RedisUrl []string, RedisPassword string, timeOut time.Duration, type Redis struct { client *redis.ClusterClient timeOut time.Duration - encode codec.IEncoder - decode codec.IDecoder + codec core.ICodec } func (this *Redis) getContext() (ctx context.Context) { diff --git a/lego/sys/redis/cluster/hash.go b/lego/sys/redis/cluster/hash.go index 55bed3662..db0bdae6a 100644 --- a/lego/sys/redis/cluster/hash.go +++ b/lego/sys/redis/cluster/hash.go @@ -36,7 +36,7 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) { agrs = append(agrs, "HMSET") agrs = append(agrs, key) var data map[string]string - if data, err = this.encode.EncoderToMapString(v); err != nil { + if data, err = this.codec.MarshalMap(v); err != nil { return } for k, v := range data { @@ -52,13 +52,13 @@ Redis Hget 命令用于返回哈希表中指定字段的值 func (this *Redis) HGet(key string, field string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { + var _result []byte + if _result, err = cmd.Bytes(); err == nil { if len(_result) == 0 { err = redis.Nil return } - err = this.decode.DecoderString(_result, v) + err = this.codec.Unmarshal(_result, v) } return } @@ -76,7 +76,7 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) { err = redis.Nil return } - err = this.decode.DecoderMapString(_result, v) + err = this.codec.UnmarshalMap(_result, v) } return } @@ -140,7 +140,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error err = redis.Nil return } - err = this.decode.DecoderMapString(_result, v) + err = this.codec.UnmarshalMap(_result, v) } return } @@ -152,7 +152,7 @@ Redis Hset 命令用于为哈希表中的字段赋值 */ func (this *Redis) HSet(key string, field string, value interface{}) (err error) { var resultvalue []byte - if resultvalue, err = this.encode.Encoder(value); err == nil { + if resultvalue, err = this.codec.Marshal(value); err == nil { err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err() } return @@ -166,7 +166,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值 */ func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) { var resultvalue []byte - if resultvalue, err = this.encode.Encoder(value); err == nil { + if resultvalue, err = this.codec.Marshal(value); err == nil { err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err() } return diff --git a/lego/sys/redis/cluster/list.go b/lego/sys/redis/cluster/list.go index b141c485b..537960f39 100644 --- a/lego/sys/redis/cluster/list.go +++ b/lego/sys/redis/cluster/list.go @@ -10,13 +10,13 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使 func (this *Redis) Lindex(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { + var _result []byte + if _result, err = cmd.Bytes(); err == nil { if len(_result) == 0 { err = redis.Nil return } - err = this.decode.DecoderString(_result, v) + err = this.codec.Unmarshal(_result, v) } return } @@ -28,13 +28,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定 */ func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) { var ( - tagervalue string - resultvalue string + tagervalue []byte + resultvalue []byte ) - if tagervalue, err = this.encode.EncoderString(tager); err != nil { + if tagervalue, err = this.codec.Marshal(tager); err != nil { return } - if resultvalue, err = this.encode.EncoderString(value); err != nil { + if resultvalue, err = this.codec.Marshal(value); err != nil { return } if isbefore { @@ -59,9 +59,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素 func (this *Redis) LPop(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "LPOP", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -73,7 +73,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "LPUSH") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -87,7 +87,7 @@ func (this *Redis) LPushX(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "LPUSHX") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -103,7 +103,7 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error) cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end) this.client.Process(this.getContext(), cmd) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -116,8 +116,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素, count = 0 : 移除表中所有与 VALUE 相等的值 */ func (this *Redis) LRem(key string, count int, target interface{}) (err error) { - var resultvalue string - if resultvalue, err = this.encode.EncoderString(target); err != nil { + var resultvalue []byte + if resultvalue, err = this.codec.Marshal(target); err != nil { return } err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err() @@ -129,8 +129,8 @@ Redis Lset 通过索引来设置元素的值。 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误 */ func (this *Redis) LSet(key string, index int, value interface{}) (err error) { - var resultvalue string - if resultvalue, err = this.encode.EncoderString(value); err == nil { + var resultvalue []byte + if resultvalue, err = this.codec.Marshal(value); err == nil { return } err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err() @@ -153,9 +153,9 @@ Redis Rpop 命令用于移除列表的最后一个元素,返回值为移除的 func (this *Redis) Rpop(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "RPOP", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -166,9 +166,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素 func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -182,7 +182,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "RPUSH") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -196,7 +196,7 @@ func (this *Redis) RPushX(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "RPUSHX") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() diff --git a/lego/sys/redis/cluster/set.go b/lego/sys/redis/cluster/set.go index 70d20fc6a..9571b72d0 100644 --- a/lego/sys/redis/cluster/set.go +++ b/lego/sys/redis/cluster/set.go @@ -10,7 +10,7 @@ func (this *Redis) SAdd(key string, values ...interface{}) (err error) { agrs = append(agrs, "SADD") agrs = append(agrs, key) for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -34,7 +34,7 @@ func (this *Redis) SDiff(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SDiff(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SInter(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) { var _result []string cmd := this.client.SMembers(this.getContext(), key) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SUnion(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } diff --git a/lego/sys/redis/cluster/string.go b/lego/sys/redis/cluster/string.go index ecc6e1798..53ddd76cb 100644 --- a/lego/sys/redis/cluster/string.go +++ b/lego/sys/redis/cluster/string.go @@ -11,8 +11,8 @@ import ( 命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。 */ func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) { - var result string - if result, err = this.encode.EncoderString(value); err != nil { + var result []byte + if result, err = this.codec.Marshal(value); err != nil { return } err = this.client.Set(this.getContext(), key, result, expiration).Err() @@ -37,7 +37,7 @@ func (this *Redis) MSet(v map[string]interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "MSET") for k, v := range v { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, k, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -51,7 +51,7 @@ func (this *Redis) MSetNX(v map[string]interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "MSETNX") for k, v := range v { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, k, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。 */ func (this *Redis) Append(key string, value interface{}) (err error) { - var result string - if result, err = this.encode.EncoderString(value); err != nil { + var result []byte + if result, err = this.codec.Marshal(value); err != nil { return } err = this.client.Do(this.getContext(), "APPEND", key, result).Err() @@ -129,9 +129,9 @@ func (this *Redis) Append(key string, value interface{}) (err error) { 命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型 */ func (this *Redis) Get(key string, value interface{}) (err error) { - var result string - if result, err = this.client.Get(this.getContext(), key).Result(); err == nil { - err = this.decode.DecoderString(result, value) + var result []byte + if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil { + err = this.codec.Unmarshal(result, value) } return } @@ -141,14 +141,14 @@ func (this *Redis) Get(key string, value interface{}) (err error) { */ func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) { var ( - _value string + _value []byte ) - if _value, err = this.encode.EncoderString(value); err == nil { + if _value, err = this.codec.Marshal(value); err == nil { cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, result) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, result) } } return @@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) { if result, err = cmd.Result(); err != nil { return } - err = this.decode.DecoderSliceString(result, v) + err = this.codec.UnmarshalSlice(result, v) return } diff --git a/lego/sys/redis/cluster/zset.go b/lego/sys/redis/cluster/zset.go index a69bc7270..ca82e6140 100644 --- a/lego/sys/redis/cluster/zset.go +++ b/lego/sys/redis/cluster/zset.go @@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e var _result []string cmd := this.client.ZRange(this.getContext(), key, start, stop) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) ( var _result []string cmd := this.client.ZRangeByLex(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{}) var _result []string cmd := this.client.ZRangeByScore(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{}) var _result []string cmd := this.client.ZRevRange(this.getContext(), key, start, stop) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface var _result []string cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } diff --git a/lego/sys/redis/core/core.go b/lego/sys/redis/core/core.go new file mode 100644 index 000000000..d99eb3f1c --- /dev/null +++ b/lego/sys/redis/core/core.go @@ -0,0 +1,12 @@ +package core + +type ( + ICodec interface { + Marshal(v interface{}) ([]byte, error) + Unmarshal(data []byte, v interface{}) error + MarshalMap(val interface{}) (ret map[string]string, err error) + UnmarshalMap(data map[string]string, val interface{}) (err error) + MarshalSlice(val interface{}) (ret []string, err error) + UnmarshalSlice(data []string, val interface{}) (err error) + } +) diff --git a/lego/sys/redis/options.go b/lego/sys/redis/options.go index 427ec10ac..3e097668c 100644 --- a/lego/sys/redis/options.go +++ b/lego/sys/redis/options.go @@ -3,6 +3,7 @@ package redis import ( "time" + "go_dreamfactory/lego/sys/redis/core" "go_dreamfactory/lego/utils/mapstructure" ) @@ -13,14 +14,6 @@ const ( Redis_Cluster ) -///redis 存储数据格式化类型 -type RedisStorageTyoe int8 - -const ( - JsonData RedisStorageTyoe = iota - ProtoData -) - type Option func(*Options) type Options struct { RedisType RedisType @@ -30,8 +23,8 @@ type Options struct { Redis_Single_PoolSize int Redis_Cluster_Addr []string Redis_Cluster_Password string - RedisStorageType RedisStorageTyoe TimeOut time.Duration + Codec core.ICodec } func SetRedisType(v RedisType) Option { @@ -74,11 +67,6 @@ func SetRedis_Cluster_Password(v string) Option { o.Redis_Cluster_Password = v } } -func SetRedisStorageType(v RedisStorageTyoe) Option { - return func(o *Options) { - o.RedisStorageType = v - } -} func SetTimeOut(v time.Duration) Option { return func(o *Options) { @@ -86,6 +74,12 @@ func SetTimeOut(v time.Duration) Option { } } +func SetCodec(v core.ICodec) Option { + return func(o *Options) { + o.Codec = v + } +} + func newOptions(config map[string]interface{}, opts ...Option) Options { options := Options{ Redis_Single_Addr: "127.0.0.1:6379", diff --git a/lego/sys/redis/redis.go b/lego/sys/redis/redis.go index ab119af6b..30d4c87da 100644 --- a/lego/sys/redis/redis.go +++ b/lego/sys/redis/redis.go @@ -5,25 +5,15 @@ import ( "fmt" "time" - jsoniter "github.com/json-iterator/go" - + "go_dreamfactory/lego/sys/codec" "go_dreamfactory/lego/sys/redis/cluster" "go_dreamfactory/lego/sys/redis/single" - "go_dreamfactory/lego/utils/codec" "github.com/go-redis/redis/v8" - "google.golang.org/protobuf/proto" ) func newSys(options Options) (sys *Redis, err error) { sys = &Redis{options: options} - if options.RedisStorageType == JsonData { - sys.decoder = &codec.Decoder{DefDecoder: jsoniter.Unmarshal} - sys.encoder = &codec.Encoder{DefEncoder: jsoniter.Marshal} - } else { - sys.decoder = &codec.Decoder{DefDecoder: func(buf []byte, v interface{}) error { return proto.Unmarshal(buf, v.(proto.Message)) }} - sys.encoder = &codec.Encoder{DefEncoder: func(v interface{}) (data []byte, err error) { return proto.Marshal(v.(proto.Message)) }} - } err = sys.init() return } @@ -31,8 +21,6 @@ func newSys(options Options) (sys *Redis, err error) { type Redis struct { options Options client IRedis - decoder codec.IDecoder - encoder codec.IEncoder } func (this *Redis) init() (err error) { @@ -43,16 +31,14 @@ func (this *Redis) init() (err error) { this.options.Redis_Single_DB, this.options.Redis_Single_PoolSize, this.options.TimeOut, - this.encoder, - this.decoder, + this, ) } else if this.options.RedisType == Redis_Cluster { this.client, err = cluster.NewSys( this.options.Redis_Cluster_Addr, this.options.Redis_Cluster_Password, this.options.TimeOut, - this.encoder, - this.decoder, + this, ) } else { err = fmt.Errorf("init Redis err:RedisType - %d", this.options.RedisType) @@ -360,3 +346,47 @@ func (this *Redis) ZUnionStore(dest string, store *redis.ZStore) (result int64, func (this *Redis) ZScan(key string, _cursor uint64, match string, count int64) (keys []string, cursor uint64, err error) { return this.client.ZScan(key, _cursor, match, count) } + +//Codec--------------------------------------------------------------------------------------------------------------------------------------- +func (this *Redis) Marshal(v interface{}) ([]byte, error) { + if this.options.Codec != nil { + return this.options.Codec.Marshal(v) + } else { + return codec.MarshalJson(v) + } +} +func (this *Redis) Unmarshal(data []byte, v interface{}) error { + if this.options.Codec != nil { + return this.options.Codec.Unmarshal(data, v) + } else { + return codec.UnmarshalJson(data, v) + } +} +func (this *Redis) MarshalMap(val interface{}) (ret map[string]string, err error) { + if this.options.Codec != nil { + return this.options.Codec.MarshalMap(val) + } else { + return codec.MarshalMapJson(val) + } +} +func (this *Redis) UnmarshalMap(data map[string]string, val interface{}) (err error) { + if this.options.Codec != nil { + return this.options.Codec.UnmarshalMap(data, val) + } else { + return codec.UnmarshalMapJson(data, val) + } +} +func (this *Redis) MarshalSlice(val interface{}) (ret []string, err error) { + if this.options.Codec != nil { + return this.options.Codec.MarshalSlice(val) + } else { + return codec.MarshalSliceJson(val) + } +} +func (this *Redis) UnmarshalSlice(data []string, val interface{}) (err error) { + if this.options.Codec != nil { + return this.options.Codec.UnmarshalSlice(data, val) + } else { + return codec.UnmarshalSliceJson(data, val) + } +} diff --git a/lego/sys/redis/single/core.go b/lego/sys/redis/single/core.go index 74899c5c1..58dd8c807 100644 --- a/lego/sys/redis/single/core.go +++ b/lego/sys/redis/single/core.go @@ -2,15 +2,14 @@ package single import ( "context" - "go_dreamfactory/lego/utils/codec" + "go_dreamfactory/lego/sys/redis/core" "time" "github.com/go-redis/redis/v8" ) func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time.Duration, - encode codec.IEncoder, - decode codec.IDecoder, + codec core.ICodec, ) (sys *Redis, err error) { var ( client *redis.Client @@ -24,8 +23,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time. sys = &Redis{ client: client, timeOut: timeOut, - encode: encode, - decode: decode, + codec: codec, } _, err = sys.Ping() return @@ -34,8 +32,7 @@ func NewSys(RedisUrl, RedisPassword string, RedisDB, PoolSize int, timeOut time. type Redis struct { client *redis.Client timeOut time.Duration - encode codec.IEncoder - decode codec.IDecoder + codec core.ICodec } func (this *Redis) getContext() (ctx context.Context) { diff --git a/lego/sys/redis/single/hash.go b/lego/sys/redis/single/hash.go index d37c24f05..bc418451c 100644 --- a/lego/sys/redis/single/hash.go +++ b/lego/sys/redis/single/hash.go @@ -36,7 +36,7 @@ func (this *Redis) HMSet(key string, v interface{}) (err error) { agrs = append(agrs, "HMSET") agrs = append(agrs, key) var data map[string]string - if data, err = this.encode.EncoderToMapString(v); err != nil { + if data, err = this.codec.MarshalMap(v); err != nil { return } for k, v := range data { @@ -52,9 +52,9 @@ Redis Hget 命令用于返回哈希表中指定字段的值 func (this *Redis) HGet(key string, field string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "HGET", key, field) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -71,7 +71,7 @@ func (this *Redis) HGetAll(key string, v interface{}) (err error) { if len(_result) == 0 { return redis.Nil } - err = this.decode.DecoderMapString(_result, v) + err = this.codec.UnmarshalMap(_result, v) } return } @@ -131,7 +131,7 @@ func (this *Redis) HMGet(key string, v interface{}, fields ...string) (err error this.client.Process(this.getContext(), cmd) var _result map[string]string if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderMapString(_result, v) + err = this.codec.UnmarshalMap(_result, v) } return } @@ -143,7 +143,7 @@ Redis Hset 命令用于为哈希表中的字段赋值 */ func (this *Redis) HSet(key string, field string, value interface{}) (err error) { var resultvalue []byte - if resultvalue, err = this.encode.Encoder(value); err == nil { + if resultvalue, err = this.codec.Marshal(value); err == nil { err = this.client.Do(this.getContext(), "HSET", key, field, resultvalue).Err() } return @@ -157,7 +157,7 @@ Redis Hsetnx 命令用于为哈希表中不存在的的字段赋值 */ func (this *Redis) HSetNX(key string, field string, value interface{}) (err error) { var resultvalue []byte - if resultvalue, err = this.encode.Encoder(value); err == nil { + if resultvalue, err = this.codec.Marshal(value); err == nil { err = this.client.Do(this.getContext(), "HSETNX", key, field, resultvalue).Err() } return diff --git a/lego/sys/redis/single/list.go b/lego/sys/redis/single/list.go index 0123cc821..7cdc71f82 100644 --- a/lego/sys/redis/single/list.go +++ b/lego/sys/redis/single/list.go @@ -10,9 +10,9 @@ Redis Lindex 命令用于通过索引获取列表中的元素。你也可以使 func (this *Redis) Lindex(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "LINDEX", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -24,13 +24,13 @@ Redis Linsert 命令用于在列表的元素前或者后插入元素。当指定 */ func (this *Redis) Linsert(key string, isbefore bool, tager interface{}, value interface{}) (err error) { var ( - tagervalue string - resultvalue string + tagervalue []byte + resultvalue []byte ) - if tagervalue, err = this.encode.EncoderString(tager); err != nil { + if tagervalue, err = this.codec.Marshal(tager); err != nil { return } - if resultvalue, err = this.encode.EncoderString(value); err != nil { + if resultvalue, err = this.codec.Marshal(value); err != nil { return } if isbefore { @@ -55,9 +55,9 @@ Redis Lpop 命令用于移除并返回列表的第一个元素 func (this *Redis) LPop(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "LPOP", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -69,7 +69,7 @@ func (this *Redis) LPush(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "LPUSH") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -83,7 +83,7 @@ func (this *Redis) LPushX(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "LPUSHX") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -99,7 +99,7 @@ func (this *Redis) LRange(key string, start, end int, v interface{}) (err error) cmd := redis.NewStringSliceCmd(this.getContext(), "LRANGE", key, start, end) this.client.Process(this.getContext(), cmd) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -112,8 +112,8 @@ count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素, count = 0 : 移除表中所有与 VALUE 相等的值 */ func (this *Redis) LRem(key string, count int, target interface{}) (err error) { - var resultvalue string - if resultvalue, err = this.encode.EncoderString(target); err != nil { + var resultvalue []byte + if resultvalue, err = this.codec.Marshal(target); err != nil { return } err = this.client.Do(this.getContext(), "LREM", key, count, resultvalue).Err() @@ -125,8 +125,8 @@ Redis Lset 通过索引来设置元素的值。 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误 */ func (this *Redis) LSet(key string, index int, value interface{}) (err error) { - var resultvalue string - if resultvalue, err = this.encode.EncoderString(value); err == nil { + var resultvalue []byte + if resultvalue, err = this.codec.Marshal(value); err == nil { return } err = this.client.Do(this.getContext(), "LSET", key, index, resultvalue).Err() @@ -149,9 +149,9 @@ Redis Rpop 命令用于移除列表的最后一个元素,返回值为移除的 func (this *Redis) Rpop(key string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "RPOP", key) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -162,9 +162,9 @@ Redis Rpoplpush 命令用于移除列表的最后一个元素,并将该元素 func (this *Redis) RPopLPush(oldkey string, newkey string, v interface{}) (err error) { cmd := redis.NewStringCmd(this.getContext(), "RPOPLPUSH", oldkey, newkey) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, v) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, v) } return } @@ -178,7 +178,7 @@ func (this *Redis) RPush(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "RPUSH") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -192,7 +192,7 @@ func (this *Redis) RPushX(key string, values ...interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "RPUSHX") for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() diff --git a/lego/sys/redis/single/set.go b/lego/sys/redis/single/set.go index 14a345666..5f5678d4f 100644 --- a/lego/sys/redis/single/set.go +++ b/lego/sys/redis/single/set.go @@ -10,7 +10,7 @@ func (this *Redis) SAdd(key string, values ...interface{}) (err error) { agrs = append(agrs, "SADD") agrs = append(agrs, key) for _, v := range values { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -34,7 +34,7 @@ func (this *Redis) SDiff(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SDiff(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -54,7 +54,7 @@ func (this *Redis) SInter(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SInter(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -82,7 +82,7 @@ func (this *Redis) SMembers(v interface{}, key string) (err error) { var _result []string cmd := this.client.SMembers(this.getContext(), key) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -137,7 +137,7 @@ func (this *Redis) SUnion(v interface{}, keys ...string) (err error) { var _result []string cmd := this.client.SUnion(this.getContext(), keys...) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } diff --git a/lego/sys/redis/single/string.go b/lego/sys/redis/single/string.go index ec63e2d6f..e894a84d3 100644 --- a/lego/sys/redis/single/string.go +++ b/lego/sys/redis/single/string.go @@ -11,8 +11,8 @@ import ( 命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。 */ func (this *Redis) Set(key string, value interface{}, expiration time.Duration) (err error) { - var result string - if result, err = this.encode.EncoderString(value); err != nil { + var result []byte + if result, err = this.codec.Marshal(value); err != nil { return } err = this.client.Set(this.getContext(), key, result, expiration).Err() @@ -37,7 +37,7 @@ func (this *Redis) MSet(v map[string]interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "MSET") for k, v := range v { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, k, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -51,7 +51,7 @@ func (this *Redis) MSetNX(v map[string]interface{}) (err error) { agrs := make([]interface{}, 0) agrs = append(agrs, "MSETNX") for k, v := range v { - result, _ := this.encode.EncoderString(v) + result, _ := this.codec.Marshal(v) agrs = append(agrs, k, result) } err = this.client.Do(this.getContext(), agrs...).Err() @@ -117,8 +117,8 @@ Redis Append 命令用于为指定的 key 追加值。 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。 */ func (this *Redis) Append(key string, value interface{}) (err error) { - var result string - if result, err = this.encode.EncoderString(value); err != nil { + var result []byte + if result, err = this.codec.Marshal(value); err != nil { return } err = this.client.Do(this.getContext(), "APPEND", key, result).Err() @@ -129,9 +129,9 @@ func (this *Redis) Append(key string, value interface{}) (err error) { 命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型 */ func (this *Redis) Get(key string, value interface{}) (err error) { - var result string - if result, err = this.client.Get(this.getContext(), key).Result(); err == nil { - err = this.decode.DecoderString(result, value) + var result []byte + if result, err = this.client.Get(this.getContext(), key).Bytes(); err == nil { + err = this.codec.Unmarshal(result, value) } return } @@ -141,14 +141,14 @@ func (this *Redis) Get(key string, value interface{}) (err error) { */ func (this *Redis) GetSet(key string, value interface{}, result interface{}) (err error) { var ( - _value string + _value []byte ) - if _value, err = this.encode.EncoderString(value); err == nil { + if _value, err = this.codec.Marshal(value); err == nil { cmd := redis.NewStringCmd(this.getContext(), "GETSET", key, _value) this.client.Process(this.getContext(), cmd) - var _result string - if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderString(_result, result) + var _result []byte + if _result, err = cmd.Bytes(); err == nil { + err = this.codec.Unmarshal(_result, result) } } return @@ -169,7 +169,7 @@ func (this *Redis) MGet(v interface{}, keys ...string) (err error) { if result, err = cmd.Result(); err != nil { return } - err = this.decode.DecoderSliceString(result, v) + err = this.codec.UnmarshalSlice(result, v) return } diff --git a/lego/sys/redis/single/zset.go b/lego/sys/redis/single/zset.go index cf447b19c..e4c264e13 100644 --- a/lego/sys/redis/single/zset.go +++ b/lego/sys/redis/single/zset.go @@ -59,7 +59,7 @@ func (this *Redis) ZRange(key string, start int64, stop int64, v interface{}) (e var _result []string cmd := this.client.ZRange(this.getContext(), key, start, stop) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -71,7 +71,7 @@ func (this *Redis) ZRangeByLex(key string, opt *redis.ZRangeBy, v interface{}) ( var _result []string cmd := this.client.ZRangeByLex(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -83,7 +83,7 @@ func (this *Redis) ZRangeByScore(key string, opt *redis.ZRangeBy, v interface{}) var _result []string cmd := this.client.ZRangeByScore(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -135,7 +135,7 @@ func (this *Redis) ZRevRange(key string, start int64, stop int64, v interface{}) var _result []string cmd := this.client.ZRevRange(this.getContext(), key, start, stop) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } @@ -147,7 +147,7 @@ func (this *Redis) ZRevRangeByScore(key string, opt *redis.ZRangeBy, v interface var _result []string cmd := this.client.ZRevRangeByScore(this.getContext(), key, opt) if _result, err = cmd.Result(); err == nil { - err = this.decode.DecoderSliceString(_result, v) + err = this.codec.UnmarshalSlice(_result, v) } return } diff --git a/lego/sys/redis/sys_test.go b/lego/sys/redis/sys_test.go index 3d690774c..522ca0f87 100644 --- a/lego/sys/redis/sys_test.go +++ b/lego/sys/redis/sys_test.go @@ -16,7 +16,6 @@ func TestMain(m *testing.M) { redis.SetRedisType(redis.Redis_Cluster), redis.SetRedis_Cluster_Addr([]string{"10.0.0.9:9001", "10.0.0.9:9002", "10.0.0.9:9003", "10.0.1.45:9004", "10.0.1.45:9005", "10.0.1.45:9006"}), redis.SetRedis_Cluster_Password(""), - redis.SetRedisStorageType(redis.JsonData), ); err != nil { fmt.Println("err:", err) return diff --git a/sys/db/benchmark/query_test.go b/sys/db/benchmark/query_test.go index b9cb055a6..8310ca8e9 100644 --- a/sys/db/benchmark/query_test.go +++ b/sys/db/benchmark/query_test.go @@ -50,6 +50,15 @@ func TestMain(m *testing.M) { defer os.Exit(m.Run()) } +func Test_GetList(t *testing.T) { + heroes := []*DBHero{} + GetList(&heroes) +} +func Test_GetList0(t *testing.T) { + heroes := []*DBHero{} + GetListO(&heroes) +} + func BenchmarkMarsh(b *testing.B) { var ( @@ -112,7 +121,7 @@ func GetList(data interface{}) (err error) { //query from mgo // if c, err = mdb.Mgo().Find(core.SqlTable("hero"), bson.M{}); err != nil { - if c, err = mgoDb.Collection("hreo").Find(context.Background(), bson.M{}); err != nil { + if c, err = mgoDb.Collection("hero").Find(context.Background(), bson.M{}); err != nil { return err } else { var temp map[string]interface{} = make(map[string]interface{}) @@ -270,7 +279,9 @@ func BenchmarkSimple(b *testing.B) { // f, _ := os.Create("c://pprof2") // pprof.WriteHeapProfile(f) // defer f.Close() + heroes := []*DBHero{} for i := 0; i < b.N; i++ { - GetList4(new(DBHero)) + // GetList4(new(DBHero)) + GetList(&heroes) } }