Bucket.Get and interface{}


#1

Hi,

I’m seeing a weird behavior with the document bucket’s .Get call and I wanted to know if this is by design.

If I create a document using bucket.Insert() and then try to get it using bucket.Get() the interface type is []byte ([]uint8) but if I edit the document via the UI and try to get the document again the interface type changes to map[string]interface{}

is this the expected behavior?

Attaching some code to test:

package main

import (

"fmt"

"reflect"

"time"

"github.com/davecgh/go-spew/spew"

"github.com/couchbase/gocb"

)

func main() {

var (

cbCluster *gocb.Cluster

cbBucket *gocb.Bucket

data []byte

doc interface{}

err error

    )

cbCluster, err = gocb.Connect("couchbase://127.0.0.1")

if err != nil {

panic(err)

    }

    cbCluster.Authenticate(gocb.PasswordAuthenticator{

        Username: "Administrator",

        Password: "f00b4r",

    })

cbBucket, err = cbCluster.OpenBucket("configuration", "")

if err != nil {

panic(err)

    }

data = []byte(`{"name": "Foo", "age": 24, "email": "foo@bar.baz"}`)

_, err = cbBucket.Insert("userid:1", data, 0)

if err != nil {

panic(err)

    }

_, err = cbBucket.Get("userid:1", &doc)

if err != nil {

panic(err)

    }

    fmt.Printf("Doc: %s - type: %s\n", spew.Sdump(doc), reflect.TypeOf(doc))

// Wait enough time for someone to open the document and edit it via the UI

    time.Sleep(20 * time.Second)

_, err = cbBucket.Get("userid:1", &doc)

if err != nil {

panic(err)

    }

    fmt.Printf("Doc: %s - type: %s\n", spew.Sdump(doc), reflect.TypeOf(doc))

}

Output:

go run main.go
Doc: ([]uint8) (len=50 cap=50) {
 00000000  7b 22 6e 61 6d 65 22 3a  20 22 46 6f 6f 22 2c 20  |{"name": "Foo", |
 00000010  22 61 67 65 22 3a 20 32  34 2c 20 22 65 6d 61 69  |"age": 24, "emai|
 00000020  6c 22 3a 20 22 66 6f 6f  40 62 61 72 2e 62 61 7a  |l": "foo@bar.baz|
 00000030  22 7d                                             |"}|
}
 - type: []uint8
Doc: (map[string]interface {}) (len=3) {
 (string) (len=4) "name": (string) (len=3) "Foo",
 (string) (len=3) "age": (float64) 20,
 (string) (len=5) "email": (string) (len=11) "foo@bar.baz"
}
 - type: map[string]interface {}

#2

Hey @aledesma,
The SDK stores and retrieves meta-data about the data type of the document being stored. In your SDK Insert case, you are explicitly providing a byte-slice, which the SDK encodes into the meta-data and on future fetches it is also returned as a byte-slice. In the case of the Web UI, the editing is explicitly JSON-oriented, and thus gets encoded with JSON meta-data.
Cheers, Brett


#3

Is the metadata something that is exposed from gbcore? I don’t think you can be 100% sure that no one will ever use the UI to quick edit a document that was upload via the Go SDK, right now I’m just doing a switch foo.(type) but it would be cleaner? if I can get that metadata and figure it out from there