Skip to content

Commit

Permalink
CBG-4263 create GetAllXattrs to allow usage in rosmar XDCR
Browse files Browse the repository at this point in the history
  • Loading branch information
torcolvin committed Oct 22, 2024
1 parent 933f0fd commit dcad7f6
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 6 deletions.
30 changes: 30 additions & 0 deletions collection+xattrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package rosmar

import (
"bytes"
"context"
"database/sql"
"encoding/binary"
Expand Down Expand Up @@ -744,3 +745,32 @@ func (e *event) expandXattrMacros(xattrKey string, xattr any, mutateOpts *sgbuck
}
return nil
}

// GetAllXattrs returns all xattrs for a document and the associated cas value. This is not a function that exists on couchbase server, but is used for a test XDCR implementation.
func (c *Collection) GetAllXattrs(key string) (map[string][]byte, uint64, error) {
row := c.db().QueryRow(`SELECT cas, xattrs FROM documents WHERE collection=?1 AND key=?2`, c.id, key)
var rawXattrBytes []byte
var cas CAS
err := scan(row, &cas, &rawXattrBytes)
if err != nil {
return nil, 0, remapKeyError(err, key)
}
if bytes.Equal(rawXattrBytes, []byte("null")) {
return nil, cas, nil
}
var rawXattrs map[string]json.RawMessage
err = json.Unmarshal(rawXattrBytes, &rawXattrs)
if err != nil {
return nil, 0, fmt.Errorf("document %q xattrs are unreadable: %w %s", key, err, rawXattrs)
}
xattrs := make(map[string][]byte, len(rawXattrs))
for k, v := range rawXattrs {
var xattr []byte
err := decodeRaw(v, &xattr)
if err != nil {
return nil, 0, err
}
xattrs[k] = xattr
}
return xattrs, cas, nil
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/couchbaselabs/rosmar
go 1.19

require (
github.com/couchbase/sg-bucket v0.0.0-20240606153601-d152b90edccb
github.com/couchbase/sg-bucket v0.0.0-20241018143914-45ef51a0c1be
github.com/google/uuid v1.6.0
github.com/mattn/go-sqlite3 v1.14.23
github.com/stretchr/testify v1.9.0
Expand All @@ -13,7 +13,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/text v0.17.0 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/couchbase/sg-bucket v0.0.0-20240606153601-d152b90edccb h1:FrUz2LZLmTwQl1cRCXUDwouE3gINsaEAV4o6BdAftz8=
github.com/couchbase/sg-bucket v0.0.0-20240606153601-d152b90edccb/go.mod h1:IQisEdcLRfS/pjSgmqG/8gerVm0Q7GrvpQtMIZ7oYt4=
github.com/couchbase/sg-bucket v0.0.0-20241018143914-45ef51a0c1be h1:QM2afa9Xhbhy1ywVEVCRV0vEQvHIPplDkc6NsNug78Y=
github.com/couchbase/sg-bucket v0.0.0-20241018143914-45ef51a0c1be/go.mod h1:Tw3QSBP+nkDjw1cpHwMFP4pBORs0UOP+KbF2hXBVwqM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -17,8 +17,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
Expand Down
54 changes: 54 additions & 0 deletions xattrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1740,3 +1740,57 @@ func requireDocNotFoundError(t testing.TB, err error) {
func requireDocFoundError(t testing.TB, err error) {
require.ErrorIs(t, err, sgbucket.ErrKeyExists)
}

func TestGetAllXattrs(t *testing.T) {
testCases := []struct {
name string
body []byte
xattrs map[string][]byte
}{
{
name: "no doc",
body: nil,
xattrs: nil,
},
{
name: "doc without xattrs",
body: []byte(`{"foo": "bar"}`),
xattrs: nil,
},
{
name: "doc with xattrs",
body: []byte(`{"foo": "bar"}`),
xattrs: map[string][]byte{
"_xattr1": []byte(`{"a": "b"}`),
"xattr2": []byte(`{"c": "d"}`),
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
col := makeTestBucket(t).DefaultDataStore().(*Collection)
docID := t.Name()
ctx := testCtx(t)
var cas uint64
if tc.body != nil {
var err error
cas, err = col.WriteWithXattrs(ctx, docID, 0, 0, tc.body, tc.xattrs, nil, nil)
require.NoError(t, err)
}
xattrs, outputCas, err := col.GetAllXattrs(docID)
if tc.body == nil {
require.ErrorAs(t, err, &sgbucket.MissingError{})
require.Equal(t, uint64(0), outputCas)
require.Nil(t, xattrs)
return
}
require.NoError(t, err)
require.Equal(t, cas, outputCas)
require.Len(t, xattrs, len(tc.xattrs))
for k, v := range tc.xattrs {
require.JSONEq(t, string(v), string(xattrs[k]))
}
})
}

}

0 comments on commit dcad7f6

Please sign in to comment.