private async Task LoadChangeFeed(Func <IEnumerable <EveneumDocument>, Task> callback, string token = null, CancellationToken cancellationToken = default) { PartitionKeyRange partitionKeyRange = this.PartitionKey != null ? null : (await this.GetPartitionKeyRanges()).FirstOrDefault(); var changeFeed = this.Client.CreateDocumentChangeFeedQuery(this.DocumentCollectionUri, new ChangeFeedOptions { PartitionKeyRangeId = partitionKeyRange?.Id, PartitionKey = this.PartitionKey, RequestContinuation = token, StartFromBeginning = true, MaxItemCount = 10000, }); Task callbackTask = null; while (changeFeed.HasMoreResults) { var page = await changeFeed.ExecuteNextAsync <Document>(cancellationToken); if (callbackTask != null) { await callbackTask; } callbackTask = callback(page.Select(x => EveneumDocument.Parse(x, this.JsonSerializerSettings))); } }
public async Task DeleteSnapshots(string streamId, ulong olderThanVersion, CancellationToken cancellationToken = default) { await this.ReadHeader(streamId, cancellationToken); var query = this.Client.CreateDocumentQuery <SnapshotDocument>(this.DocumentCollectionUri, new FeedOptions { PartitionKey = this.PartitionKey }) .Where(x => x.StreamId == streamId) .Where(x => x.DocumentType == DocumentType.Snapshot) .Where(x => x.Version < olderThanVersion) .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(UriFactory.CreateDocumentUri(this.Database, this.Collection, document.Id), new RequestOptions { PartitionKey = this.PartitionKey }, cancellationToken); } } } }
public static async Task <IReadOnlyCollection <EveneumDocument> > All(this IDocumentQuery <Document> query, JsonSerializerSettings jsonSerializerSettings) { var documents = new List <EveneumDocument>(); while (query.HasMoreResults) { var page = await query.ExecuteNextAsync <Document>(); documents.AddRange(page.Select(x => EveneumDocument.Parse(x, jsonSerializerSettings))); } return(documents); }
public async Task LoadEvents(string sql, Func <IReadOnlyCollection <EventData>, Task> callback, CancellationToken cancellationToken = default) { var query = this.Client.CreateDocumentQuery <Document>(this.DocumentCollectionUri, sql, new FeedOptions { PartitionKey = this.PartitionKey, MaxItemCount = -1 }).AsDocumentQuery(); do { var page = await query.ExecuteNextAsync <Document>(cancellationToken); await callback(page.Select(x => EveneumDocument.Parse(x, this.JsonSerializerSettings)).Where(x => !x.Deleted).OfType <EventDocument>().Select(Deserialize).ToList()); }while (query.HasMoreResults); }
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); } } } }
private static async Task <List <TDocument> > Query <TDocument>(IDocumentClient client, string database, string collection, string query, FeedOptions feedOptions) where TDocument : EveneumDocument { var documentQuery = client.CreateDocumentQuery <Document>(UriFactory.CreateDocumentCollectionUri(database, collection), query, feedOptions).AsDocumentQuery(); var documents = new List <TDocument>(); do { var page = await documentQuery.ExecuteNextAsync <Document>(); documents.AddRange(page.Select(x => EveneumDocument.Parse(x, new JsonSerializerSettings())).OfType <TDocument>()); }while (documentQuery.HasMoreResults); return(documents); }
public async Task <Stream?> ReadStream(string streamId, CancellationToken cancellationToken = default) { if (streamId == null) { throw new ArgumentNullException(nameof(streamId)); } var sql = $"SELECT * FROM x WHERE x.{nameof(EveneumDocument.StreamId)} = '{streamId}' ORDER BY x.{nameof(EveneumDocument.SortOrder)} DESC"; var query = this.Client.CreateDocumentQuery <Document>(this.DocumentCollectionUri, sql, new FeedOptions { PartitionKey = this.PartitionKey }).AsDocumentQuery(); var documents = new List <EveneumDocument>(); var finishLoading = false; do { var page = await query.ExecuteNextAsync <Document>(cancellationToken); foreach (var document in page) { var eveneumDoc = EveneumDocument.Parse(document, this.JsonSerializerSettings); if (eveneumDoc is HeaderDocument && eveneumDoc.Deleted) { throw new StreamNotFoundException(streamId); } if (eveneumDoc.Deleted) { continue; } documents.Add(eveneumDoc); if (eveneumDoc is SnapshotDocument) { finishLoading = true; break; } } if (finishLoading) { break; } }while (query.HasMoreResults); if (documents.Count == 0) { return(null); } var headerDocument = documents.First() as HeaderDocument; var events = documents.OfType <EventDocument>().Select(this.Deserialize).Reverse().ToArray(); var snapshot = documents.OfType <SnapshotDocument>().Select(this.Deserialize).Cast <Snapshot?>().FirstOrDefault(); object metadata = null; if (!string.IsNullOrEmpty(headerDocument.MetadataType)) { metadata = headerDocument.Metadata.ToObject(this.TypeCache.Resolve(headerDocument.MetadataType), this.JsonSerializer); } return(new Stream(streamId, headerDocument.Version, metadata, events, snapshot)); }