/// <summary>
        /// Retrieves an object that can iterate through the individual results of the query.
        /// </summary>
        /// <remarks>
        /// This triggers a synchronous multi-page load.
        /// </remarks>
        /// <returns>IEnumerator</returns>
        public IEnumerator <T> GetEnumerator()
        {
            if (!this.allowSynchronousQueryExecution)
            {
                throw new NotSupportedException("To execute LINQ query please set " + nameof(allowSynchronousQueryExecution) + " true or" +
                                                " use GetItemsQueryIterator to execute asynchronously");
            }

            using (CosmosQueryExecutionContext localQueryExecutionContext = CreateCosmosQueryExecutionContext())
            {
                while (!localQueryExecutionContext.IsDone)
                {
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
                    QueryResponse cosmosQueryResponse = TaskHelper.InlineIfPossible(() => localQueryExecutionContext.ExecuteNextAsync(CancellationToken.None), null).GetAwaiter().GetResult();
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
                    QueryResponse <T> responseIterator = QueryResponse <T> .CreateResponse <T>(
                        cosmosQueryResponse : cosmosQueryResponse,
                        jsonSerializer : cosmosJsonSerializer,
                        hasMoreResults : !localQueryExecutionContext.IsDone);

                    foreach (T item in responseIterator)
                    {
                        yield return(item);
                    }
                }
            }
        }
Beispiel #2
0
        internal async Task <FeedResponse <T> > NextResultSetAsync <T>(
            int?maxItemCount,
            string continuationToken,
            RequestOptions options,
            object state,
            CancellationToken cancellationToken)
        {
            CosmosQueryExecutionContext cosmosQueryExecution = (CosmosQueryExecutionContext)state;
            QueryResponse queryResponse = await cosmosQueryExecution.ExecuteNextAsync(cancellationToken);

            queryResponse.EnsureSuccessStatusCode();

            return(QueryResponse <T> .CreateResponse <T>(
                       cosmosQueryResponse : queryResponse,
                       jsonSerializer : this.ClientContext.CosmosSerializer,
                       hasMoreResults : !cosmosQueryExecution.IsDone));
        }
Beispiel #3
0
        private async Task <ResponseMessage> QueryRequestExecutorAsync(
            int?maxItemCount,
            string continuationToken,
            RequestOptions options,
            object state,
            CancellationToken cancellationToken)
        {
            // This catches exception thrown by the caches and converts it to QueryResponse
            try
            {
                CosmosQueryExecutionContext cosmosQueryExecution = (CosmosQueryExecutionContext)state;
                return(await cosmosQueryExecution.ExecuteNextAsync(cancellationToken));
            }
            catch (DocumentClientException exception)
            {
                return(exception.ToCosmosResponseMessage(request: null));
            }
            catch (CosmosException exception)
            {
                return(new ResponseMessage(
                           headers: exception.Headers,
                           requestMessage: null,
                           errorMessage: exception.Message,
                           statusCode: exception.StatusCode,
                           error: exception.Error));
            }
            catch (AggregateException ae)
            {
                ResponseMessage errorMessage = TransportHandler.AggregateExceptionConverter(ae, null);
                if (errorMessage != null)
                {
                    return(errorMessage);
                }

                throw;
            }
        }
Beispiel #4
0
        public async Task TestCosmosQueryPartitionKeyDefinition()
        {
            PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition();
            QueryRequestOptions    queryRequestOptions    = new QueryRequestOptions
            {
                Properties = new Dictionary <string, object>()
                {
                    { "x-ms-query-partitionkey-definition", partitionKeyDefinition }
                }
            };

            SqlQuerySpec            sqlQuerySpec = new SqlQuerySpec(@"select * from t where t.something = 42 ");
            bool                    allowNonValueAggregateQuery = true;
            bool                    isContinuationExpected      = true;
            CancellationTokenSource cancellationTokenSource     = new CancellationTokenSource();
            CancellationToken       cancellationtoken           = cancellationTokenSource.Token;

            Mock <CosmosQueryClient> client = new Mock <CosmosQueryClient>();
            string exceptionMessage         = "Verified that the PartitionKeyDefinition was correctly set. Cancel the rest of the query";

            client
            .Setup(x => x.GetCachedContainerQueryPropertiesAsync(It.IsAny <Uri>(), It.IsAny <Cosmos.PartitionKey?>(), cancellationtoken))
            .ReturnsAsync(new ContainerQueryProperties("mockContainer", null, partitionKeyDefinition));
            client
            .Setup(x => x.ByPassQueryParsing())
            .Returns(false);
            client
            .Setup(x => x.TryGetPartitionedQueryExecutionInfoAsync(
                       It.IsAny <SqlQuerySpec>(),
                       It.IsAny <PartitionKeyDefinition>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(TryCatch <PartitionedQueryExecutionInfo> .FromException(
                              new InvalidOperationException(
                                  exceptionMessage)));

            CosmosQueryExecutionContextFactory.InputParameters inputParameters = new CosmosQueryExecutionContextFactory.InputParameters(
                sqlQuerySpec: sqlQuerySpec,
                initialUserContinuationToken: null,
                maxConcurrency: queryRequestOptions?.MaxConcurrency,
                maxItemCount: queryRequestOptions?.MaxItemCount,
                maxBufferedItemCount: queryRequestOptions?.MaxBufferedItemCount,
                partitionKey: queryRequestOptions?.PartitionKey,
                properties: queryRequestOptions?.Properties,
                partitionedQueryExecutionInfo: null,
                executionEnvironment: queryRequestOptions?.ExecutionEnvironment,
                testInjections: queryRequestOptions?.TestSettings);

            CosmosQueryContext cosmosQueryContext = new CosmosQueryContextCore(
                client: client.Object,
                queryRequestOptions: queryRequestOptions,
                resourceTypeEnum: ResourceType.Document,
                operationType: OperationType.Query,
                resourceType: typeof(QueryResponse),
                resourceLink: new Uri("dbs/mockdb/colls/mockColl", UriKind.Relative),
                isContinuationExpected: isContinuationExpected,
                allowNonValueAggregateQuery: allowNonValueAggregateQuery,
                correlatedActivityId: new Guid("221FC86C-1825-4284-B10E-A6029652CCA6"));

            CosmosQueryExecutionContext context = CosmosQueryExecutionContextFactory.Create(
                cosmosQueryContext,
                inputParameters);

            QueryResponseCore queryResponse = await context.ExecuteNextAsync(cancellationtoken);

            Assert.AreEqual(HttpStatusCode.BadRequest, queryResponse.StatusCode);
            Assert.IsTrue(queryResponse.ErrorMessage.Contains(exceptionMessage), "response error message did not contain the proper substring.");
        }