/// <summary> /// Helper method to create a stream feed iterator. /// It decides if it is a query or read feed and create /// the correct instance. /// </summary> public override FeedIteratorInternal GetItemQueryStreamIteratorInternal( SqlQuerySpec sqlQuerySpec, bool isContinuationExcpected, string continuationToken, FeedRangeInternal feedRange, QueryRequestOptions requestOptions) { requestOptions ??= new QueryRequestOptions(); if (requestOptions.IsEffectivePartitionKeyRouting) { if (feedRange != null) { throw new ArgumentException(nameof(feedRange), ClientResources.FeedToken_EffectivePartitionKeyRouting); } requestOptions.PartitionKey = null; } if (sqlQuerySpec == null) { NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer( this, this.queryClient, requestOptions); DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer); ReadFeedPaginationOptions.PaginationDirection?direction = null; if ((requestOptions.Properties != null) && requestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection)) { direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward; } ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions( direction, pageSizeHint: requestOptions.MaxItemCount ?? int.MaxValue); return(new ReadFeedIteratorCore( documentContainer, continuationToken, readFeedPaginationOptions, requestOptions, cancellationToken: default)); } return(QueryIterator.Create( containerCore: this, client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: sqlQuerySpec, continuationToken: continuationToken, feedRangeInternal: feedRange, queryRequestOptions: requestOptions, resourceLink: this.LinkUri, isContinuationExpected: isContinuationExcpected, allowNonValueAggregateQuery: true, forcePassthrough: false, partitionedQueryExecutionInfo: null)); }
public Task <TryCatch <ReadFeedPage> > MonadicReadFeedAsync( FeedRangeState <ReadFeedState> feedRangeState, ReadFeedPaginationOptions readFeedPaginationOptions, ITrace trace, CancellationToken cancellationToken) => this.monadicDocumentContainer.MonadicReadFeedAsync( feedRangeState, readFeedPaginationOptions, trace, cancellationToken);
public ReadFeedCrossFeedRangeAsyncEnumerable( IDocumentContainer documentContainer, ReadFeedCrossFeedRangeState state, ReadFeedPaginationOptions readFeedPaginationOptions) { this.documentContainer = documentContainer ?? throw new ArgumentNullException(nameof(documentContainer)); this.state = state; this.readFeedPaginationOptions = readFeedPaginationOptions; }
public ReadFeedPartitionRangeEnumerator( IReadFeedDataSource readFeedDataSource, FeedRangeState <ReadFeedState> feedRangeState, ReadFeedPaginationOptions readFeedPaginationOptions, CancellationToken cancellationToken) : base(feedRangeState, cancellationToken) { this.readFeedDataSource = readFeedDataSource ?? throw new ArgumentNullException(nameof(readFeedDataSource)); this.readFeedPaginationOptions = readFeedPaginationOptions; }
public override FeedIteratorInternal GetReadFeedIterator( QueryDefinition queryDefinition, QueryRequestOptions queryRequestOptions, string resourceLink, ResourceType resourceType, string continuationToken, int pageSize) { queryRequestOptions ??= new QueryRequestOptions(); NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer( this, this.queryClient, queryRequestOptions, resourceLink: resourceLink, resourceType: resourceType); DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer); FeedIteratorInternal feedIterator; if (queryDefinition != null) { feedIterator = QueryIterator.Create( containerCore: this, client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: queryDefinition.ToSqlQuerySpec(), continuationToken: continuationToken, feedRangeInternal: FeedRangeEpk.FullRange, queryRequestOptions: queryRequestOptions, resourceLink: resourceLink, isContinuationExpected: false, allowNonValueAggregateQuery: true, forcePassthrough: false, partitionedQueryExecutionInfo: null); } else { ReadFeedPaginationOptions.PaginationDirection?direction = null; if ((queryRequestOptions.Properties != null) && queryRequestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection)) { direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward; } ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions( direction, pageSizeHint: queryRequestOptions.MaxItemCount ?? int.MaxValue); feedIterator = new ReadFeedIteratorCore( documentContainer: documentContainer, queryRequestOptions: queryRequestOptions, continuationToken: continuationToken, readFeedPaginationOptions: readFeedPaginationOptions, cancellationToken: default);
public Task <ReadFeedPage> ReadFeedAsync( FeedRangeState <ReadFeedState> feedRangeState, ReadFeedPaginationOptions readFeedPaginationOptions, ITrace trace, CancellationToken cancellationToken) => TryCatch <ReadFeedPage> .UnsafeGetResultAsync( this.MonadicReadFeedAsync( feedRangeState, readFeedPaginationOptions, trace, cancellationToken), cancellationToken);
public ReadFeedIteratorCore( IDocumentContainer documentContainer, string continuationToken, ReadFeedPaginationOptions readFeedPaginationOptions, QueryRequestOptions queryRequestOptions, CancellationToken cancellationToken) { this.queryRequestOptions = queryRequestOptions; readFeedPaginationOptions ??= ReadFeedPaginationOptions.Default; if (!string.IsNullOrEmpty(continuationToken)) { bool isNewArrayFormat = (continuationToken.Length >= 2) && (continuationToken[0] == '[') && (continuationToken[continuationToken.Length - 1] == ']'); if (!isNewArrayFormat) { // One of the two older formats if (!FeedRangeContinuation.TryParse(continuationToken, out FeedRangeContinuation feedRangeContinuation)) { // Backward compatible with old format feedRangeContinuation = new FeedRangeCompositeContinuation( containerRid: string.Empty, FeedRangeEpk.FullRange, new List <Documents.Routing.Range <string> >() { new Documents.Routing.Range <string>( Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey, Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey, isMinInclusive: true, isMaxInclusive: false) }, continuationToken); } // need to massage it a little List <CosmosElement> feedRangeStates = new List <CosmosElement>(); string oldContinuationFormat = feedRangeContinuation.ToString(); if (feedRangeContinuation.FeedRange is FeedRangePartitionKey feedRangePartitionKey) { CosmosObject cosmosObject = CosmosObject.Parse(oldContinuationFormat); CosmosArray continuations = (CosmosArray)cosmosObject["Continuation"]; if (continuations.Count != 1) { throw new InvalidOperationException("Expected only one continuation for partition key queries"); } CosmosElement continuation = continuations[0]; CosmosObject continuationObject = (CosmosObject)continuation; CosmosElement token = continuationObject["token"]; ReadFeedState state; if (token is CosmosNull) { state = ReadFeedState.Beginning(); } else { CosmosString tokenAsString = (CosmosString)token; state = ReadFeedState.Continuation(CosmosElement.Parse(tokenAsString.Value)); } FeedRangeState <ReadFeedState> feedRangeState = new FeedRangeState <ReadFeedState>(feedRangePartitionKey, state); feedRangeStates.Add(ReadFeedFeedRangeStateSerializer.ToCosmosElement(feedRangeState)); } else { CosmosObject cosmosObject = CosmosObject.Parse(oldContinuationFormat); CosmosArray continuations = (CosmosArray)cosmosObject["Continuation"]; foreach (CosmosElement continuation in continuations) { CosmosObject continuationObject = (CosmosObject)continuation; CosmosObject rangeObject = (CosmosObject)continuationObject["range"]; string min = ((CosmosString)rangeObject["min"]).Value; string max = ((CosmosString)rangeObject["max"]).Value; CosmosElement token = continuationObject["token"]; FeedRangeInternal feedRange = new FeedRangeEpk(new Documents.Routing.Range <string>(min, max, isMinInclusive: true, isMaxInclusive: false)); ReadFeedState state; if (token is CosmosNull) { state = ReadFeedState.Beginning(); } else { CosmosString tokenAsString = (CosmosString)token; state = ReadFeedState.Continuation(CosmosElement.Parse(tokenAsString.Value)); } FeedRangeState <ReadFeedState> feedRangeState = new FeedRangeState <ReadFeedState>(feedRange, state); feedRangeStates.Add(ReadFeedFeedRangeStateSerializer.ToCosmosElement(feedRangeState)); } } CosmosArray cosmosArrayContinuationTokens = CosmosArray.Create(feedRangeStates); continuationToken = cosmosArrayContinuationTokens.ToString(); } } TryCatch <ReadFeedCrossFeedRangeState> monadicReadFeedState; if (continuationToken == null) { FeedRange feedRange; if ((this.queryRequestOptions != null) && this.queryRequestOptions.PartitionKey.HasValue) { feedRange = new FeedRangePartitionKey(this.queryRequestOptions.PartitionKey.Value); } else if ((this.queryRequestOptions != null) && (this.queryRequestOptions.FeedRange != null)) { feedRange = this.queryRequestOptions.FeedRange; } else { feedRange = FeedRangeEpk.FullRange; } monadicReadFeedState = TryCatch <ReadFeedCrossFeedRangeState> .FromResult(ReadFeedCrossFeedRangeState.CreateFromBeginning(feedRange)); } else { monadicReadFeedState = ReadFeedCrossFeedRangeState.Monadic.Parse(continuationToken); } if (monadicReadFeedState.Failed) { this.monadicEnumerator = TryCatch <CrossPartitionReadFeedAsyncEnumerator> .FromException(monadicReadFeedState.Exception); } else { this.monadicEnumerator = TryCatch <CrossPartitionReadFeedAsyncEnumerator> .FromResult( CrossPartitionReadFeedAsyncEnumerator.Create( documentContainer, new CrossFeedRangeState <ReadFeedState>(monadicReadFeedState.Result.FeedRangeStates), readFeedPaginationOptions, cancellationToken)); } this.hasMoreResults = true; }