public static async Task <SkipDocumentQueryExecutionComponent> CreateAsync( int offsetCount, string continuationToken, Func <string, Task <IDocumentQueryExecutionComponent> > createSourceCallback) { OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { offsetContinuationToken = OffsetContinuationToken.Parse(continuationToken); } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { throw new ArgumentException("offset count in continuation token can not be greater than the offsetcount in the query."); } return(new SkipDocumentQueryExecutionComponent( await createSourceCallback(offsetContinuationToken.SourceToken), offsetContinuationToken.Offset)); }
public override async ValueTask <bool> MoveNextAsync(ITrace trace) { this.cancellationToken.ThrowIfCancellationRequested(); if (trace == null) { throw new ArgumentNullException(nameof(trace)); } if (!await this.inputStage.MoveNextAsync(trace)) { this.Current = default; return(false); } TryCatch <QueryPage> tryGetSourcePage = this.inputStage.Current; if (tryGetSourcePage.Failed) { this.Current = tryGetSourcePage; return(true); } QueryPage sourcePage = tryGetSourcePage.Result; // Skip the documents but keep all the other headers IReadOnlyList <CosmosElement> documentsAfterSkip = sourcePage.Documents.Skip(this.skipCount).ToList(); int numberOfDocumentsSkipped = sourcePage.Documents.Count() - documentsAfterSkip.Count(); this.skipCount -= numberOfDocumentsSkipped; QueryState state; if (sourcePage.State == null) { state = default; } else { OffsetContinuationToken offsetContinuationToken = new OffsetContinuationToken( offset: this.skipCount, sourceToken: sourcePage.State.Value); state = new QueryState(OffsetContinuationToken.ToCosmosElement(offsetContinuationToken)); } QueryPage queryPage = new QueryPage( documents: documentsAfterSkip, requestCharge: sourcePage.RequestCharge, activityId: sourcePage.ActivityId, responseLengthInBytes: sourcePage.ResponseLengthInBytes, cosmosQueryExecutionInfo: sourcePage.CosmosQueryExecutionInfo, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, state: state); this.Current = TryCatch <QueryPage> .FromResult(queryPage); return(true); }
public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token) { token.ThrowIfCancellationRequested(); QueryResponse sourcePage = await base.DrainAsync(maxElements, token); if (!sourcePage.IsSuccessStatusCode) { return(sourcePage); } // skip the documents but keep all the other headers List <CosmosElement> documentsAfterSkip = sourcePage.CosmosElements.Skip(this.skipCount).ToList(); int numberOfDocumentsSkipped = sourcePage.Count - documentsAfterSkip.Count; this.skipCount -= numberOfDocumentsSkipped; string updatedContinuationToken = null; if (sourcePage.QueryHeaders.DisallowContinuationTokenMessage == null) { if (!this.IsDone) { updatedContinuationToken = new OffsetContinuationToken( this.skipCount, sourcePage.Headers.ContinuationToken).ToString(); } } return(QueryResponse.CreateSuccess( result: documentsAfterSkip, count: documentsAfterSkip.Count(), responseHeaders: sourcePage.QueryHeaders.CloneKnownProperties(updatedContinuationToken, sourcePage.QueryHeaders.DisallowContinuationTokenMessage), responseLengthBytes: sourcePage.ResponseLengthBytes)); }
public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync( int offsetCount, CosmosElement continuationToken, Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync) { if (tryCreateSourceAsync == null) { throw new ArgumentNullException(nameof(tryCreateSourceAsync)); } OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { if (!OffsetContinuationToken.TryParse(continuationToken.ToString(), out offsetContinuationToken)) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException($"Invalid {nameof(SkipDocumentQueryExecutionComponent)}: {continuationToken}."))); } } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException("offset count in continuation token can not be greater than the offsetcount in the query."))); } CosmosElement sourceToken; if (offsetContinuationToken.SourceToken != null) { TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(offsetContinuationToken.SourceToken); if (tryParse.Failed) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException( message : $"source token: '{offsetContinuationToken.SourceToken ?? "<null>"}' is not valid.", innerException : tryParse.Exception))); } sourceToken = tryParse.Result; } else { sourceToken = null; } return((await tryCreateSourceAsync(sourceToken)) .Try <IDocumentQueryExecutionComponent>((source) => new ClientSkipDocumentQueryExecutionComponent( source, offsetContinuationToken.Offset))); }
public static TryCatch <IQueryPipelineStage> MonadicCreate( int offsetCount, CosmosElement continuationToken, CancellationToken cancellationToken, MonadicCreatePipelineStage monadicCreatePipelineStage) { if (monadicCreatePipelineStage == null) { throw new ArgumentNullException(nameof(monadicCreatePipelineStage)); } OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { (bool parsed, OffsetContinuationToken parsedToken) = OffsetContinuationToken.TryParse(continuationToken); if (!parsed) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException($"Invalid {nameof(SkipQueryPipelineStage)}: {continuationToken}."))); } offsetContinuationToken = parsedToken; } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( "offset count in continuation token can not be greater than the offsetcount in the query."))); } TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(offsetContinuationToken.SourceToken, cancellationToken); if (tryCreateSource.Failed) { return(tryCreateSource); } IQueryPipelineStage stage = new ComputeSkipQueryPipelineStage( tryCreateSource.Result, cancellationToken, offsetContinuationToken.Offset); return(TryCatch <IQueryPipelineStage> .FromResult(stage)); }
public static CosmosElement ToCosmosElement(OffsetContinuationToken offsetContinuationToken) { Dictionary <string, CosmosElement> dictionary = new Dictionary <string, CosmosElement>() { { OffsetContinuationToken.ProperytNames.SkipCountProperty, CosmosNumber64.Create(offsetContinuationToken.Offset) }, { OffsetContinuationToken.ProperytNames.SourceTokenProperty, offsetContinuationToken.SourceToken } }; return(CosmosObject.Create(dictionary)); }
/// <summary> /// Tries to parse out the OffsetContinuationToken. /// </summary> /// <param name="value">The value to parse from.</param> /// <param name="offsetContinuationToken">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 OffsetContinuationToken offsetContinuationToken) { offsetContinuationToken = default; if (string.IsNullOrWhiteSpace(value)) { return(false); } try { offsetContinuationToken = JsonConvert.DeserializeObject <OffsetContinuationToken>(value); return(true); } catch (JsonException) { return(false); } }
/// <summary> /// Tries to parse out the OffsetContinuationToken. /// </summary> /// <param name="value">The value to parse from.</param> /// <param name="offsetContinuationToken">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 OffsetContinuationToken offsetContinuationToken) { offsetContinuationToken = default(OffsetContinuationToken); if (string.IsNullOrWhiteSpace(value)) { return(false); } try { offsetContinuationToken = JsonConvert.DeserializeObject <OffsetContinuationToken>(value); return(true); } catch (JsonException ex) { DefaultTrace.TraceWarning($"{DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)} Invalid continuation token {value} for offset~Component, exception: {ex}"); return(false); } }
public override async Task <QueryResponseCore> DrainAsync(int maxElements, CancellationToken token) { token.ThrowIfCancellationRequested(); QueryResponseCore sourcePage = await base.DrainAsync(maxElements, token); if (!sourcePage.IsSuccess) { return(sourcePage); } // skip the documents but keep all the other headers List <CosmosElement> documentsAfterSkip = sourcePage.CosmosElements.Skip(this.skipCount).ToList(); int numberOfDocumentsSkipped = sourcePage.CosmosElements.Count - documentsAfterSkip.Count; this.skipCount -= numberOfDocumentsSkipped; string updatedContinuationToken = null; if (sourcePage.DisallowContinuationTokenMessage == null) { if (!this.IsDone) { updatedContinuationToken = new OffsetContinuationToken( this.skipCount, sourcePage.ContinuationToken).ToString(); } } return(QueryResponseCore.CreateSuccess( result: documentsAfterSkip, continuationToken: updatedContinuationToken, disallowContinuationTokenMessage: sourcePage.DisallowContinuationTokenMessage, activityId: sourcePage.ActivityId, requestCharge: sourcePage.RequestCharge, queryMetricsText: sourcePage.QueryMetricsText, queryMetrics: sourcePage.QueryMetrics, requestStatistics: sourcePage.RequestStatistics, responseLengthBytes: sourcePage.ResponseLengthBytes)); }
public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync( int offsetCount, CosmosElement continuationToken, Func <CosmosElement, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync) { if (tryCreateSourceAsync == null) { throw new ArgumentNullException(nameof(tryCreateSourceAsync)); } OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { (bool parsed, OffsetContinuationToken parsedToken) = OffsetContinuationToken.TryParse(continuationToken); if (!parsed) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException($"Invalid {nameof(SkipDocumentQueryExecutionComponent)}: {continuationToken}."))); } offsetContinuationToken = parsedToken; } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new MalformedContinuationTokenException("offset count in continuation token can not be greater than the offsetcount in the query."))); } return((await tryCreateSourceAsync(offsetContinuationToken.SourceToken)) .Try <IDocumentQueryExecutionComponent>((source) => new ComputeSkipDocumentQueryExecutionComponent( source, offsetContinuationToken.Offset))); }
public override bool TryGetContinuationToken(out string state) { if (!this.IsDone) { if (this.Source.TryGetContinuationToken(out string sourceState)) { state = new OffsetContinuationToken( this.skipCount, sourceState).ToString(); return(true); } else { state = null; return(false); } } else { state = null; return(true); } }
public static async Task <TryCatch <IDocumentQueryExecutionComponent> > TryCreateAsync( int offsetCount, string continuationToken, Func <string, Task <TryCatch <IDocumentQueryExecutionComponent> > > tryCreateSourceAsync) { if (tryCreateSourceAsync == null) { throw new ArgumentNullException(nameof(tryCreateSourceAsync)); } OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { if (!OffsetContinuationToken.TryParse(continuationToken, out offsetContinuationToken)) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new Exception($"Invalid {nameof(SkipDocumentQueryExecutionComponent)}: {continuationToken}."))); } } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { return(TryCatch <IDocumentQueryExecutionComponent> .FromException( new Exception("offset count in continuation token can not be greater than the offsetcount in the query."))); } return((await tryCreateSourceAsync(offsetContinuationToken.SourceToken)) .Try <IDocumentQueryExecutionComponent>((source) => new SkipDocumentQueryExecutionComponent( source, offsetContinuationToken.Offset))); }
public static TryCatch <IQueryPipelineStage> MonadicCreate( int offsetCount, CosmosElement continuationToken, CancellationToken cancellationToken, MonadicCreatePipelineStage monadicCreatePipelineStage) { if (monadicCreatePipelineStage == null) { throw new ArgumentNullException(nameof(monadicCreatePipelineStage)); } OffsetContinuationToken offsetContinuationToken; if (continuationToken != null) { if (!OffsetContinuationToken.TryParse(continuationToken.ToString(), out offsetContinuationToken)) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( $"Invalid {nameof(SkipQueryPipelineStage)}: {continuationToken}."))); } } else { offsetContinuationToken = new OffsetContinuationToken(offsetCount, null); } if (offsetContinuationToken.Offset > offsetCount) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( "offset count in continuation token can not be greater than the offsetcount in the query."))); } CosmosElement sourceToken; if (offsetContinuationToken.SourceToken != null) { TryCatch <CosmosElement> tryParse = CosmosElement.Monadic.Parse(offsetContinuationToken.SourceToken); if (tryParse.Failed) { return(TryCatch <IQueryPipelineStage> .FromException( new MalformedContinuationTokenException( message : $"source token: '{offsetContinuationToken.SourceToken ?? "<null>"}' is not valid.", innerException : tryParse.Exception))); } sourceToken = tryParse.Result; } else { sourceToken = null; } TryCatch <IQueryPipelineStage> tryCreateSource = monadicCreatePipelineStage(sourceToken, cancellationToken); if (tryCreateSource.Failed) { return(tryCreateSource); } IQueryPipelineStage stage = new ClientSkipQueryPipelineStage( tryCreateSource.Result, cancellationToken, offsetContinuationToken.Offset); return(TryCatch <IQueryPipelineStage> .FromResult(stage)); }