/// <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));
        }
        /// <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="throughput">(Optional) The throughput provisioned for a collection in measurement of Requests-per-Unit 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="CosmosDatabaseResponse"/> which wraps a <see cref="CosmosDatabaseSettings"/> containing the resource record.</returns>
        public virtual 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));
        }
        internal static Task <T> ProcessCollectionCreateAsync <T>(
            CosmosContainerSettings containerSettings,
            CosmosDatabase database,
            int?throughput,
            Func <CosmosResponseMessage, T> responseCreator,
            CosmosRequestOptions requestOptions = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (containerSettings == null)
            {
                throw new ArgumentNullException(nameof(containerSettings));
            }

            containerSettings.ValidateRequiredProperties();
            database.Client.DocumentClient.ValidateResource(containerSettings);
            return(ExecUtils.ProcessResourceOperationAsync <T>(
                       database.Client,
                       database.LinkUri,
                       ResourceType.Collection,
                       OperationType.Create,
                       requestOptions,
                       partitionKey: null,
                       streamPayload: containerSettings.GetResourceStream(),
                       requestEnricher: (httpRequestMessage) => httpRequestMessage.AddThroughputHeader(throughput),
                       responseCreator: responseCreator,
                       cancellationToken: cancellationToken));
        }
 internal CosmosDatabaseResponse CreateDatabaseResponse(
     CosmosResponseMessage cosmosResponseMessage,
     CosmosDatabase database)
 {
     return(CosmosDatabaseResponse.CreateResponse(
                cosmosResponseMessage,
                this.jsonSerializer,
                database));
 }
 /// <summary>
 /// Create the cosmos database response.
 /// Creates the response object, deserializes the
 /// http content stream, and disposes of the HttpResponseMessage
 /// </summary>
 /// <param name="cosmosResponseMessage"><see cref="CosmosResponseMessage"/> from the Cosmos DB service</param>
 /// <param name="jsonSerializer">The cosmos json serializer</param>
 /// <param name="database">The cosmos database</param>
 internal static CosmosDatabaseResponse CreateResponse(
     CosmosResponseMessage cosmosResponseMessage,
     CosmosJsonSerializer jsonSerializer,
     CosmosDatabase database)
 {
     return(CosmosResponse <CosmosDatabaseSettings>
            .InitResponse <CosmosDatabaseResponse, CosmosDatabaseSettings>(
                (httpResponse) => new CosmosDatabaseResponse(cosmosResponseMessage, database),
                jsonSerializer,
                cosmosResponseMessage));
 }
Beispiel #6
0
 /// <summary>
 /// A private constructor to ensure the factory is used to create the object.
 /// This will prevent memory leaks when handling the HttpResponseMessage
 /// </summary>
 internal CosmosDatabaseResponse(
     HttpStatusCode httpStatusCode,
     CosmosResponseMessageHeaders headers,
     CosmosDatabaseSettings cosmosDatabaseSettings,
     CosmosDatabase database) : base(
         httpStatusCode,
         headers,
         cosmosDatabaseSettings)
 {
     this.Database = database;
 }
 internal Task <DatabaseResponse> CreateDatabaseResponseAsync(
     CosmosDatabase database,
     Task <CosmosResponseMessage> cosmosResponseMessageTask)
 {
     return(this.ProcessMessageAsync(cosmosResponseMessageTask, (cosmosResponseMessage) =>
     {
         CosmosDatabaseProperties settings = this.ToObjectInternal <CosmosDatabaseProperties>(cosmosResponseMessage, this.settingsSerializer);
         return new DatabaseResponse(
             cosmosResponseMessage.StatusCode,
             cosmosResponseMessage.Headers,
             settings,
             database);
     }));
 }
 /// <summary>
 /// Create a <see cref="CosmosContainer"/>
 /// </summary>
 /// <param name="database">The <see cref="CosmosDatabase"/></param>
 /// <param name="containerId">The cosmos container id.</param>
 /// <remarks>
 /// Note that the container must be explicitly created, if it does not already exist, before
 /// you can read from it or write to it.
 /// </remarks>
 protected internal CosmosContainer(
     CosmosDatabase database,
     string containerId) :
     base(database.Client,
          database.Link,
          containerId)
 {
     this.Database             = database;
     this.Items                = new CosmosItems(this);
     this.StoredProcedures     = new CosmosStoredProcedures(this);
     this.DocumentClient       = this.Database.Client.DocumentClient;
     this.Triggers             = new CosmosTriggers(this);
     this.UserDefinedFunctions = new CosmosUserDefinedFunctions(this);
 }
 internal Task <CosmosDatabaseResponse> CreateDatabaseResponse(
     CosmosDatabase database,
     Task <CosmosResponseMessage> cosmosResponseMessageTask)
 {
     return(this.MessageHelper(cosmosResponseMessageTask, (cosmosResponseMessage) =>
     {
         CosmosDatabaseSettings settings = this.ToObjectInternal <CosmosDatabaseSettings>(cosmosResponseMessage);
         return new CosmosDatabaseResponse(
             cosmosResponseMessage.StatusCode,
             cosmosResponseMessage.Headers,
             settings,
             database);
     }));
 }
Beispiel #10
0
        internal CosmosContainerCore(
            CosmosDatabase database,
            string containerId)
        {
            this.Id = containerId;
            base.Initialize(
                client: database.Client,
                parentLink: database.LinkUri.OriginalString,
                uriPathSegment: Paths.CollectionsPathSegment);

            this.Database             = database;
            this.Items                = new CosmosItemsCore(this);
            this.StoredProcedures     = new CosmosStoredProceduresCore(this);
            this.DocumentClient       = this.Client.DocumentClient;
            this.Triggers             = new CosmosTriggers(this);
            this.UserDefinedFunctions = new CosmosUserDefinedFunctions(this);
        }
 internal CosmosContainersCore(CosmosDatabase database)
 {
     this.database       = database;
     this.client         = database.Client;
     this.containerCache = new ConcurrentDictionary <string, CosmosContainer>();
 }
 /// <summary>
 /// A private constructor to ensure the factory is used to create the object.
 /// This will prevent memory leaks when handling the HttpResponseMessage
 /// </summary>
 private CosmosDatabaseResponse(
     CosmosResponseMessage cosmosResponse,
     CosmosDatabase database) : base(cosmosResponse)
 {
     this.Database = database;
 }