Given Attachments Meta to be stored in the database, storeAttachments goes through the map, finds attachments with inline bodies, copies the bodies into the Couchbase db, and replaces the bodies with the 'digest' attributes which are the keys to retrieving them.
(ctx context.Context, doc *Document, newAttachmentsMeta AttachmentsMeta, generation int, parentRev string, docHistory []string)
| 76 | // inline bodies, copies the bodies into the Couchbase db, and replaces the bodies with the 'digest' attributes which |
| 77 | // are the keys to retrieving them. |
| 78 | func (db *DatabaseCollectionWithUser) storeAttachments(ctx context.Context, doc *Document, newAttachmentsMeta AttachmentsMeta, generation int, parentRev string, docHistory []string) (updatedAttachments, error) { |
| 79 | if len(newAttachmentsMeta) == 0 { |
| 80 | return nil, nil |
| 81 | } |
| 82 | |
| 83 | var parentAttachments map[string]interface{} |
| 84 | newAttachments := make(updatedAttachments, 0) |
| 85 | atts := newAttachmentsMeta |
| 86 | for name, value := range atts { |
| 87 | meta, ok := value.(map[string]interface{}) |
| 88 | if !ok { |
| 89 | return nil, base.HTTPErrorf(400, "Invalid _attachments") |
| 90 | } |
| 91 | |
| 92 | data := meta["data"] |
| 93 | if data != nil { |
| 94 | // Attachment contains data, so store it in the db: |
| 95 | attachment, err := DecodeAttachment(data) |
| 96 | if err != nil { |
| 97 | return nil, err |
| 98 | } |
| 99 | digest := Sha1DigestKey(attachment) |
| 100 | key := MakeAttachmentKey(AttVersion2, doc.ID, digest) |
| 101 | _, updated := doc.Attachments()[name] |
| 102 | newAttachments[key] = updatedAttachment{ |
| 103 | body: attachment, |
| 104 | name: name, |
| 105 | created: !updated, |
| 106 | } |
| 107 | |
| 108 | newMeta := map[string]interface{}{ |
| 109 | "stub": true, |
| 110 | "digest": digest, |
| 111 | "revpos": generation, |
| 112 | "ver": AttVersion2, |
| 113 | } |
| 114 | if contentType, ok := meta["content_type"].(string); ok { |
| 115 | newMeta["content_type"] = contentType |
| 116 | } |
| 117 | if encoding := meta["encoding"]; encoding != nil { |
| 118 | newMeta["encoding"] = encoding |
| 119 | newMeta["encoded_length"] = len(attachment) |
| 120 | if length, ok := meta["length"].(float64); ok { |
| 121 | newMeta["length"] = length |
| 122 | } |
| 123 | } else { |
| 124 | newMeta["length"] = len(attachment) |
| 125 | } |
| 126 | atts[name] = newMeta |
| 127 | |
| 128 | } else { |
| 129 | // Attachment must be a stub that repeats a parent attachment |
| 130 | if meta["stub"] != true { |
| 131 | return nil, base.HTTPErrorf(400, "Missing data of attachment %q", name) |
| 132 | } |
| 133 | // Try to look up the attachment in ancestor attachments |
| 134 | if parentAttachments == nil { |
| 135 | parentAttachments = db.retrieveAncestorAttachments(ctx, doc, parentRev, docHistory) |
no test coverage detected