github.com/altipla-consulting/ravendb-go-client@v0.1.3/document_session_attachments_base.go (about) 1 package ravendb 2 3 import ( 4 "fmt" 5 "io" 6 "reflect" 7 ) 8 9 type DocumentSessionAttachmentsBase struct { 10 *AdvancedSessionExtensionBase 11 } 12 13 func NewDocumentSessionAttachmentsBase(session *InMemoryDocumentSessionOperations) *DocumentSessionAttachmentsBase { 14 res := &DocumentSessionAttachmentsBase{} 15 res.AdvancedSessionExtensionBase = newAdvancedSessionExtensionBase(session) 16 return res 17 } 18 19 func (s *DocumentSessionAttachmentsBase) GetNames(entity interface{}) ([]*AttachmentName, error) { 20 err := checkValidEntityIn(entity, "entity") 21 if err != nil { 22 return nil, err 23 } 24 document := getDocumentInfoByEntity(s.documents, entity) 25 if document == nil { 26 return nil, throwEntityNotInSession(entity) 27 } 28 meta := document.metadata 29 attachmentsI, ok := meta[MetadataAttachments] 30 if !ok { 31 return nil, nil 32 } 33 34 attachments, ok := attachmentsI.([]interface{}) 35 if !ok { 36 return nil, fmt.Errorf("meta value '%s' is of type %T, expected []interface{}", MetadataAttachments, attachmentsI) 37 } 38 n := len(attachments) 39 results := make([]*AttachmentName, n) 40 clazz := reflect.TypeOf(&AttachmentName{}) 41 for i := 0; i < n; i++ { 42 jsonNode := attachments[i] 43 resI, err := convertValue(jsonNode, clazz) 44 if err != nil { 45 return nil, err 46 } 47 res := resI.(*AttachmentName) 48 results[i] = res 49 } 50 return results, nil 51 } 52 53 // contentType is optional 54 func (s *DocumentSessionAttachmentsBase) StoreByID(documentID string, name string, stream io.Reader, contentType string) error { 55 if stringIsBlank(documentID) { 56 return newIllegalArgumentError("documentID can't be an empty string") 57 } 58 if stringIsBlank(name) { 59 return newIllegalArgumentError("name can't be an empty string") 60 } 61 if stream == nil { 62 return newIllegalArgumentError("stream can't be nil") 63 } 64 65 deferredCommandsMap := s.deferredCommandsMap 66 67 key := newIDTypeAndName(documentID, CommandDelete, "") 68 if _, ok := deferredCommandsMap[key]; ok { 69 return newIllegalStateError("Cannot Store attachment" + name + " of document " + documentID + ", there is a deferred command registered for this document to be deleted") 70 } 71 72 key = newIDTypeAndName(documentID, CommandAttachmentPut, name) 73 if _, ok := deferredCommandsMap[key]; ok { 74 return newIllegalStateError("Cannot Store attachment" + name + " of document " + documentID + ", there is a deferred command registered to create an attachment with the same name.") 75 } 76 77 key = newIDTypeAndName(documentID, CommandAttachmentDelete, name) 78 if _, ok := deferredCommandsMap[key]; ok { 79 return newIllegalStateError("Cannot Store attachment" + name + " of document " + documentID + ", there is a deferred command registered to delete an attachment with the same name.") 80 } 81 82 documentInfo := s.documentsByID.getValue(documentID) 83 if documentInfo != nil && s.deletedEntities.contains(documentInfo.entity) { 84 return newIllegalStateError("Cannot Store attachment " + name + " of document " + documentID + ", the document was already deleted in this session.") 85 } 86 87 cmdData, err := NewPutAttachmentCommandData(documentID, name, stream, contentType, nil) 88 if err != nil { 89 return err 90 } 91 s.Defer(cmdData) 92 return nil 93 } 94 95 // Store stores an entity 96 func (s *DocumentSessionAttachmentsBase) Store(entity interface{}, name string, stream io.Reader, contentType string) error { 97 document := getDocumentInfoByEntity(s.documents, entity) 98 if document == nil { 99 return throwEntityNotInSession(entity) 100 } 101 102 return s.StoreByID(document.id, name, stream, contentType) 103 } 104 105 // Delete deletes a given entity 106 // TODO: support **struct or return good error message 107 func (s *DocumentSessionAttachmentsBase) Delete(entity interface{}, name string) error { 108 document := getDocumentInfoByEntity(s.documents, entity) 109 if document == nil { 110 return throwEntityNotInSession(entity) 111 } 112 113 return s.DeleteByID(document.id, name) 114 } 115 116 // Delete deletes entity with a given i 117 func (s *DocumentSessionAttachmentsBase) DeleteByID(documentID string, name string) error { 118 if stringIsBlank(documentID) { 119 return newIllegalArgumentError("DocumentId cannot be null") 120 } 121 122 if stringIsBlank(name) { 123 return newIllegalArgumentError("Name cannot be null") 124 } 125 126 deferredCommandsMap := s.deferredCommandsMap 127 128 key := newIDTypeAndName(documentID, CommandDelete, "") 129 if _, ok := deferredCommandsMap[key]; ok { 130 return nil // no-op 131 } 132 133 key = newIDTypeAndName(documentID, CommandAttachmentDelete, name) 134 if _, ok := deferredCommandsMap[key]; ok { 135 return nil // no-op 136 } 137 138 documentInfo := s.documentsByID.getValue(documentID) 139 if documentInfo != nil && s.deletedEntities.contains(documentInfo.entity) { 140 return nil //no-op 141 } 142 143 key = newIDTypeAndName(documentID, CommandAttachmentPut, name) 144 if _, ok := deferredCommandsMap[key]; ok { 145 return newIllegalStateError("Cannot delete attachment " + name + " of document " + documentID + ", there is a deferred command registered to create an attachment with the same name.") 146 } 147 148 cmdData, err := NewDeleteAttachmentCommandData(documentID, name, nil) 149 if err != nil { 150 return err 151 } 152 s.Defer(cmdData) 153 return nil 154 } 155 156 func throwEntityNotInSession(entity interface{}) *IllegalArgumentError { 157 return newIllegalArgumentError("%v is not associated with the session. Use documentID instead or track the entity in the session.", entity) 158 }