/// <summary>
        /// Check if a database exists, and if it doesn't, create it.
        /// This will make a read operation, and if the database is not found it will do a create operation.
        ///
        /// A database manages users, permissions and a set of containers.
        /// Each Azure Cosmos DB Database Account is able to support multiple independent named databases,
        /// with the database being the logical container for data.
        ///
        /// Each Database consists of one or more containers, each of which in turn contain one or more
        /// documents. Since databases are an administrative resource, the Service Master Key will be
        /// required in order to access and successfully complete any action using the User APIs.
        /// </summary>
        /// <param name="id">The database id.</param>
        /// <param name="requestUnitsPerSecond">(Optional) The throughput provisioned for a database in measurement of Request Units per second in the Azure Cosmos DB service.</param>
        /// <param name="requestOptions">(Optional) A set of additional options that can be set.</param>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A <see cref="Task"/> containing a <see cref="DatabaseResponse"/> which wraps a <see cref="CosmosDatabaseSettings"/> containing the resource record.</returns>
        /// <remarks>
        /// <seealso href="https://docs.microsoft.com/azure/cosmos-db/request-units"/> for details on provision throughput.
        /// </remarks>
        public virtual async Task <DatabaseResponse> CreateDatabaseIfNotExistsAsync(
            string id,
            int?requestUnitsPerSecond           = null,
            RequestOptions requestOptions       = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            // Doing a Read before Create will give us better latency for existing databases
            CosmosDatabase   database = this.GetDatabase(id);
            DatabaseResponse cosmosDatabaseResponse = await database.ReadAsync(cancellationToken : cancellationToken);

            if (cosmosDatabaseResponse.StatusCode != HttpStatusCode.NotFound)
            {
                return(cosmosDatabaseResponse);
            }

            cosmosDatabaseResponse = await this.CreateDatabaseAsync(id, requestUnitsPerSecond, requestOptions, cancellationToken : cancellationToken);

            if (cosmosDatabaseResponse.StatusCode != HttpStatusCode.Conflict)
            {
                return(cosmosDatabaseResponse);
            }

            // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create
            // so for the remaining ones we should do a Read instead of throwing Conflict exception
            return(await database.ReadAsync(cancellationToken : cancellationToken));
        }
Ejemplo n.º 2
0
        public override async Task <CosmosDatabaseResponse> CreateDatabaseIfNotExistsAsync(
            string id,
            int?throughput = null,
            CosmosRequestOptions requestOptions = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            // Doing a Read before Create will give us better latency for existing databases
            CosmosDatabase         database = this[id];
            CosmosDatabaseResponse cosmosDatabaseResponse = await database.ReadAsync(cancellationToken : cancellationToken);

            if (cosmosDatabaseResponse.StatusCode != HttpStatusCode.NotFound)
            {
                return(cosmosDatabaseResponse);
            }

            cosmosDatabaseResponse = await this.CreateDatabaseAsync(id, throughput, requestOptions, cancellationToken : cancellationToken);

            if (cosmosDatabaseResponse.StatusCode != HttpStatusCode.Conflict)
            {
                return(cosmosDatabaseResponse);
            }

            // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create
            // so for the remaining ones we should do a Read instead of throwing Conflict exception
            return(await database.ReadAsync(cancellationToken : cancellationToken));
        }