Beispiel #1
0
        protected void WriteDocumentWithAttachment(IDocumentActions documentActions, DocumentsOperationContext context, Stream dataStream, string key, BlittableJsonReaderObject metadata)
        {
            using (dataStream)
            {
                var attachment = new DocumentItem.AttachmentStream
                {
                    Stream = documentActions.GetTempStream()
                };

                var attachmentDetails = StreamSource.GenerateLegacyAttachmentDetails(context, dataStream, key, metadata, ref attachment);

                var dummyDoc = new DocumentItem
                {
                    Document = new Document
                    {
                        Data               = StreamSource.WriteDummyDocumentForAttachment(context, attachmentDetails),
                        Id                 = attachmentDetails.Id,
                        ChangeVector       = string.Empty,
                        Flags              = DocumentFlags.HasAttachments,
                        NonPersistentFlags = NonPersistentDocumentFlags.FromSmuggler,
                        LastModified       = _database.Time.GetUtcNow(),
                    },
                    Attachments = new List <DocumentItem.AttachmentStream>
                    {
                        attachment
                    }
                };

                documentActions.WriteDocument(dummyDoc, Result.Documents);
            }
        }
Beispiel #2
0
        public async Task Attachments()
        {
            var destination = new DatabaseDestination(Database);
            var options     = new DatabaseSmugglerOptionsServerSide
            {
                OperateOnTypes       = DatabaseItemType.Attachments,
                SkipRevisionCreation = true
            };

            destination.Initialize(options, null, buildVersion: default);

            using (var documentActions = destination.Documents())
                using (var buffered = new BufferedStream(RequestBodyStream()))
                    using (var reader = new BsonReader(buffered))
                    {
                        var result = LegacyAttachmentUtils.GetObject(reader);

                        const string idProperty       = "@id";
                        const string etagProperty     = "@etag";
                        const string metadataProperty = "@metadata";
                        const string dataProperty     = "data";

                        string lastAttachmentEtag = null;
                        var    progress           = new SmugglerProgressBase.CountsWithLastEtag();
                        foreach (var attachmentObject in result.Values)
                        {
                            if (!(attachmentObject is Dictionary <string, object> attachmentDictionary))
                            {
                                throw new InvalidDataException("attachmentObject isn't a Dictionary<string, object>");
                            }

                            if (attachmentDictionary.TryGetValue(idProperty, out var attachmentKeyObject) == false)
                            {
                                throw new InvalidDataException($"{idProperty} doesn't exist");
                            }

                            if (!(attachmentKeyObject is string attachmentKey))
                            {
                                throw new InvalidDataException($"{idProperty} isn't of type string");
                            }

                            if (attachmentDictionary.TryGetValue(etagProperty, out var lastAttachmentEtagObject) == false)
                            {
                                throw new InvalidDataException($"{etagProperty} doesn't exist");
                            }

                            if (!(lastAttachmentEtagObject is byte[] lastAttachmentEtagByteArray))
                            {
                                throw new InvalidDataException($"{etagProperty} isn't of type byte[]");
                            }

                            lastAttachmentEtag = LegacyAttachmentUtils.ByteArrayToEtagString(lastAttachmentEtagByteArray);

                            if (attachmentDictionary.TryGetValue(metadataProperty, out object metadataObject) == false)
                            {
                                throw new InvalidDataException($"{metadataProperty} doesn't exist");
                            }

                            if (!(metadataObject is Dictionary <string, object> metadata))
                            {
                                throw new InvalidDataException($"{idProperty} isn't of type string");
                            }

                            if (metadata.TryGetValue("Raven-Delete-Marker", out var deletedObject) && deletedObject is bool deletedObjectAsBool && deletedObjectAsBool)
                            {
                                var id = StreamSource.GetLegacyAttachmentId(attachmentKey);
                                documentActions.DeleteDocument(id);
                                continue;
                            }

                            var djv = new DynamicJsonValue();
                            foreach (var keyValue in metadata)
                            {
                                var key = keyValue.Key;
                                if (key.Equals("Raven-Replication-Source") ||
                                    key.Equals("Raven-Replication-Version") ||
                                    key.Equals("Raven-Replication-History"))
                                {
                                    continue;
                                }

                                djv[key] = keyValue.Value;
                            }

                            var contextToUse      = documentActions.GetContextForNewDocument();
                            var metadataBlittable = contextToUse.ReadObject(djv, "metadata");

                            if (attachmentDictionary.TryGetValue(dataProperty, out object dataObject) == false)
                            {
                                throw new InvalidDataException($"{dataProperty} doesn't exist");
                            }

                            if (!(dataObject is byte[] data))
                            {
                                throw new InvalidDataException($"{dataProperty} isn't of type byte[]");
                            }

                            using (var dataStream = new MemoryStream(data))
                            {
                                var attachment = new DocumentItem.AttachmentStream
                                {
                                    Stream = documentActions.GetTempStream()
                                };

                                var attachmentDetails = StreamSource.GenerateLegacyAttachmentDetails(contextToUse, dataStream, attachmentKey, metadataBlittable, ref attachment);

                                var documentItem = new DocumentItem
                                {
                                    Document = new Document
                                    {
                                        Data         = StreamSource.WriteDummyDocumentForAttachment(contextToUse, attachmentDetails),
                                        Id           = attachmentDetails.Id,
                                        ChangeVector = string.Empty,
                                        Flags        = DocumentFlags.HasAttachments,
                                        LastModified = Database.Time.GetUtcNow()
                                    },
                                    Attachments = new List <DocumentItem.AttachmentStream>
                                    {
                                        attachment
                                    }
                                };

                                documentActions.WriteDocument(documentItem, progress);
                            }
                        }

                        using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                        {
                            var replicationSource = GetSourceReplicationInformation(context, GetRemoteServerInstanceId(), out var documentId);
                            replicationSource.LastAttachmentEtag = lastAttachmentEtag;
                            replicationSource.Source             = GetFromServer();
                            replicationSource.LastModified       = DateTime.UtcNow;

                            await SaveSourceReplicationInformation(replicationSource, context, documentId);
                        }
                    }
        }