implemented interface gob encode and decode for redit cacher
This commit is contained in:
parent
40f3ddd819
commit
4c93eaf1f4
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/garyburd/redigo/redis"
|
"github.com/garyburd/redigo/redis"
|
||||||
//"github.com/go-xorm/core"
|
//"github.com/go-xorm/core"
|
||||||
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -86,11 +87,15 @@ func (c *RedisCacher) getObject(key string) interface{} {
|
||||||
if raw == nil {
|
if raw == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err = redis.Bytes(raw, err) // TODO: item, err := redis.Bytes(raw, err)
|
item, err := redis.Bytes(raw, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
log.Fatalf("xorm/cache: redis.Bytes failed: %s", err)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return nil //Deserialize(item, ptrValue) // TODO
|
|
||||||
|
value, err := Deserialize(item)
|
||||||
|
|
||||||
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RedisCacher) GetIds(tableName, sql string) interface{} {
|
func (c *RedisCacher) GetIds(tableName, sql string) interface{} {
|
||||||
|
@ -197,10 +202,12 @@ func Serialize(value interface{}) ([]byte, error) {
|
||||||
return []byte(strconv.FormatUint(v.Uint(), 10)), nil
|
return []byte(strconv.FormatUint(v.Uint(), 10)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegisterGobConcreteType(value)
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
encoder := gob.NewEncoder(&b)
|
encoder := gob.NewEncoder(&b)
|
||||||
if err := encoder.Encode(value); err != nil {
|
if err := interfaceEncode(encoder, value); err != nil {
|
||||||
// revel.ERROR.Printf("revel/cache: gob encoding '%s' failed: %s", value, err)
|
log.Fatalf("xorm/cache: gob encoding '%s' failed: %s", value, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b.Bytes(), nil
|
return b.Bytes(), nil
|
||||||
|
@ -208,7 +215,7 @@ func Serialize(value interface{}) ([]byte, error) {
|
||||||
|
|
||||||
// Deserialize transforms bytes produced by Serialize back into a Go object,
|
// Deserialize transforms bytes produced by Serialize back into a Go object,
|
||||||
// storing it into "ptr", which must be a pointer to the value type.
|
// storing it into "ptr", which must be a pointer to the value type.
|
||||||
func Deserialize(byt []byte, ptr interface{}) (err error) {
|
func Deserialize(byt []byte) (ptr interface{}, err error) {
|
||||||
if bytes, ok := ptr.(*[]byte); ok {
|
if bytes, ok := ptr.(*[]byte); ok {
|
||||||
*bytes = byt
|
*bytes = byt
|
||||||
return
|
return
|
||||||
|
@ -220,7 +227,7 @@ func Deserialize(byt []byte, ptr interface{}) (err error) {
|
||||||
var i int64
|
var i int64
|
||||||
i, err = strconv.ParseInt(string(byt), 10, 64)
|
i, err = strconv.ParseInt(string(byt), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// revel.ERROR.Printf("revel/cache: failed to parse int '%s': %s", string(byt), err)
|
log.Fatalf("xorm/cache: failed to parse int '%s': %s", string(byt), err)
|
||||||
} else {
|
} else {
|
||||||
p.SetInt(i)
|
p.SetInt(i)
|
||||||
}
|
}
|
||||||
|
@ -230,7 +237,7 @@ func Deserialize(byt []byte, ptr interface{}) (err error) {
|
||||||
var i uint64
|
var i uint64
|
||||||
i, err = strconv.ParseUint(string(byt), 10, 64)
|
i, err = strconv.ParseUint(string(byt), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// revel.ERROR.Printf("revel/cache: failed to parse uint '%s': %s", string(byt), err)
|
log.Fatalf("xorm/cache: failed to parse uint '%s': %s", string(byt), err)
|
||||||
} else {
|
} else {
|
||||||
p.SetUint(i)
|
p.SetUint(i)
|
||||||
}
|
}
|
||||||
|
@ -240,9 +247,57 @@ func Deserialize(byt []byte, ptr interface{}) (err error) {
|
||||||
|
|
||||||
b := bytes.NewBuffer(byt)
|
b := bytes.NewBuffer(byt)
|
||||||
decoder := gob.NewDecoder(b)
|
decoder := gob.NewDecoder(b)
|
||||||
if err = decoder.Decode(ptr); err != nil {
|
|
||||||
// revel.ERROR.Printf("revel/cache: gob decoding failed: %s", err)
|
if ptr, err = interfaceDecode(decoder); err != nil {
|
||||||
|
log.Fatalf("xorm/cache: gob decoding failed: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegisterGobConcreteType(value interface{}) {
|
||||||
|
|
||||||
|
t := reflect.TypeOf(value)
|
||||||
|
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
v := reflect.ValueOf(value)
|
||||||
|
i := v.Elem().Interface()
|
||||||
|
gob.Register(i)
|
||||||
|
case reflect.Struct:
|
||||||
|
gob.Register(value)
|
||||||
|
case reflect.Slice:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Map:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unhandled type: %v", t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interfaceEncode encodes the interface value into the encoder.
|
||||||
|
func interfaceEncode(enc *gob.Encoder, p interface{}) error {
|
||||||
|
// The encode will fail unless the concrete type has been
|
||||||
|
// registered. We registered it in the calling function.
|
||||||
|
|
||||||
|
// Pass pointer to interface so Encode sees (and hence sends) a value of
|
||||||
|
// interface type. If we passed p directly it would see the concrete type instead.
|
||||||
|
// See the blog post, "The Laws of Reflection" for background.
|
||||||
|
err := enc.Encode(&p)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("encode:", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// interfaceDecode decodes the next interface value from the stream and returns it.
|
||||||
|
func interfaceDecode(dec *gob.Decoder) (interface{}, error) {
|
||||||
|
// The decode will fail unless the concrete type on the wire has been
|
||||||
|
// registered. We registered it in the calling function.
|
||||||
|
var p interface{}
|
||||||
|
err := dec.Decode(&p)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("decode:", err)
|
||||||
|
}
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue