gocb get原始二進制數據

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

作者原創,轉載請注明出處

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。