MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / getOldRevisionJSON

Method getOldRevisionJSON

db/revision.go:246–287  ·  view source on GitHub ↗

getOldRevisionJSON looks up the raw JSON data of a revision that's been archived to a separate doc. If the revision isn't found (e.g. has been deleted by compaction) returns 404 error.

(ctx context.Context, docid string, revOrCV string)

Source from the content-addressed store, hash-verified

244// getOldRevisionJSON looks up the raw JSON data of a revision that's been archived to a separate doc.
245// If the revision isn't found (e.g. has been deleted by compaction) returns 404 error.
246func (c *DatabaseCollection) getOldRevisionJSON(ctx context.Context, docid string, revOrCV string) ([]byte, base.Set, bool, error) {
247 data, _, err := c.dataStore.GetRaw(oldRevisionKey(docid, revOrCV))
248 if base.IsDocNotFoundError(err) {
249 base.DebugfCtx(ctx, base.KeyCRUD, "No old revision %q / %q", base.UD(docid), revOrCV)
250 return nil, nil, false, ErrMissing
251 } else if err != nil {
252 return nil, nil, false, err
253 }
254 kind, revData := stripNonJSONPrefix(data)
255 switch kind {
256 case nonJSONPrefixKindRevBody:
257 base.DebugfCtx(ctx, base.KeyCRUD, "Got old revision %q / %q --> %d bytes", base.UD(docid), revOrCV, len(revData))
258 return revData, nil, false, nil
259 case nonJSONPrefixKindRevPtr:
260 // pointer to a CV-keyed backup revision - do another fetch by CV for the body
261 base.DebugfCtx(ctx, base.KeyCRUD, "Found old revision pointer %q -> %q / %q", revOrCV, base.UD(docid), string(revData))
262 return c.getOldRevisionJSON(ctx, docid, string(revData))
263 case nonJSONPrefixKindRevWithMeta:
264 jsonBody, meta, err := getOldRevisionJSONAndMeta(revData)
265 if err != nil {
266 return nil, nil, false, err
267 }
268 base.DebugfCtx(ctx, base.KeyCRUD, "Got old revision (with %d meta properties) %q / %q --> %d bytes", len(meta), base.UD(docid), revOrCV, len(jsonBody))
269 var channelSet base.Set
270 if ch, ok := meta[backupRevisionChannelsMetaKey]; ok && ch != nil {
271 err = base.JSONUnmarshal(ch, &channelSet)
272 if err != nil {
273 return nil, nil, false, fmt.Errorf("error unmarshalling _channels xattr for old revision %q / %q: %v", base.UD(docid), revOrCV, err)
274 }
275 }
276 var deletedDoc bool
277 if deletedMeta, ok := meta[backupRevisionBodyDeletedMetaKey]; ok && deletedMeta != nil {
278 err = base.JSONUnmarshal(deletedMeta, &deletedDoc)
279 if err != nil {
280 return nil, nil, false, fmt.Errorf("error unmarshalling _deleted xattr for old revision %q / %q: %v", base.UD(docid), revOrCV, err)
281 }
282 }
283 return jsonBody, channelSet, deletedDoc, nil
284 default:
285 return nil, nil, false, fmt.Errorf("unexpected prefix %b for old revision doc %q / %q", kind, base.UD(docid).String(), revOrCV)
286 }
287}
288
289func getOldRevisionJSONAndMeta(payload []byte) (jsonBody []byte, kvPairs map[string][]byte, err error) {
290 body, meta, err := sgbucket.DecodeValueWithAllXattrs(payload)

Callers 4

getCurrentVersionMethod · 0.95
getRevisionMethod · 0.95
TestBackupOldRevisionFunction · 0.80

Calls 10

IsDocNotFoundErrorFunction · 0.92
DebugfCtxFunction · 0.92
UDFunction · 0.92
JSONUnmarshalFunction · 0.92
oldRevisionKeyFunction · 0.85
stripNonJSONPrefixFunction · 0.85
ErrorfMethod · 0.80
StringMethod · 0.65
GetRawMethod · 0.45

Tested by 2

TestBackupOldRevisionFunction · 0.64