美文网首页
gocb get原始二进制数据

gocb get原始二进制数据

作者: NeverLee | 来源:发表于2017-10-01 15:41 被阅读0次

    线上使用的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))
    }
    

    作者原创,转载请注明出处

    相关文章

      网友评论

          本文标题:gocb get原始二进制数据

          本文链接:https://www.haomeiwen.com/subject/tfkaextx.html