线上使用的couchbase被他们长期使用不标准的数据写入,导致gocb的get无法正常的解析数据,只能获取其原始二进制数据自己解析了。gocb文档和源码里都没有找到get原始二进制数据的办法。于是只好去抄gocb里的源码来改了。
方法一重新实现get
package main
import (
"fmt"
"gopkg.in/couchbase/gocb.v1"
"gopkg.in/couchbase/gocbcore.v2"
"time"
)
func GetRaw(agent *gocbcore.Agent, key string) (byteOut []byte, casOut gocbcore.Cas, errOut error) {
signal := make(chan bool, 1)
op, err := agent.Get([]byte(key), func(bytes []byte, flags uint32, cas gocbcore.Cas, err error) {
if errOut == nil {
casOut = cas
byteOut = bytes
}
signal <- true
})
if err != nil {
return nil, 0, err
}
opTimeout := 2500 * time.Millisecond
timeoutTmr := gocbcore.AcquireTimer(opTimeout)
select {
case <-signal:
gocbcore.ReleaseTimer(timeoutTmr, false)
return
case <-timeoutTmr.C:
gocbcore.ReleaseTimer(timeoutTmr, true)
if !op.Cancel() {
<-signal
return
}
return nil, 0, fmt.Errorf("Timeout")
}
}
func main() {
// For example
myCluster, _ := gocb.Connect("couchbase://127.0.0.1")
myBucket, _ := myCluster.OpenBucket("default", "")
agent := myBucket.IoRouter()
by, a, e := GetRaw(agent, "a_key")
fmt.Println(k, len(by), a, e)
agent.Close()
}
方法二实在一个新的transcoder
package main
import (
"fmt"
"gopkg.in/couchbase/gocb.v1"
"gopkg.in/couchbase/gocbcore.v2"
)
type BytesTranscoder struct{}
// Decode applies the default Couchbase transcoding behaviour to decode into a Go byte slice.
func (t BytesTranscoder) Decode(bytes []byte, flags uint32, out interface{}) error {
switch typedOut := out.(type) {
case *[]byte:
*typedOut = bytes
return nil
case *interface{}:
*typedOut = bytes
return nil
case *string:
*typedOut = string(bytes)
return nil
}
return fmt.Errorf("Only support raw")
}
// Encode applies the default Couchbase transcoding behaviour to encode a Go byte slice.
func (t BytesTranscoder) Encode(value interface{}) ([]byte, uint32, error) {
var bytes []byte
cfFmtBinary := uint32(3 << 24)
switch value.(type) {
case []byte:
bytes = value.([]byte)
case *[]byte:
bytes = *value.(*[]byte)
case string:
bytes = []byte(value.(string))
case *string:
bytes = []byte(*value.(*string))
default:
return nil, 0, fmt.Errorf("Unsupport type")
}
return bytes, cfFmtBinary, nil
}
func main() {
myCluster, _ := gocb.Connect("couchbase://127.0.0.1")
myBucket, _ := myCluster.OpenBucket("default", "")
var bt BytesTranscoder
myBucket.SetTranscoder(bt)
var b []byte
_, _ = myBucket.Get("a_key", &b)
fmt.Println(string(b))
}
作者原创,转载请注明出处
网友评论