public async Task <XeroOAuth2Token> GetStoredToken(string tenantId = null) { var partitionKey = new PartitionKey(nameof(PartitionKeyValue.Xero)); // strategy 1 by query async Task <Token> GetTheFirstOne() { var queryRequestOptions = new QueryRequestOptions() { PartitionKey = partitionKey, MaxConcurrency = 1 }; var query = _container.GetItemQueryIterator <Token>( "SELECT top 1 * FROM c", requestOptions: queryRequestOptions); var feed = await query.ReadNextAsync(); return(feed.FirstOrDefault()); } // strategy 2 by read item async Task <Token> GetByTenantId() { var resp = await _container.ReadItemAsync <Token>(tenantId, partitionKey); return(resp); } var result = tenantId == null ? await GetTheFirstOne() : await GetByTenantId(); if (result == null) { return(null); } // remap to XeroOAuth2Token object var xeroToken = result.IsOrMap <XeroOAuth2Token>(); xeroToken.Tenants = new[] { result.Tenant }.ToList(); return(xeroToken); }
public override FeedIteratorInternal GetReadFeedIterator(QueryDefinition queryDefinition, QueryRequestOptions queryRequestOptions, string resourceLink, Documents.ResourceType resourceType, string continuationToken, int pageSize) { return(base.GetReadFeedIterator(queryDefinition, queryRequestOptions, resourceLink, resourceType, continuationToken, pageSize)); }
private async Task <ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnostics, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Stream stream = null; OperationType operation = OperationType.ReadFeed; if (this.querySpec != null) { stream = this.clientContext.SerializerCore.ToStreamSqlQuerySpec(this.querySpec, this.resourceType); operation = OperationType.Query; } if (this.feedTokenInternal == null) { TryCatch <FeedTokenInternal> tryCatchFeedTokeninternal = await this.TryInitializeFeedTokenAsync(cancellationToken); if (!tryCatchFeedTokeninternal.Succeeded) { if (tryCatchFeedTokeninternal.Exception.InnerException is CosmosException cosmosException) { return(cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics))); } return(CosmosExceptionFactory.CreateInternalServerErrorException( message: tryCatchFeedTokeninternal.Exception.InnerException.Message, innerException: tryCatchFeedTokeninternal.Exception.InnerException, diagnosticsContext: diagnostics).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics))); } this.feedTokenInternal = tryCatchFeedTokeninternal.Result; } ResponseMessage response = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri : this.resourceLink, resourceType : this.resourceType, operationType : operation, requestOptions : this.requestOptions, cosmosContainerCore : null, partitionKey : this.requestOptions?.PartitionKey, streamPayload : stream, requestEnricher : request => { QueryRequestOptions.FillContinuationToken(request, this.ContinuationToken); if (this.querySpec != null) { request.Headers.Add(HttpConstants.HttpHeaders.ContentType, MediaTypes.QueryJson); request.Headers.Add(HttpConstants.HttpHeaders.IsQuery, bool.TrueString); } this.feedTokenInternal?.EnrichRequest(request); }, diagnosticsScope : diagnostics, cancellationToken : cancellationToken); // Retry in case of splits or other scenarios only on partitioned resources if (this.containerCore != null && await this.feedTokenInternal.ShouldRetryAsync(this.containerCore, response, cancellationToken)) { return(await this.ReadNextInternalAsync(diagnostics, cancellationToken)); } if (response.IsSuccessStatusCode) { this.feedTokenInternal.UpdateContinuation(response.Headers.ContinuationToken); this.ContinuationToken = this.feedTokenInternal.GetContinuation(); this.hasMoreResultsInternal = !this.feedTokenInternal.IsDone; } else { this.hasMoreResultsInternal = false; } return(response); }
public override IAsyncEnumerable <TryCatch <ReadFeedPage> > GetReadFeedAsyncEnumerable( ReadFeedCrossFeedRangeState state, QueryRequestOptions requestOptions = null) { return(base.GetReadFeedAsyncEnumerable(state, requestOptions)); }
/// <summary> /// This method creates a query for users under an database using a SQL statement. It returns a FeedIterator. /// For more information on preparing SQL statements with parameterized values, please see <see cref="QueryDefinition"/> overload. /// </summary> /// <param name="queryText">The cosmos SQL query text.</param> /// <param name="continuationToken">(Optional) The continuation token in the Azure Cosmos DB service.</param> /// <param name="requestOptions">(Optional) The options for the user query request <see cref="QueryRequestOptions"/></param> /// <returns>An iterator to go through the users</returns> /// <example> /// 1. This create the type feed iterator for users with queryText as input, /// <code language="c#"> /// <![CDATA[ /// string queryText = "SELECT * FROM c where c.id like '%testId%'"; /// FeedIterator<UserProperties> resultSet = this.cosmosDatabase.GetUserQueryIterator<UserProperties>(queryText); /// while (feedIterator.HasMoreResults) /// { /// FeedResponse<UserProperties> iterator = await feedIterator.ReadNextAsync(this.cancellationToken); /// } /// ]]> /// </code> /// </example> /// <example> /// 2. This create the type feed iterator for users without queryText, retrieving all users. /// <code language="c#"> /// <![CDATA[ /// FeedIterator<UserProperties> resultSet = this.cosmosDatabase.GetUserQueryIterator<ContainerProperties>(); /// while (feedIterator.HasMoreResults) /// { /// FeedResponse<UserProperties> iterator = /// await feedIterator.ReadNextAsync(this.cancellationToken); /// } /// ]]> /// </code> /// </example> public abstract FeedIterator <T> GetUserQueryIterator <T>( string queryText = null, string continuationToken = null, QueryRequestOptions requestOptions = null);
/// <summary> /// This method creates a query for users under an database using a SQL statement. It returns a FeedIterator. /// For more information on preparing SQL statements with parameterized values, please see <see cref="QueryDefinition"/> overload. /// </summary> /// <param name="queryDefinition">The cosmos SQL query definition.</param> /// <param name="continuationToken">(Optional) The continuation token in the Azure Cosmos DB service.</param> /// <param name="requestOptions">(Optional) The options for the user query request <see cref="QueryRequestOptions"/></param> /// <returns>An iterator to go through the users</returns> /// <example> /// This create the type feed iterator for users with queryDefinition as input. /// <code language="c#"> /// <![CDATA[ /// string queryText = "SELECT * FROM c where c.id like @testId"; /// QueryDefinition queryDefinition = new QueryDefinition(queryText); /// queryDefinition.WithParameter("@testId", "testUserId"); /// FeedIterator<UserProperties> resultSet = this.cosmosDatabase.GetUserQueryIterator<UserProperties>(queryDefinition); /// while (feedIterator.HasMoreResults) /// { /// foreach (UserProperties properties in await feedIterator.ReadNextAsync()) /// { /// Console.WriteLine(properties.Id); /// } /// } /// ]]> /// </code> /// </example> public abstract FeedIterator <T> GetUserQueryIterator <T>( QueryDefinition queryDefinition, string continuationToken = null, QueryRequestOptions requestOptions = null);
/// <summary> /// This method creates a query for containers under an database using a SQL statement. It returns a FeedIterator. /// For more information on preparing SQL statements with parameterized values, please see <see cref="QueryDefinition"/> overload. /// </summary> /// <param name="queryDefinition">The cosmos SQL query definition.</param> /// <param name="continuationToken">The continuation token in the Azure Cosmos DB service.</param> /// <param name="requestOptions">(Optional) The options for the container request <see cref="QueryRequestOptions"/></param> /// <returns>An iterator to go through the containers</returns> /// <example> /// This create the stream feed iterator for containers with queryDefinition as input. /// <code language="c#"> /// <![CDATA[ /// string queryText = "SELECT * FROM c where c.id like '%testId%'"; /// QueryDefinition queryDefinition = new QueryDefinition(queryText); /// FeedIterator resultSet = this.cosmosDatabase.GetContainerQueryStreamIterator(queryDefinition); /// while (feedIterator.HasMoreResults) /// { /// using (ResponseMessage response = await feedIterator.ReadNextAsync()) /// { /// using (StreamReader sr = new StreamReader(response.Content)) /// using (JsonTextReader jtr = new JsonTextReader(sr)) /// { /// JObject result = JObject.Load(jtr); /// } /// } /// } /// ]]> /// </code> /// </example> /// <remarks> /// Refer to https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started for syntax and examples. /// <para> /// <see cref="Container.ReadContainerStreamAsync(ContainerRequestOptions, CancellationToken)" /> is recommended for single container look-up. /// </para> /// </remarks> public abstract FeedIterator GetContainerQueryStreamIterator( QueryDefinition queryDefinition, string continuationToken = null, QueryRequestOptions requestOptions = null);
/// <summary> /// This method creates a query for containers under an database using a SQL statement. It returns a FeedIterator. /// For more information on preparing SQL statements with parameterized values, please see <see cref="QueryDefinition"/> overload. /// </summary> /// <param name="queryText">The cosmos SQL query text.</param> /// <param name="continuationToken">The continuation token in the Azure Cosmos DB service.</param> /// <param name="requestOptions">(Optional) The options for the container request <see cref="QueryRequestOptions"/></param> /// <returns>An iterator to go through the containers</returns> /// <example> /// 1. This create the stream feed iterator for containers with queryText as input. /// <code language="c#"> /// <![CDATA[ /// string queryText = "SELECT * FROM c where c.id like '%testId%'"; /// FeedIterator resultSet = this.cosmosDatabase.GetContainerQueryStreamIterator(queryText); /// while (feedIterator.HasMoreResults) /// { /// ResponseMessage iterator = /// await feedIterator.ReadNextAsync(this.cancellationToken); /// } /// ]]> /// </code> /// </example> /// <example> /// 2. This create the stream feed iterator for containers without queryText, retrieving all container. /// <code language="c#"> /// <![CDATA[ /// FeedIterator resultSet = this.cosmosDatabase.GetContainerQueryStreamIterator(); /// while (feedIterator.HasMoreResults) /// { /// ResponseMessage iterator = /// await feedIterator.ReadNextAsync(this.cancellationToken); /// } /// ]]> /// </code> /// </example> /// <remarks> /// Refer to https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started for syntax and examples. /// <para> /// <see cref="Container.ReadContainerStreamAsync(ContainerRequestOptions, CancellationToken)" /> is recommended for single container look-up. /// </para> /// </remarks> public abstract FeedIterator GetContainerQueryStreamIterator( string queryText = null, string continuationToken = null, QueryRequestOptions requestOptions = null);
public abstract FeedIteratorInternal GetItemQueryStreamIteratorInternal( SqlQuerySpec sqlQuerySpec, bool isContinuationExcpected, string continuationToken, FeedRangeInternal feedRange, QueryRequestOptions requestOptions);
/// <summary> /// Used in the compute gateway to support legacy gateway interface. /// </summary> public override async Task <TryExecuteQueryResult> TryExecuteQueryAsync( QueryFeatures supportedQueryFeatures, QueryDefinition queryDefinition, string continuationToken, FeedRangeInternal feedRangeInternal, QueryRequestOptions requestOptions, CancellationToken cancellationToken = default(CancellationToken)) { if (queryDefinition == null) { throw new ArgumentNullException(nameof(queryDefinition)); } if (requestOptions == null) { throw new ArgumentNullException(nameof(requestOptions)); } if (feedRangeInternal != null) { // The user has scoped down to a physical partition or logical partition. // In either case let the query execute as a passthrough. QueryIterator passthroughQueryIterator = QueryIterator.Create( client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: queryDefinition.ToSqlQuerySpec(), continuationToken: continuationToken, feedRangeInternal: feedRangeInternal, queryRequestOptions: requestOptions, resourceLink: this.LinkUri, isContinuationExpected: false, allowNonValueAggregateQuery: true, forcePassthrough: true, // Forcing a passthrough, since we don't want to get the query plan nor try to rewrite it. partitionedQueryExecutionInfo: null); return(new QueryPlanIsSupportedResult(passthroughQueryIterator)); } cancellationToken.ThrowIfCancellationRequested(); Documents.PartitionKeyDefinition partitionKeyDefinition; if (requestOptions.Properties != null && requestOptions.Properties.TryGetValue("x-ms-query-partitionkey-definition", out object partitionKeyDefinitionObject)) { if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition) { partitionKeyDefinition = definition; } else { throw new ArgumentException( "partitionkeydefinition has invalid type", nameof(partitionKeyDefinitionObject)); } } else { ContainerQueryProperties containerQueryProperties = await this.queryClient.GetCachedContainerQueryPropertiesAsync( this.LinkUri, requestOptions.PartitionKey, cancellationToken); partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition; } QueryPlanHandler queryPlanHandler = new QueryPlanHandler(this.queryClient); TryCatch <(PartitionedQueryExecutionInfo queryPlan, bool supported)> tryGetQueryInfoAndIfSupported = await queryPlanHandler.TryGetQueryInfoAndIfSupportedAsync( supportedQueryFeatures, queryDefinition.ToSqlQuerySpec(), partitionKeyDefinition, requestOptions.PartitionKey.HasValue, cancellationToken); if (tryGetQueryInfoAndIfSupported.Failed) { return(new FailedToGetQueryPlanResult(tryGetQueryInfoAndIfSupported.Exception)); } (PartitionedQueryExecutionInfo queryPlan, bool supported) = tryGetQueryInfoAndIfSupported.Result; TryExecuteQueryResult tryExecuteQueryResult; if (supported) { QueryIterator queryIterator = QueryIterator.Create( client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: queryDefinition.ToSqlQuerySpec(), continuationToken: continuationToken, feedRangeInternal: feedRangeInternal, queryRequestOptions: requestOptions, resourceLink: this.LinkUri, isContinuationExpected: false, allowNonValueAggregateQuery: true, forcePassthrough: false, partitionedQueryExecutionInfo: queryPlan); tryExecuteQueryResult = new QueryPlanIsSupportedResult(queryIterator); } else { tryExecuteQueryResult = new QueryPlanNotSupportedResult(queryPlan); } return(tryExecuteQueryResult); }
public abstract FeedIterator <T> GetItemQueryIterator <T>( FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken = null, QueryRequestOptions requestOptions = null);
public abstract FeedIterator GetItemQueryStreamIterator( FeedRange feedRange, QueryDefinition queryDefinition, string continuationToken, QueryRequestOptions requestOptions = null);
public abstract IAsyncEnumerable <TryCatch <ReadFeedPage> > GetReadFeedAsyncEnumerable( ReadFeedCrossFeedRangeState state, QueryRequestOptions requestOptions = null);
/// <summary> /// Used in the compute gateway to support legacy gateway interface. /// </summary> internal override async Task <((Exception, PartitionedQueryExecutionInfo), (bool, QueryIterator))> TryExecuteQueryAsync( QueryFeatures supportedQueryFeatures, QueryDefinition queryDefinition, string continuationToken, FeedRangeInternal feedRangeInternal, QueryRequestOptions requestOptions, CancellationToken cancellationToken = default(CancellationToken)) { if (queryDefinition == null) { throw new ArgumentNullException(nameof(queryDefinition)); } if (requestOptions == null) { throw new ArgumentNullException(nameof(requestOptions)); } cancellationToken.ThrowIfCancellationRequested(); Documents.PartitionKeyDefinition partitionKeyDefinition; if (requestOptions.Properties != null && requestOptions.Properties.TryGetValue("x-ms-query-partitionkey-definition", out object partitionKeyDefinitionObject)) { if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition) { partitionKeyDefinition = definition; } else { throw new ArgumentException( "partitionkeydefinition has invalid type", nameof(partitionKeyDefinitionObject)); } } else { ContainerQueryProperties containerQueryProperties = await this.queryClient.GetCachedContainerQueryPropertiesAsync( this.LinkUri, requestOptions.PartitionKey, cancellationToken); partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition; } QueryPlanHandler queryPlanHandler = new QueryPlanHandler(this.queryClient); ((Exception exception, PartitionedQueryExecutionInfo partitionedQueryExecutionInfo), bool supported) = await queryPlanHandler.TryGetQueryInfoAndIfSupportedAsync( supportedQueryFeatures, queryDefinition.ToSqlQuerySpec(), partitionKeyDefinition, requestOptions.PartitionKey.HasValue, cancellationToken); if (exception != null) { return((exception, null), (false, null)); } QueryIterator queryIterator; if (supported) { queryIterator = QueryIterator.Create( client: this.queryClient, clientContext: this.ClientContext, sqlQuerySpec: queryDefinition.ToSqlQuerySpec(), continuationToken: continuationToken, feedRangeInternal: feedRangeInternal, queryRequestOptions: requestOptions, resourceLink: this.LinkUri, isContinuationExpected: false, allowNonValueAggregateQuery: true, partitionedQueryExecutionInfo: partitionedQueryExecutionInfo); } else { queryIterator = null; } return((null, partitionedQueryExecutionInfo), (supported, queryIterator)); }
public override IOrderedQueryable <T> CreateItemQuery <T>(object partitionKey = null, bool allowSynchronousQueryExecution = false, QueryRequestOptions requestOptions = null) { requestOptions = requestOptions != null ? requestOptions : new QueryRequestOptions(); if (partitionKey != null) { requestOptions.PartitionKey = new PartitionKey(partitionKey); } else { requestOptions.EnableCrossPartitionQuery = true; } return(new CosmosLinqQuery <T>(this, this.ClientContext.CosmosSerializer, this.queryClient, requestOptions, allowSynchronousQueryExecution)); }