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));
        }
示例#2
0
            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)));
            }
示例#5
0
            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));
            }
示例#6
0
                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));
                }
示例#7
0
                /// <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);
     }
 }
示例#12
0
        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)));
        }
示例#13
0
            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));
            }