public static async Task <TakeDocumentQueryExecutionComponent> CreateLimitDocumentQueryExecutionComponentAsync( int limitCount, string continuationToken, Func <string, Task <IDocumentQueryExecutionComponent> > createSourceCallback) { LimitContinuationToken limitContinuationToken; if (continuationToken != null) { limitContinuationToken = LimitContinuationToken.Parse(continuationToken); } else { limitContinuationToken = new LimitContinuationToken(limitCount, null); } if (limitContinuationToken.Limit > limitCount) { throw new BadRequestException($"limit count in continuation token: {limitContinuationToken.Limit} can not be greater than the limit count in the query: {limitCount}."); } return(new TakeDocumentQueryExecutionComponent( await createSourceCallback(limitContinuationToken.SourceToken), limitContinuationToken.Limit, TakeEnum.Limit)); }
public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateLimitDocumentQueryExecutionComponentAsync( int limitCount, CosmosElement requestContinuationToken, Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync) { if (limitCount < 0) { throw new ArgumentException($"{nameof(limitCount)}: {limitCount} must be a non negative number."); } if (tryCreateSourceAsync == null) { throw new ArgumentNullException(nameof(tryCreateSourceAsync)); } LimitContinuationToken limitContinuationToken; if (requestContinuationToken != null) { if (!LimitContinuationToken.TryParse(requestContinuationToken.ToString(), out limitContinuationToken)) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException($"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}."))); } } else { limitContinuationToken = new LimitContinuationToken(limitCount, null); } if (limitContinuationToken.Limit > limitCount) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException($"{nameof(LimitContinuationToken.Limit)} in {nameof(LimitContinuationToken)}: {requestContinuationToken}: {limitContinuationToken.Limit} can not be greater than the limit count in the query: {limitCount}."))); } CosmosElement sourceToken; if (limitContinuationToken.SourceToken != null) { if (!CosmosElement.TryParse(limitContinuationToken.SourceToken, out sourceToken)) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException($"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}."))); } } else { sourceToken = null; } return((await tryCreateSourceAsync(sourceToken)) .Try <IDocumentQueryExecutionComponent>((source) => new ClientTakeDocumentQueryExecutionComponent( source, limitContinuationToken.Limit, TakeEnum.Limit))); }
public override async Task <QueryResponseCore> DrainAsync(int maxElements, CancellationToken token) { token.ThrowIfCancellationRequested(); QueryResponseCore results = await base.DrainAsync(maxElements, token); if (!results.IsSuccess) { return(results); } List <CosmosElement> takedDocuments = results.CosmosElements.Take(this.takeCount).ToList(); this.takeCount -= takedDocuments.Count; string updatedContinuationToken = null; if (results.DisallowContinuationTokenMessage == null) { if (!this.IsDone) { string sourceContinuation = results.ContinuationToken; TakeContinuationToken takeContinuationToken; switch (this.takeEnum) { case TakeEnum.Limit: takeContinuationToken = new LimitContinuationToken( this.takeCount, sourceContinuation); break; case TakeEnum.Top: takeContinuationToken = new TopContinuationToken( this.takeCount, sourceContinuation); break; default: throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}"); } updatedContinuationToken = takeContinuationToken.ToString(); } } return(QueryResponseCore.CreateSuccess( result: takedDocuments, continuationToken: updatedContinuationToken, disallowContinuationTokenMessage: results.DisallowContinuationTokenMessage, activityId: results.ActivityId, requestCharge: results.RequestCharge, queryMetricsText: results.QueryMetricsText, queryMetrics: results.QueryMetrics, requestStatistics: results.RequestStatistics, responseLengthBytes: results.ResponseLengthBytes)); }
public override async Task <FeedResponse <CosmosElement> > DrainAsync(int maxElements, CancellationToken token) { FeedResponse <CosmosElement> results = await base.DrainAsync(maxElements, token); List <CosmosElement> takedDocuments = results.Take(this.takeCount).ToList(); results = new FeedResponse <CosmosElement>( takedDocuments, takedDocuments.Count, results.Headers, results.UseETagAsContinuation, results.QueryMetrics, results.RequestStatistics, results.DisallowContinuationTokenMessage, results.ResponseLengthBytes); this.takeCount -= takedDocuments.Count; if (results.DisallowContinuationTokenMessage == null) { if (!this.IsDone) { string sourceContinuation = results.ResponseContinuation; TakeContinuationToken takeContinuationToken; switch (this.takeEnum) { case TakeEnum.Limit: takeContinuationToken = new LimitContinuationToken( this.takeCount, sourceContinuation); break; case TakeEnum.Top: takeContinuationToken = new TopContinuationToken( this.takeCount, sourceContinuation); break; default: throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {takeEnum}"); } results.ResponseContinuation = takeContinuationToken.ToString(); } else { results.ResponseContinuation = null; } } return(results); }
public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token) { token.ThrowIfCancellationRequested(); QueryResponse results = await base.DrainAsync(maxElements, token); if (!results.IsSuccessStatusCode) { return(results); } List <CosmosElement> takedDocuments = results.CosmosElements.Take(this.takeCount).ToList(); this.takeCount -= takedDocuments.Count; string updatedContinuationToken = null; if (results.QueryHeaders.DisallowContinuationTokenMessage == null) { if (!this.IsDone) { string sourceContinuation = results.Headers.ContinuationToken; TakeContinuationToken takeContinuationToken; switch (this.takeEnum) { case TakeEnum.Limit: takeContinuationToken = new LimitContinuationToken( this.takeCount, sourceContinuation); break; case TakeEnum.Top: takeContinuationToken = new TopContinuationToken( this.takeCount, sourceContinuation); break; default: throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}"); } updatedContinuationToken = takeContinuationToken.ToString(); } } return(QueryResponse.CreateSuccess( takedDocuments, takedDocuments.Count, results.ResponseLengthBytes, results.QueryHeaders.CloneKnownProperties(updatedContinuationToken, results.QueryHeaders.DisallowContinuationTokenMessage), results.queryMetrics)); }
public override async Task <QueryResponseCore> DrainAsync(int maxElements, CancellationToken token) { token.ThrowIfCancellationRequested(); QueryResponseCore sourcePage = await base.DrainAsync(maxElements, token); if (!sourcePage.IsSuccess) { return(sourcePage); } List <CosmosElement> takedDocuments = sourcePage.CosmosElements.Take(this.takeCount).ToList(); this.takeCount -= takedDocuments.Count; string updatedContinuationToken; if (!this.IsDone && (sourcePage.DisallowContinuationTokenMessage == null)) { switch (this.takeEnum) { case TakeEnum.Limit: updatedContinuationToken = new LimitContinuationToken( limit: this.takeCount, sourceToken: sourcePage.ContinuationToken).ToString(); break; case TakeEnum.Top: updatedContinuationToken = new TopContinuationToken( top: this.takeCount, sourceToken: sourcePage.ContinuationToken).ToString(); break; default: throw new ArgumentOutOfRangeException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}."); } } else { updatedContinuationToken = null; } return(QueryResponseCore.CreateSuccess( result: takedDocuments, continuationToken: updatedContinuationToken, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, activityId: sourcePage.ActivityId, requestCharge: sourcePage.RequestCharge, diagnostics: sourcePage.Diagnostics, responseLengthBytes: sourcePage.ResponseLengthBytes)); }
/// <summary> /// Tries to parse out the LimitContinuationToken. /// </summary> /// <param name="value">The value to parse from.</param> /// <param name="limitContinuationToken">The result of parsing out the token.</param> /// <returns>Whether or not the LimitContinuationToken was successfully parsed out.</returns> public static bool TryParse(string value, out LimitContinuationToken limitContinuationToken) { limitContinuationToken = default; if (string.IsNullOrWhiteSpace(value)) { return(false); } try { limitContinuationToken = JsonConvert.DeserializeObject <LimitContinuationToken>(value); return(true); } catch (JsonException) { return(false); } }
public override bool TryGetContinuationToken(out string state) { if (!this.IsDone) { if (this.Source.TryGetContinuationToken(out string sourceState)) { TakeContinuationToken takeContinuationToken; switch (this.takeEnum) { case TakeEnum.Limit: takeContinuationToken = new LimitContinuationToken( this.takeCount, sourceState); break; case TakeEnum.Top: takeContinuationToken = new TopContinuationToken( this.takeCount, sourceState); break; default: throw new ArgumentException($"Unknown {nameof(TakeEnum)}: {this.takeEnum}"); } state = takeContinuationToken.ToString(); return(true); } else { state = default(string); return(false); } } else { state = default(string); return(true); } }
/// <summary> /// Tries to parse out the LimitContinuationToken. /// </summary> /// <param name="value">The value to parse from.</param> /// <param name="LimitContinuationToken">The result of parsing out the token.</param> /// <returns>Whether or not the LimitContinuationToken was successfully parsed out.</returns> public static bool TryParse(string value, out LimitContinuationToken LimitContinuationToken) { LimitContinuationToken = default(LimitContinuationToken); if (string.IsNullOrWhiteSpace(value)) { return(false); } try { LimitContinuationToken = JsonConvert.DeserializeObject <LimitContinuationToken>(value); return(true); } catch (JsonException ex) { DefaultTrace.TraceWarning(string.Format( CultureInfo.InvariantCulture, "{0} Invalid continuation token {1} for limit~Component, exception: {2}", DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture), value, ex.Message)); return(false); } }
public static TryCatch <IQueryPipelineStage> MonadicCreateLimitStage( int limitCount, CosmosElement requestContinuationToken, CancellationToken cancellationToken, MonadicCreatePipelineStage monadicCreatePipelineStage) { if (limitCount < 0) { throw new ArgumentException($"{nameof(limitCount)}: {limitCount} must be a non negative number."); } if (monadicCreatePipelineStage == null) { throw new ArgumentNullException(nameof(monadicCreatePipelineStage)); } LimitContinuationToken limitContinuationToken; if (requestContinuationToken != null) { if (!LimitContinuationToken.TryParse(requestContinuationToken.ToString(), out limitContinuationToken)) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( $"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}."))); } } else { limitContinuationToken = new LimitContinuationToken(limitCount, null); } if (limitContinuationToken.Limit > limitCount) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( $"{nameof(LimitContinuationToken.Limit)} in {nameof(LimitContinuationToken)}: {requestContinuationToken}: {limitContinuationToken.Limit} can not be greater than the limit count in the query: {limitCount}."))); } CosmosElement sourceToken; if (limitContinuationToken.SourceToken != null) { TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(limitContinuationToken.SourceToken); if (tryParse.Failed) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( message : $"Malformed {nameof(LimitContinuationToken)}: {requestContinuationToken}.", innerException : tryParse.Exception))); } sourceToken = tryParse.Result; } else { sourceToken = null; } TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(sourceToken, cancellationToken); if (tryCreateSource.Failed) { return(tryCreateSource); } IQueryPipelineStage stage = new ClientTakeQueryPipelineStage( tryCreateSource.Result, cancellationToken, limitContinuationToken.Limit, TakeEnum.Limit); return(TryCatch <IQueryPipelineStage> .FromResult(stage)); }