/// <summary> /// Create the database. /// </summary> /// <returns> /// A <see cref="Task"/> representing the operation. /// </returns> public override async Task CreateDatabase() { RequireState(); Log.LogInformation("Creating database {DatabaseName} (Id:{DatabaseId}) on server {ServerId}...", State.Name, State.Id, State.ServerId ); CommandResult commandResult = await DatabaseProxyClient.ExecuteCommand( serverId : State.ServerId, databaseId : DatabaseProxyApiClient.MasterDatabaseId, sql : ManagementSql.CreateDatabase( State.Name, State.DatabaseUser, State.DatabasePassword, maxPrimaryFileSizeMB: State.Storage.SizeMB, maxLogFileSizeMB: (int)(0.2 * State.Storage.SizeMB) // Reserve an additional 20% of storage for transaction logs. ), executeAsAdminUser : true, stopOnError : true ); for (int messageIndex = 0; messageIndex < commandResult.Messages.Count; messageIndex++) { Log.LogInformation("T-SQL message [{MessageIndex}] from server {ServerId}: {TSqlMessage}", messageIndex, State.ServerId, commandResult.Messages[messageIndex] ); } if (!commandResult.Success) { foreach (SqlError error in commandResult.Errors) { Log.LogWarning("Error encountered while creating database {DatabaseId} ({DatabaseName}) on server {ServerId} ({ErrorKind}: {ErrorMessage})", State.Id, State.Name, State.ServerId, error.Kind, error.Message ); } throw new SqlExecutionException($"Failed to create database '{State.Name}' (Id:{State.Id}) on server {State.ServerId}.", serverId: State.ServerId, databaseId: State.Id, sqlMessages: commandResult.Messages, sqlErrors: commandResult.Errors ); } Log.LogInformation("Created database {DatabaseName} (Id:{DatabaseId}) on server {ServerId}.", State.Name, State.Id, State.ServerId ); }
/// <summary> /// Drop the database. /// </summary> public override async Task DropDatabase() { RequireState(); Log.LogInformation("Dropping database {DatabaseName} (Id:{DatabaseId}) on server {ServerId}...", State.Name, State.Id, State.ServerId ); CommandResult commandResult = await DatabaseProxyClient.ExecuteCommand( serverId : State.ServerId, databaseId : DatabaseProxyApiClient.MasterDatabaseId, sql : ManagementSql.DropDatabase(State.Name), executeAsAdminUser : true, stopOnError : true ); for (int messageIndex = 0; messageIndex < commandResult.Messages.Count; messageIndex++) { Log.LogInformation("T-SQL message [{MessageIndex}] from server {ServerId}: {TSqlMessage}", messageIndex, State.ServerId, commandResult.Messages[messageIndex] ); } if (!commandResult.Success) { foreach (SqlError error in commandResult.Errors) { Log.LogWarning("Error encountered while dropping database {DatabaseId} ({DatabaseName}) on server {ServerId} ({ErrorKind}: {ErrorMessage})", State.Id, State.Name, State.ServerId, error.Kind, error.Message ); } throw new SqlExecutionException($"Failed to drop database '{State.Name}' (Id:{State.Id}) on server {State.ServerId}.", serverId: State.ServerId, databaseId: State.Id, sqlMessages: commandResult.Messages, sqlErrors: commandResult.Errors ); } Log.LogInformation("Dropped database {DatabaseName} (Id:{DatabaseId}) on server {ServerId}.", State.Name, State.Id, State.ServerId ); }
/// <summary> /// Check if the target database exists. /// </summary> /// <returns> /// <c>true</c>, if the database exists; otherwise, <c>false</c>. /// </returns> public override async Task <bool> DoesDatabaseExist() { RequireState(); QueryResult result = await DatabaseProxyClient.ExecuteQuery( serverId : State.ServerId, databaseId : DatabaseProxyApiClient.MasterDatabaseId, sql : ManagementSql.CheckDatabaseExists(), parameters : ManagementSql.Parameters.CheckDatabaseExists( databaseName: State.Name ), executeAsAdminUser : true, stopOnError : true ); return(result.ResultSets[0].Rows.Count == 1); }
/// <summary> /// Initialise the server's configuration. /// </summary> /// <returns> /// A <see cref="Task"/> representing the operation. /// </returns> public async Task InitialiseServerConfiguration() { RequireCurrentState(); Log.LogInformation("Initialising configuration for server {ServerId}...", State.Id); switch (State.Kind) { case DatabaseServerKind.SqlServer: { CommandResult commandResult = await DatabaseProxyClient.ExecuteCommand( serverId : State.Id, databaseId : DatabaseProxyApiClient.MasterDatabaseId, sql : ManagementSql.ConfigureServerMemory(maxMemoryMB: 500 * 1024), executeAsAdminUser : true ); for (int messageIndex = 0; messageIndex < commandResult.Messages.Count; messageIndex++) { Log.LogInformation("T-SQL message [{MessageIndex}] from server {ServerId}: {TSqlMessage}", messageIndex, State.Id, commandResult.Messages[messageIndex] ); } if (!commandResult.Success) { foreach (SqlError error in commandResult.Errors) { Log.LogWarning("Error encountered while initialising configuration for server {ServerId} ({ErrorKind}: {ErrorMessage})", State.Id, error.Kind, error.Message ); } throw new SqlExecutionException($"One or more errors were encountered while configuring server (Id: {State.Id}).", serverId: State.Id, databaseId: DatabaseProxyApiClient.MasterDatabaseId, sqlMessages: commandResult.Messages, sqlErrors: commandResult.Errors ); } break; } case DatabaseServerKind.RavenDB: { if (State.Action == ProvisioningAction.Provision) // For now, we don't attempt this during a Reconfigure (not sure if RavenDB allows running it more than once). { await DatabaseProxyClient.InitializeRavenServerConfiguration(State.Id); } break; } default: { Log.LogInformation("Skipping initialisation of configuration for server {ServerId} (initialisation not supported for servers of kind {ServerKind}).", State.Id, State.Kind); return; } } Log.LogInformation("Configuration initialised for server {ServerId}.", State.Id); }