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

Method ForEachStubAttachment

db/attachment.go:291–339  ·  view source on GitHub ↗

Given a document body, invokes the callback once for each attachment that doesn't include its data, and isn't present with a matching digest on the existing doc (existingDigests). The callback is told whether the attachment body is known to the database, according to its digest. If the attachment is

(body Body, minRevpos int, docID string, existingDigests map[string]string, callback AttachmentCallback)

Source from the content-addressed store, hash-verified

289// to its digest. If the attachment isn't known, the callback can return data for it, which will
290// be added to the metadata as a "data" property.
291func (c *DatabaseCollection) ForEachStubAttachment(body Body, minRevpos int, docID string, existingDigests map[string]string, callback AttachmentCallback) error {
292 atts := GetBodyAttachments(body)
293 if atts == nil && body[BodyAttachments] != nil {
294 return base.HTTPErrorf(http.StatusBadRequest, "Invalid _attachments")
295 }
296 for name, value := range atts {
297 meta, ok := value.(map[string]interface{})
298 if !ok {
299 return base.HTTPErrorf(http.StatusBadRequest, "Invalid attachment")
300 }
301 if meta["data"] == nil {
302 if revpos, ok := base.ToInt64(meta["revpos"]); revpos < int64(minRevpos) || (!ok && minRevpos > 0) {
303 continue
304 }
305 digest, ok := meta["digest"].(string)
306 if !ok {
307 return base.HTTPErrorf(http.StatusBadRequest, "Invalid attachment")
308 }
309
310 // If digest matches the one on existing doc, SG doesn't need to prove/get
311 existingDigest, existingOk := existingDigests[name]
312 if existingOk && existingDigest == digest {
313 // see CBG-2010 for discussion of potential existence check here
314 continue
315 }
316
317 // Assumes the attachment is always AttVersion2 while checking whether it has already been uploaded.
318 attachmentKey := MakeAttachmentKey(AttVersion2, docID, digest)
319 data, err := c.GetAttachment(attachmentKey)
320 if err != nil && !base.IsDocNotFoundError(err) {
321 return err
322 }
323 newData, err := callback(name, digest, data, meta)
324 if err != nil {
325 return err
326 }
327 if newData != nil {
328 meta["data"] = newData
329 delete(meta, "stub")
330 delete(meta, "follows")
331 } else {
332 // Update version in the case where this is a new attachment on the doc sharing a V2 digest with
333 // an existing attachment
334 meta["ver"] = AttVersion2
335 }
336 }
337 }
338 return nil
339}
340
341func GetAttachmentVersion(meta map[string]interface{}) (int, bool) {
342 ver, ok := meta["ver"]

Callers 2

Calls 6

GetAttachmentMethod · 0.95
HTTPErrorfFunction · 0.92
ToInt64Function · 0.92
IsDocNotFoundErrorFunction · 0.92
GetBodyAttachmentsFunction · 0.85
MakeAttachmentKeyFunction · 0.85

Tested by 1