Example #1
0
        public async Task WriteToStream(string streamId, EventData[] events, ulong?expectedVersion = null, object metadata = null, CancellationToken cancellationToken = default)
        {
            HeaderDocument header;

            // Existing stream
            if (expectedVersion.HasValue)
            {
                header = await this.ReadHeader(streamId, cancellationToken);

                if (header.Version != expectedVersion)
                {
                    throw new OptimisticConcurrencyException(streamId, expectedVersion.Value, header.Version);
                }
            }
            else
            {
                header = new HeaderDocument
                {
                    Partition = this.Partition,
                    StreamId  = streamId
                };
            }

            header.Version += (ulong)events.Length;

            if (metadata != null)
            {
                header.Metadata     = JToken.FromObject(metadata, this.JsonSerializer);
                header.MetadataType = metadata.GetType().AssemblyQualifiedName;
            }

            if (!expectedVersion.HasValue)
            {
                try
                {
                    await this.Client.CreateDocumentAsync(this.DocumentCollectionUri, header, new RequestOptions { PartitionKey = this.PartitionKey }, disableAutomaticIdGeneration : true, cancellationToken);
                }
                catch (DocumentClientException ex) when(ex.Error.Code == nameof(System.Net.HttpStatusCode.Conflict))
                {
                    throw new StreamAlreadyExistsException(streamId);
                }
            }
            else
            {
                await this.Client.ReplaceDocumentAsync(this.HeaderDocumentUri(streamId), header, new RequestOptions { PartitionKey = this.PartitionKey, AccessCondition = new AccessCondition {
                                                                                                                          Type = AccessConditionType.IfMatch, Condition = header.ETag
                                                                                                                      } }, cancellationToken);
            }

            var eventDocuments = (events ?? Enumerable.Empty <EventData>()).Select(@event => this.Serialize(@event, streamId));

            foreach (var eventDocument in eventDocuments)
            {
                await this.Client.CreateDocumentAsync(this.DocumentCollectionUri, eventDocument, new RequestOptions { PartitionKey = this.PartitionKey }, disableAutomaticIdGeneration : true, cancellationToken);
            }
        }
Example #2
0
        public async Task DeleteStream(string streamId, ulong expectedVersion, CancellationToken cancellationToken = default)
        {
            var header = new HeaderDocument
            {
                Partition = this.Partition,
                StreamId  = streamId,
                Version   = expectedVersion
            };

            var existingHeader = await this.ReadHeader(streamId, cancellationToken);

            if (existingHeader.Deleted)
            {
                throw new StreamNotFoundException(streamId);
            }

            if (existingHeader.Version != expectedVersion)
            {
                throw new OptimisticConcurrencyException(streamId, expectedVersion, existingHeader.Version);
            }

            string etag = existingHeader.ETag;

            var query = this.Client.CreateDocumentQuery <EveneumDocument>(this.DocumentCollectionUri, new FeedOptions {
                PartitionKey = this.PartitionKey
            })
                        .Where(x => x.StreamId == streamId)
                        .AsDocumentQuery();

            while (query.HasMoreResults)
            {
                var page = await query.ExecuteNextAsync <Document>(cancellationToken);

                foreach (var document in page)
                {
                    if (this.DeleteMode == DeleteMode.SoftDelete)
                    {
                        var doc = EveneumDocument.Parse(document, this.JsonSerializerSettings);
                        doc.Deleted = true;
                        await this.Client.UpsertDocumentAsync(this.DocumentCollectionUri, doc, new RequestOptions { PartitionKey = this.PartitionKey }, disableAutomaticIdGeneration : true, cancellationToken);
                    }
                    else
                    {
                        await this.Client.DeleteDocumentAsync(document.SelfLink, new RequestOptions { PartitionKey = this.PartitionKey }, cancellationToken);
                    }
                }
            }
        }
Example #3
0
 private Uri HeaderDocumentUri(string streamId) => UriFactory.CreateDocumentUri(this.Database, this.Collection, HeaderDocument.GenerateId(streamId));
 public ScriptManager()
 {
     Header = new HeaderDocument();
     Items  = new ScriptCollection();
 }