Skip to content

Commit

Permalink
CBG-4419 Return cas from GetWithXattrs when no doc, xattrs found (#42)
Browse files Browse the repository at this point in the history
* CBG-4419 Return cas from GetWithXattrs when no doc, xattrs found

In the case where a tombstone exists but doesn't have any of the requested xattrs, GetWithXattrs should return the document cas for use for subsequent writes.

* run goimports
  • Loading branch information
adamcfraser authored Dec 19, 2024
1 parent 24e402b commit f9921fc
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
3 changes: 2 additions & 1 deletion collection+xattrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ func (c *Collection) GetWithXattrs(_ context.Context, key string, xattrKeys []st
}

if rawDoc.Body == nil && len(rawDoc.Xattrs) == 0 {
return nil, nil, 0, sgbucket.MissingError{Key: key}
// Doc exists as tombstone, but not with any of the requested xattrs
return nil, nil, rawDoc.Cas, sgbucket.MissingError{Key: key}
}

xattrs = make(map[string][]byte, len(xattrKeys))
Expand Down
31 changes: 20 additions & 11 deletions collection_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Copyright (c) 2013 Couchbase, Inc.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

// Copyright (c) 2013 Couchbase, Inc.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
package rosmar

import (
Expand All @@ -24,6 +25,7 @@ import (
)

const syncXattrName = "_sync" // name of xattr used for sync gateway metadata
const vvXattrName = "_vv" // name of xattr used for HLV

func TestDeleteThenAdd(t *testing.T) {
ensureNoLeaks(t)
Expand Down Expand Up @@ -568,6 +570,7 @@ func TestWriteWithXattrNoBody(t *testing.T) {

require.NoError(t, json.Unmarshal(getXattrs[syncXattrName], &fetchedXattr))
require.Equal(t, updatedXattrVal, fetchedXattr)

}

func TestWriteCasWithXattrNoXattr(t *testing.T) {
Expand Down Expand Up @@ -652,9 +655,15 @@ func TestWriteCasWithXattrOnTombstone(t *testing.T) {
require.NoError(t, err)
require.NotEqual(t, cas, deleteCas)

postDeleteCas, err := col.WriteWithXattrs(ctx, docID, 0, 0, mustMarshalJSON(t, val), xattrs, nil, nil)
_, err = col.WriteWithXattrs(ctx, docID, 0, 0, mustMarshalJSON(t, val), xattrs, nil, nil)
require.ErrorAs(t, err, &sgbucket.CasMismatchErr{})
require.NotEqual(t, cas, postDeleteCas)

// Verify attempted retrieval of non-existent xattrs still returns the correct cas
retrievedVal, retrievedXattrs, getCas, err := col.GetWithXattrs(ctx, docID, []string{vvXattrName})
require.ErrorAs(t, err, &sgbucket.MissingError{})
require.Nil(t, retrievedVal)
require.Equal(t, 0, len(retrievedXattrs))
require.Equal(t, deleteCas, getCas)
}

func verifyEmptyBodyAndSyncXattr(t *testing.T, store sgbucket.DataStore, key string) {
Expand Down

0 comments on commit f9921fc

Please sign in to comment.