Skip to content

Commit a99df74

Browse files
authored
CBG-4752: Bulk APIs for CV (read and write) (#7714)
1 parent f83f07b commit a99df74

File tree

16 files changed

+313
-130
lines changed

16 files changed

+313
-130
lines changed

channels/log_entry.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ func (rv *RevAndVersion) UnmarshalJSON(data []byte) error {
168168

169169
// CV returns ver@src in big endian format 1@cbl for CBL format.
170170
func (rv RevAndVersion) CV() string {
171+
if rv.CurrentSource == "" || rv.CurrentVersion == "" {
172+
return ""
173+
}
171174
// this should match db.Version.String()
172175
return strconv.FormatUint(base.HexCasToUint64(rv.CurrentVersion), 16) + "@" + rv.CurrentSource
173176
}

db/database.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -984,17 +984,17 @@ func (c *DatabaseCollection) processForEachDocIDResults(ctx context.Context, cal
984984
found = results.Next(ctx, &viewRow)
985985
if found {
986986
docid = viewRow.Key
987-
revid = viewRow.Value.RevID.RevTreeID
988-
cv = viewRow.Value.RevID.CV()
987+
revid = viewRow.Value.Rev.RevTreeID
988+
cv = viewRow.Value.Rev.CV()
989989
seq = viewRow.Value.Sequence
990990
channels = viewRow.Value.Channels
991991
}
992992
} else {
993993
found = results.Next(ctx, &queryRow)
994994
if found {
995995
docid = queryRow.Id
996-
revid = queryRow.RevID.RevTreeID
997-
cv = queryRow.RevID.CV()
996+
revid = queryRow.Rev.RevTreeID
997+
cv = queryRow.Rev.CV()
998998
seq = queryRow.Sequence
999999
channels = make([]string, 0)
10001000
// Query returns all channels, but we only want to return active channels

db/document.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ func (sd *SyncData) GetRevTreeID() string {
131131
return sd.RevAndVersion.RevTreeID
132132
}
133133

134+
func (sd *SyncData) CV() string {
135+
if sd == nil {
136+
return ""
137+
}
138+
return sd.RevAndVersion.CV()
139+
}
140+
134141
// determine set of current channels based on removal entries.
135142
func (sd *SyncData) getCurrentChannels() base.Set {
136143
ch := base.SetOf()

db/query.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,15 +688,15 @@ func (context *DatabaseContext) QueryAllRoles(ctx context.Context, startKey stri
688688
type AllDocsViewQueryRow struct {
689689
Key string
690690
Value struct {
691-
RevID channels.RevAndVersion `json:"r"`
691+
Rev channels.RevAndVersion `json:"r"`
692692
Sequence uint64 `json:"s"`
693693
Channels []string `json:"c"`
694694
}
695695
}
696696

697697
type AllDocsIndexQueryRow struct {
698698
Id string
699-
RevID channels.RevAndVersion `json:"r"`
699+
Rev channels.RevAndVersion `json:"r"`
700700
Sequence uint64 `json:"s"`
701701
Channels channels.ChannelMap `json:"c"`
702702
}

docs/api/components/parameters.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,6 @@ show_exp:
387387
schema:
388388
type: boolean
389389
description: Whether to show the expiry property (`_exp`) in the response.
390-
show_cv:
391-
name: show_cv
392-
in: query
393-
required: false
394-
schema:
395-
type: boolean
396-
description: Output the Current Version in the response as property `_cv`.
397390
startkey:
398391
name: startkey
399392
in: query

docs/api/paths/admin/keyspace-_all_docs.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ get:
2929
- $ref: ../../components/parameters.yaml#/startkey
3030
- $ref: ../../components/parameters.yaml#/endkey
3131
- $ref: ../../components/parameters.yaml#/limit-result-rows
32-
- $ref: ../../components/parameters.yaml#/show_cv
3332
responses:
3433
'200':
3534
$ref: ../../components/responses.yaml#/all-docs

docs/api/paths/admin/keyspace-_bulk_get.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ post:
4545
description: If this header includes `gzip` then the the HTTP response will be compressed. This takes priority over `X-Accept-Part-Encoding`. Only part compression will be done if `X-Accept-Part-Encoding=gzip` and the `User-Agent` is below 1.2 due to clients not being able to handle full compression.
4646
schema:
4747
type: string
48-
- $ref: ../../components/parameters.yaml#/show_cv
4948
requestBody:
5049
content:
5150
application/json:

docs/api/paths/public/keyspace-_all_docs.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ get:
2424
- $ref: ../../components/parameters.yaml#/startkey
2525
- $ref: ../../components/parameters.yaml#/endkey
2626
- $ref: ../../components/parameters.yaml#/limit-result-rows
27-
- $ref: ../../components/parameters.yaml#/show_cv
2827
responses:
2928
'200':
3029
$ref: ../../components/responses.yaml#/all-docs

docs/api/paths/public/keyspace-_bulk_get.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ post:
4040
description: If this header includes `gzip` then the the HTTP response will be compressed. This takes priority over `X-Accept-Part-Encoding`. Only part compression will be done if `X-Accept-Part-Encoding=gzip` and the `User-Agent` is below 1.2 due to clients not being able to handle full compression.
4141
schema:
4242
type: string
43-
- $ref: ../../components/parameters.yaml#/show_cv
4443
requestBody:
4544
content:
4645
application/json:

rest/access_test.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,20 @@ func TestForceAPIForbiddenErrors(t *testing.T) {
496496
})
497497
}
498498
}
499-
func TestBulkDocsChangeToAccess(t *testing.T) {
500499

500+
// TestBulkDocsChangeToAccess verifies that access() grants from one doc in a single bulk_docs request apply to subsequent docs in the same batch.
501+
func TestBulkDocsChangeToAccess(t *testing.T) {
501502
base.SetUpTestLogging(t, base.LevelInfo, base.KeyAccess)
502503

503-
rtConfig := RestTesterConfig{SyncFn: `function(doc) {if(doc.type == "setaccess") {channel(doc.channel); access(doc.owner, doc.channel);} else { requireAccess(doc.channel)}}`}
504+
rtConfig := RestTesterConfig{SyncFn: `
505+
function(doc) {
506+
if(doc.type == "setaccess") {
507+
channel(doc.channel);
508+
access(doc.owner, doc.channel);
509+
} else {
510+
requireAccess(doc.channel);
511+
}
512+
}`}
504513
rt := NewRestTesterDefaultCollection(t, &rtConfig)
505514
defer rt.Close()
506515

@@ -518,17 +527,18 @@ func TestBulkDocsChangeToAccess(t *testing.T) {
518527
assert.NoError(t, a.Save(user))
519528

520529
input := `{"docs": [{"_id": "bulk1", "type" : "setaccess", "owner":"user1" , "channel":"chan1"}, {"_id": "bulk2" , "channel":"chan1"}]}`
521-
522530
response := rt.SendUserRequest("POST", "/db/_bulk_docs", input, "user1")
523531
RequireStatus(t, response, 201)
524532

525533
var docs []interface{}
526534
require.NoError(t, base.JSONUnmarshal(response.Body.Bytes(), &docs))
527-
assert.Len(t, docs, 2)
528-
assert.Equal(t, map[string]interface{}{"rev": "1-afbcffa8a4641a0f4dd94d3fc9593e74", "id": "bulk1"}, docs[0])
529-
530-
assert.Equal(t, map[string]interface{}{"rev": "1-4d79588b9fe9c38faae61f0c1b9471c0", "id": "bulk2"}, docs[1])
531-
535+
require.Len(t, docs, 2)
536+
assert.NotContains(t, response.BodyString(), `missing channel access`)
537+
assert.NotContains(t, response.BodyString(), `"status":403"`)
538+
assert.Contains(t, response.BodyString(), `"id":"bulk1"`)
539+
assert.Contains(t, response.BodyString(), `"rev":"1-afbcffa8a4641a0f4dd94d3fc9593e74"`)
540+
assert.Contains(t, response.BodyString(), `"id":"bulk2"`)
541+
assert.Contains(t, response.BodyString(), `"rev":"1-4d79588b9fe9c38faae61f0c1b9471c0"`)
532542
}
533543

534544
// Test _all_docs API call under different security scenarios
@@ -1154,15 +1164,6 @@ func TestAllDocsCV(t *testing.T) {
11541164
{
11551165
name: "no query string",
11561166
url: "/{{.keyspace}}/_all_docs",
1157-
output: fmt.Sprintf(`{
1158-
"total_rows": 1,
1159-
"update_seq": 1,
1160-
"rows": [{"key": "%s", "id": "%s", "value": {"rev": "%s"}}]
1161-
}`, docID, docID, docVersion.RevTreeID),
1162-
},
1163-
{
1164-
name: "cvs=true",
1165-
url: "/{{.keyspace}}/_all_docs?show_cv=true",
11661167
output: fmt.Sprintf(`{
11671168
"total_rows": 1,
11681169
"update_seq": 1,

0 commit comments

Comments
 (0)