Skip to content

Commit 2369b91

Browse files
committed
Remove the _globalSync xattr with purge to avoid attachment metadata hanging around
1 parent 45b3bbf commit 2369b91

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

db/crud.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2888,7 +2888,7 @@ func (db *DatabaseCollectionWithUser) Purge(ctx context.Context, key string, nee
28882888
}
28892889

28902890
if db.UseXattrs() {
2891-
err := db.dataStore.DeleteWithXattrs(ctx, key, []string{base.SyncXattrName})
2891+
err := db.dataStore.DeleteWithXattrs(ctx, key, []string{base.SyncXattrName, base.GlobalXattrName})
28922892
if err != nil {
28932893
return err
28942894
}

rest/adminapitest/admin_api_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,40 @@ func TestPurgeWithSomeInvalidDocs(t *testing.T) {
17891789
rest.RequireStatus(t, rt.SendAdminRequest("PUT", "/{{.keyspace}}/doc2", `{"moo":"car"}`), 409)
17901790
}
17911791

1792+
// TestPurgeWithOldAttachment ensures that purging a document with an attachment actually removes it and a recreated document does not have the old attachment.
1793+
func TestPurgeWithOldAttachment(t *testing.T) {
1794+
rt := rest.NewRestTester(t, nil)
1795+
defer rt.Close()
1796+
1797+
_ = rt.PutDocWithAttachment("doc1", `{"foo":"doc1"}`, "att1", "b25lCg==")
1798+
1799+
rawBody, rawXattrs, _, err := rt.GetSingleDataStore().GetWithXattrs(t.Context(), "doc1", []string{base.SyncXattrName, base.GlobalXattrName})
1800+
require.NoError(t, err)
1801+
assert.NotNil(t, rawBody)
1802+
assert.NotNil(t, rawXattrs)
1803+
1804+
response := rt.SendAdminRequest("POST", "/{{.keyspace}}/_purge", `{"doc1":["*"]}`)
1805+
rest.RequireStatus(t, response, http.StatusOK)
1806+
var body db.Body
1807+
require.NoError(t, base.JSONUnmarshal(response.Body.Bytes(), &body))
1808+
assert.Equal(t, db.Body{"purged": map[string]any{"doc1": []interface{}{"*"}}}, body)
1809+
1810+
// inspect bucket doc to ensure SG's xattrs are gone
1811+
rawBody, rawXattrs, _, err = rt.GetSingleDataStore().GetWithXattrs(t.Context(), "doc1", []string{base.SyncXattrName, base.GlobalXattrName})
1812+
assert.Error(t, err)
1813+
assert.True(t, base.IsDocNotFoundError(err))
1814+
assert.Nil(t, rawBody)
1815+
assert.Empty(t, rawXattrs)
1816+
1817+
// Here we're overwriting any previous global sync that may exist, so attachments being resurrected aren't an actual issue for us.
1818+
_ = rt.PutDocDirectly("doc1", db.Body{"foo": "doc1"})
1819+
1820+
rawBody, rawXattrs, _, err = rt.GetSingleDataStore().GetWithXattrs(t.Context(), "doc1", []string{base.SyncXattrName, base.GlobalXattrName})
1821+
require.NoError(t, err)
1822+
assert.NotNil(t, rawBody)
1823+
assert.NotNil(t, rawXattrs)
1824+
}
1825+
17921826
// TestRawRedaction tests the /_raw endpoint with and without redaction
17931827
// intentionally does string matching on redactable strings to avoid any regressions if we move around metadata without updating the test
17941828
func TestRawRedaction(t *testing.T) {

0 commit comments

Comments
 (0)