mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
Enabling Database scoped configurations tab to DB Properties (#2147)
* sending dsc values to ADS * modifying dsc method with unsupportable property IsValuedefault * getting the options and added a bool flag to maintian checkbox for secondary to save * sending data to ads * Ready for PR with minimal changes of loading UI as expected, TODO:saving logic * Excluding maxdop and resumable options from primary value conversion for 1/0's * Adding Id to the info, as we cannot depend on names, as names can be altered in future * saving successfully, todo-diff servers, script (secondary - primary compare and dont update),test, send null for unsupported * adding nullable dsc for unsupported servers * fixing script generation for some properties that are not touched. the generated script is unharmed but unnecessary here * adding test conditions for database scoped configurations * adding switch case method to get the values * Removing Loc string for the TSQL options * removing unnecessary using statement * Adding test case and fixing createDatabase issue * Update src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype130.cs Co-authored-by: Charles Gagnon <chgagnon@microsoft.com> * comment update --------- Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
7c0da6b6b1
commit
e4db70fb39
@@ -46,6 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
public DateTime lastLogBackupDate;
|
||||
public DatabaseUserAccess restrictAccess;
|
||||
public DatabaseStatus databaseState;
|
||||
public DatabaseScopedConfigurationCollection databaseScopedConfigurations;
|
||||
public DefaultCursor defaultCursor;
|
||||
public CompatibilityLevel databaseCompatibilityLevel;
|
||||
public ContainmentType databaseContainmentType;
|
||||
@@ -556,6 +557,11 @@ WHERE do.database_id = @DbID
|
||||
this.isLedger = db.IsLedger;
|
||||
}
|
||||
|
||||
if (db.IsSupportedObject<DatabaseScopedConfiguration>())
|
||||
{
|
||||
this.databaseScopedConfigurations = db.DatabaseScopedConfigurations;
|
||||
}
|
||||
|
||||
//Only fill in the Azure properties when connected to an Azure server
|
||||
if (context.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
|
||||
{
|
||||
@@ -689,6 +695,7 @@ WHERE do.database_id = @DbID
|
||||
this.maxSize = other.maxSize == null ? null : new DbSize(other.maxSize);
|
||||
this.backupStorageRedundancy = other.backupStorageRedundancy;
|
||||
this.isLedger = other.isLedger;
|
||||
this.databaseScopedConfigurations = other.databaseScopedConfigurations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -773,7 +780,8 @@ WHERE do.database_id = @DbID
|
||||
(this.queryStoreEnabled == other.queryStoreEnabled) &&
|
||||
(this.maxSize == other.maxSize) &&
|
||||
(this.backupStorageRedundancy == other.backupStorageRedundancy) &&
|
||||
(this.isLedger == other.isLedger);
|
||||
(this.isLedger == other.isLedger) &&
|
||||
(this.databaseScopedConfigurations == other.databaseScopedConfigurations);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -199,51 +199,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
db.EncryptionEnabled = this.currentState.encryptionEnabled;
|
||||
}
|
||||
|
||||
// Check if we support database scoped configurations in this database. Since these were all added at the same time,
|
||||
// only check if MaxDop is supported rather than each individual property.
|
||||
if (db.IsSupportedProperty("MaxDop"))
|
||||
{
|
||||
if (!this.Exists || (db.MaxDop != this.MaxDop))
|
||||
{
|
||||
db.MaxDop = this.MaxDop;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.MaxDopForSecondary != this.MaxDopForSecondary))
|
||||
{
|
||||
db.MaxDopForSecondary = this.MaxDopForSecondary;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.LegacyCardinalityEstimation != this.currentState.legacyCardinalityEstimation))
|
||||
{
|
||||
db.LegacyCardinalityEstimation = this.currentState.legacyCardinalityEstimation;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.LegacyCardinalityEstimationForSecondary != this.currentState.legacyCardinalityEstimationForSecondary))
|
||||
{
|
||||
db.LegacyCardinalityEstimationForSecondary = this.currentState.legacyCardinalityEstimationForSecondary;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.ParameterSniffing != this.currentState.parameterSniffing))
|
||||
{
|
||||
db.ParameterSniffing = this.currentState.parameterSniffing;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.ParameterSniffingForSecondary != this.currentState.parameterSniffingForSecondary))
|
||||
{
|
||||
db.ParameterSniffingForSecondary = this.currentState.parameterSniffingForSecondary;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.QueryOptimizerHotfixes != this.currentState.queryOptimizerHotfixes))
|
||||
{
|
||||
db.QueryOptimizerHotfixes = this.currentState.queryOptimizerHotfixes;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.QueryOptimizerHotfixesForSecondary != this.currentState.queryOptimizerHotfixesForSecondary))
|
||||
{
|
||||
db.QueryOptimizerHotfixesForSecondary = this.currentState.queryOptimizerHotfixesForSecondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2016
|
||||
/// </summary>
|
||||
internal class DatabasePrototype130 : DatabasePrototype110
|
||||
{
|
||||
// Properties that doen't support secondary value updates
|
||||
// More info here: https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql?view=sql-server-ver16
|
||||
// The secondaryValUnsupportedPropsSet containst the configuration Ids of the below properties
|
||||
// IDENTITY_CACHE(6)
|
||||
// ELEVATE_ONLINE(11)
|
||||
// ELEVATE_RESUMABLE(12)
|
||||
// GLOBAL_TEMPORARY_TABLE_AUTO_DROP(21)
|
||||
// PAUSED_RESUMABLE_INDEX_ABORT_DURATION_MINUTES(25)
|
||||
private static readonly HashSet<int> secondaryValUnsupportedPropsSet = new HashSet<int> { 6, 11, 12, 21, 25 };
|
||||
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2016 class constructor
|
||||
/// </summary>
|
||||
public DatabasePrototype130(CDataContainer context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations")]
|
||||
public DatabaseScopedConfigurationCollection DatabaseScopedConfiguration
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.databaseScopedConfigurations;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.databaseScopedConfigurations = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
|
||||
for (int i = 0; i < db.DatabaseScopedConfigurations.Count; i++)
|
||||
{
|
||||
if (db.DatabaseScopedConfigurations[i].Value != this.currentState.databaseScopedConfigurations[i].Value)
|
||||
{
|
||||
db.DatabaseScopedConfigurations[i].Value = this.currentState.databaseScopedConfigurations[i].Value;
|
||||
}
|
||||
|
||||
// Configurations that are not allowed secondary replicas are excluded.
|
||||
if (db.DatabaseScopedConfigurations[i].ValueForSecondary != this.currentState.databaseScopedConfigurations[i].ValueForSecondary
|
||||
&& !secondaryValUnsupportedPropsSet.Contains(db.DatabaseScopedConfigurations[i].Id))
|
||||
{
|
||||
db.DatabaseScopedConfigurations[i].ValueForSecondary = this.currentState.databaseScopedConfigurations[i].ValueForSecondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2017
|
||||
/// </summary>
|
||||
internal class DatabasePrototype140 : DatabasePrototype110
|
||||
internal class DatabasePrototype140 : DatabasePrototype130
|
||||
{
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2017 class constructor
|
||||
@@ -71,6 +71,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
this.prototype = new DatabasePrototype160(context);
|
||||
}
|
||||
else if (majorVersionNumber >= 14)
|
||||
{
|
||||
this.prototype = new DatabasePrototype140(context);
|
||||
}
|
||||
else if (majorVersionNumber == 13)
|
||||
{
|
||||
this.prototype = new DatabasePrototype130(context);
|
||||
}
|
||||
else if (Utils.IsSql11OrLater(context.Server.Version.Major))
|
||||
{
|
||||
this.prototype = new DatabasePrototype110(context);
|
||||
|
||||
@@ -12301,14 +12301,6 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
}
|
||||
}
|
||||
|
||||
public static string prototype_db_prop_databasescopedconfig_value_primary
|
||||
{
|
||||
get
|
||||
{
|
||||
return Keys.GetString(Keys.prototype_db_prop_databasescopedconfig_value_primary);
|
||||
}
|
||||
}
|
||||
|
||||
public static string error_db_prop_invalidleadingColumns
|
||||
{
|
||||
get
|
||||
@@ -17828,9 +17820,6 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
public const string prototype_db_prop_databasescopedconfig_value_on = "prototype_db_prop_databasescopedconfig_value_on";
|
||||
|
||||
|
||||
public const string prototype_db_prop_databasescopedconfig_value_primary = "prototype_db_prop_databasescopedconfig_value_primary";
|
||||
|
||||
|
||||
public const string error_db_prop_invalidleadingColumns = "error_db_prop_invalidleadingColumns";
|
||||
|
||||
|
||||
|
||||
@@ -6702,10 +6702,6 @@ The Query Processor estimates that implementing the following index could improv
|
||||
<value>ON</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_primary" xml:space="preserve">
|
||||
<value>PRIMARY</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="error_db_prop_invalidleadingColumns" xml:space="preserve">
|
||||
<value>For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</value>
|
||||
<comment></comment>
|
||||
|
||||
@@ -2786,7 +2786,6 @@ prototype_db_prop_varDecimalEnabled = VarDecimal Storage Format Enabled
|
||||
prototype_db_prop_encryptionEnabled = Encryption Enabled
|
||||
prototype_db_prop_databasescopedconfig_value_off = OFF
|
||||
prototype_db_prop_databasescopedconfig_value_on = ON
|
||||
prototype_db_prop_databasescopedconfig_value_primary = PRIMARY
|
||||
error_db_prop_invalidleadingColumns = For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns
|
||||
compatibilityLevel_sphinx = SQL Server 7.0 (70)
|
||||
compatibilityLevel_shiloh = SQL Server 2000 (80)
|
||||
|
||||
@@ -8216,11 +8216,6 @@ The Query Processor estimates that implementing the following index could improv
|
||||
<target state="new">ON</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="prototype_db_prop_databasescopedconfig_value_primary">
|
||||
<source>PRIMARY</source>
|
||||
<target state="new">PRIMARY</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="error_db_prop_invalidleadingColumns">
|
||||
<source>For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</source>
|
||||
<target state="new">For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</target>
|
||||
|
||||
@@ -23,7 +23,7 @@ using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Database object type handler
|
||||
/// </summary>
|
||||
public class DatabaseHandler : ObjectTypeHandler<DatabaseInfo, DatabaseViewContext>
|
||||
@@ -44,8 +44,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
|
||||
internal static readonly string[] AzureEditionNames;
|
||||
internal static readonly string[] AzureBackupLevels;
|
||||
internal static readonly string[] DscOnOffOptions;
|
||||
internal static readonly string[] DscElevateOptions;
|
||||
internal static readonly string[] DscEnableDisableOptions;
|
||||
internal static readonly AzureEditionDetails[] AzureMaxSizes;
|
||||
internal static readonly AzureEditionDetails[] AzureServiceLevels;
|
||||
internal DatabaseScopedConfigurationCollection? databaseScopedConfigurationsCollection = null;
|
||||
|
||||
static DatabaseHandler()
|
||||
{
|
||||
@@ -75,6 +79,22 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
displayRestrictAccessOptions.Add(DatabaseUserAccess.Single, SR.prototype_db_prop_restrictAccess_value_single);
|
||||
displayRestrictAccessOptions.Add(DatabaseUserAccess.Restricted, SR.prototype_db_prop_restrictAccess_value_restricted);
|
||||
|
||||
DscOnOffOptions = new[]{
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_On,
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_Off
|
||||
};
|
||||
|
||||
DscElevateOptions = new[]{
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_Off,
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_When_supported,
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_Fail_Unsupported
|
||||
};
|
||||
|
||||
DscEnableDisableOptions = new[]{
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_Enabled,
|
||||
CommonConstants.DatabaseScopedConfigurations_Value_Disabled
|
||||
};
|
||||
|
||||
// Set up maps from displayName to enum type so we can retrieve the equivalent enum types later when getting a Save/Script request.
|
||||
// We can't use a simple Enum.Parse for that since the displayNames get localized.
|
||||
foreach (CompatibilityLevel key in displayCompatLevels.Keys)
|
||||
@@ -160,7 +180,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
AutoShrink = smoDatabase.AutoShrink,
|
||||
AutoUpdateStatistics = smoDatabase.AutoUpdateStatisticsEnabled,
|
||||
AutoUpdateStatisticsAsynchronously = smoDatabase.AutoUpdateStatisticsAsync,
|
||||
EncryptionEnabled = smoDatabase.EncryptionEnabled
|
||||
EncryptionEnabled = smoDatabase.EncryptionEnabled,
|
||||
DatabaseScopedConfigurations = smoDatabase.IsSupportedObject<DatabaseScopedConfiguration>() ? GetDSCMetaData(smoDatabase.DatabaseScopedConfigurations) : null
|
||||
};
|
||||
|
||||
if (!isAzureDB)
|
||||
@@ -187,7 +208,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
((DatabaseInfo)databaseViewInfo.ObjectInfo).IsLedgerDatabase = smoDatabase.IsLedger;
|
||||
}
|
||||
}
|
||||
databaseScopedConfigurationsCollection = smoDatabase.IsSupportedObject<DatabaseScopedConfiguration>() ? smoDatabase.DatabaseScopedConfigurations : null;
|
||||
}
|
||||
databaseViewInfo.DscOnOffOptions = DscOnOffOptions;
|
||||
databaseViewInfo.DscElevateOptions = DscElevateOptions;
|
||||
databaseViewInfo.DscEnableDisableOptions = DscEnableDisableOptions;
|
||||
}
|
||||
|
||||
// azure sql db doesn't have a sysadmin fixed role
|
||||
@@ -569,6 +594,36 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
db110.DatabaseContainmentType = containmentTypeEnums[database.ContainmentType];
|
||||
}
|
||||
}
|
||||
if (prototype is DatabasePrototype130 db130)
|
||||
{
|
||||
if (!viewParams.IsNewObject && databaseScopedConfigurationsCollection != null && database.DatabaseScopedConfigurations != null)
|
||||
{
|
||||
foreach (DatabaseScopedConfigurationsInfo dsc in database.DatabaseScopedConfigurations)
|
||||
{
|
||||
foreach (DatabaseScopedConfiguration smoDscCollection in databaseScopedConfigurationsCollection)
|
||||
{
|
||||
if (smoDscCollection.Name == dsc.Name)
|
||||
{
|
||||
smoDscCollection.Value = dsc.ValueForPrimary == CommonConstants.DatabaseScopedConfigurations_Value_Enabled
|
||||
? "1" : dsc.ValueForPrimary == CommonConstants.DatabaseScopedConfigurations_Value_Disabled
|
||||
? "0" : dsc.ValueForPrimary;
|
||||
|
||||
// When sending the DSC seconday value to ADS, we convert the secondaryValue of 'PRIMARY' to match with primaryValue
|
||||
// We need to set it back to 'PRIMARY' so that SMO would not generate any unnecessary scripts for unchanged properties
|
||||
if (!(smoDscCollection.ValueForSecondary == CommonConstants.DatabaseScopedConfigurations_Value_Primary &&
|
||||
dsc.ValueForPrimary.Equals(dsc.ValueForSecondary)))
|
||||
{
|
||||
smoDscCollection.ValueForSecondary = dsc.ValueForSecondary == CommonConstants.DatabaseScopedConfigurations_Value_Enabled
|
||||
? "1" : dsc.ValueForSecondary == CommonConstants.DatabaseScopedConfigurations_Value_Disabled
|
||||
? "0" : dsc.ValueForSecondary;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
db130.DatabaseScopedConfiguration = databaseScopedConfigurationsCollection;
|
||||
}
|
||||
}
|
||||
|
||||
// AutoCreateStatisticsIncremental can only be set when AutoCreateStatistics is enabled
|
||||
prototype.AutoCreateStatisticsIncremental = database.AutoCreateIncrementalStatistics;
|
||||
@@ -985,5 +1040,51 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
}
|
||||
return sizes.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares database scoped configurations list
|
||||
/// </summary>
|
||||
/// <param name="smoDSCMetaData"></param>
|
||||
/// <returns>database scoped configurations metadata array</returns>
|
||||
private static DatabaseScopedConfigurationsInfo[] GetDSCMetaData(DatabaseScopedConfigurationCollection smoDSCMetaData)
|
||||
{
|
||||
var dscMetaData = new List<DatabaseScopedConfigurationsInfo>();
|
||||
foreach (DatabaseScopedConfiguration dsc in smoDSCMetaData)
|
||||
{
|
||||
string primaryValue = GetDscValue(dsc.Id, dsc.Value);
|
||||
dscMetaData.Add(new DatabaseScopedConfigurationsInfo()
|
||||
{
|
||||
Id = dsc.Id,
|
||||
Name = dsc.Name,
|
||||
ValueForPrimary = primaryValue,
|
||||
ValueForSecondary = dsc.ValueForSecondary == CommonConstants.DatabaseScopedConfigurations_Value_Primary ? primaryValue : GetDscValue(dsc.Id, dsc.ValueForSecondary)
|
||||
});
|
||||
}
|
||||
return dscMetaData.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets primary and secondary value of the database scoped configuration property
|
||||
/// </summary>
|
||||
/// <param name="dsc"></param>
|
||||
/// <returns>Value of the primary/secondary</returns>
|
||||
private static string GetDscValue(int id, string value)
|
||||
{
|
||||
// MAXDOP(Id = 1) and PAUSED_RESUMABLE_INDEX_ABORT_DURATION_MINUTES(Id = 25) are integer numbers but coming as string value type and they need to send as is.
|
||||
if (id == 1 || id == 25)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case "1":
|
||||
return CommonConstants.DatabaseScopedConfigurations_Value_Enabled;
|
||||
case "0":
|
||||
return CommonConstants.DatabaseScopedConfigurations_Value_Disabled;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,5 +39,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
public bool? DatabaseReadOnly { get; set; }
|
||||
public bool EncryptionEnabled { get; set; }
|
||||
public string? RestrictAccess { get; set; }
|
||||
public DatabaseScopedConfigurationsInfo[]? DatabaseScopedConfigurations { get; set; }
|
||||
}
|
||||
|
||||
public class DatabaseScopedConfigurationsInfo
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ValueForPrimary { get; set; }
|
||||
public string ValueForSecondary { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
|
||||
public AzureEditionDetails[] AzureMaxSizes { get; set; }
|
||||
public string[] PageVerifyOptions { get; set; }
|
||||
public string[] RestrictAccessOptions { get; set; }
|
||||
public string[] DscOnOffOptions { get; set; }
|
||||
public string[] DscElevateOptions { get; set; }
|
||||
public string[] DscEnableDisableOptions { get; set; }
|
||||
}
|
||||
|
||||
public class AzureEditionDetails
|
||||
|
||||
@@ -19,5 +19,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
public const string TempDbDatabaseName = "tempdb";
|
||||
|
||||
public const string DefaultBatchSeperator = "GO";
|
||||
|
||||
// Database scoped configurations property values
|
||||
public const string DatabaseScopedConfigurations_Value_On = "ON";
|
||||
public const string DatabaseScopedConfigurations_Value_Off = "OFF";
|
||||
public const string DatabaseScopedConfigurations_Value_Primary = "PRIMARY";
|
||||
public const string DatabaseScopedConfigurations_Value_When_supported = "WHEN_SUPPORTED";
|
||||
public const string DatabaseScopedConfigurations_Value_Fail_Unsupported = "FAIL_UNSUPPORTED";
|
||||
public const string DatabaseScopedConfigurations_Value_Enabled = "ENABLED";
|
||||
public const string DatabaseScopedConfigurations_Value_Disabled = "DISABLED";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +300,67 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).AutoUpdateStatisticsAsynchronously, Is.False, $"AutoUpdateStatisticsAsynchronously should match with testdata");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).PageVerify, Is.EqualTo(testDatabase.PageVerify), $"PageVerify should match with testdata");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).RestrictAccess, Is.EqualTo(testDatabase.RestrictAccess), $"RestrictAccess should match with testdata");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations, Is.Not.Null, $"DatabaseScopedConfigurations is not null");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations.Count, Is.GreaterThan(0), $"DatabaseScopedConfigurations should have at least a+ few properties");
|
||||
|
||||
// cleanup
|
||||
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn, throwIfNotExist: true);
|
||||
Assert.That(DatabaseExists(testDatabase.Name!, server), Is.False, $"Database '{testDatabase.Name}' was not dropped succesfully");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Cleanup using SMO if Drop didn't work
|
||||
DropDatabase(server, testDatabase.Name!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updating and validating database scoped configurations property values
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Test]
|
||||
public async Task VerifyDatabaseScopedConfigurationsTest()
|
||||
{
|
||||
// setup, drop database if exists.
|
||||
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", serverType: TestServerType.OnPrem);
|
||||
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo))
|
||||
{
|
||||
var server = new Server(new ServerConnection(sqlConn));
|
||||
|
||||
var testDatabase = ObjectManagementTestUtils.GetTestDatabaseInfo();
|
||||
var objUrn = ObjectManagementTestUtils.GetDatabaseURN(testDatabase.Name);
|
||||
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn);
|
||||
|
||||
try
|
||||
{
|
||||
// create database
|
||||
var parametersForCreation = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", true, SqlObjectType.Database, "", "");
|
||||
await ObjectManagementTestUtils.SaveObject(parametersForCreation, testDatabase);
|
||||
Assert.That(DatabaseExists(testDatabase.Name!, server), $"Expected database '{testDatabase.Name}' was not created succesfully");
|
||||
|
||||
// Get database properties and verify
|
||||
var parametersForUpdate = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, testDatabase.Name, false, SqlObjectType.Database, "", objUrn);
|
||||
DatabaseViewInfo databaseViewInfo = await ObjectManagementTestUtils.GetDatabaseObject(parametersForUpdate, testDatabase);
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations, Is.Not.Null, $"DatabaseScopedConfigurations is not null");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations.Count, Is.GreaterThan(0), $"DatabaseScopedConfigurations should have at least a+ few properties");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations[0].ValueForPrimary, Is.EqualTo("ON"), $"DatabaseScopedConfigurations primary value should match");
|
||||
Assert.That(((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations[0].ValueForSecondary, Is.EqualTo("ON"), $"DatabaseScopedConfigurations secondary value should match");
|
||||
|
||||
// Update few database scoped configurations
|
||||
testDatabase.DatabaseScopedConfigurations = ((DatabaseInfo)databaseViewInfo.ObjectInfo).DatabaseScopedConfigurations;
|
||||
if (testDatabase.DatabaseScopedConfigurations.Length > 0)
|
||||
{
|
||||
// ACCELERATED_PLAN_FORCING
|
||||
testDatabase.DatabaseScopedConfigurations[0].ValueForPrimary = "OFF";
|
||||
testDatabase.DatabaseScopedConfigurations[0].ValueForSecondary = "OFF";
|
||||
}
|
||||
await ObjectManagementTestUtils.SaveObject(parametersForUpdate, testDatabase);
|
||||
DatabaseViewInfo updatedDatabaseViewInfo = await ObjectManagementTestUtils.GetDatabaseObject(parametersForUpdate, testDatabase);
|
||||
|
||||
// verify the modified properties
|
||||
Assert.That(((DatabaseInfo)updatedDatabaseViewInfo.ObjectInfo).DatabaseScopedConfigurations[0].ValueForPrimary, Is.EqualTo(testDatabase.DatabaseScopedConfigurations[0].ValueForPrimary), $"DSC updated primary value should match");
|
||||
Assert.That(((DatabaseInfo)updatedDatabaseViewInfo.ObjectInfo).DatabaseScopedConfigurations[0].ValueForSecondary, Is.EqualTo(testDatabase.DatabaseScopedConfigurations[0].ValueForSecondary), $"DSC updated Secondary value should match");
|
||||
|
||||
// cleanup
|
||||
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn, throwIfNotExist: true);
|
||||
|
||||
@@ -79,7 +79,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
|
||||
AutoCreateStatistics = true,
|
||||
AutoShrink = false,
|
||||
AutoUpdateStatistics = true,
|
||||
AutoUpdateStatisticsAsynchronously = false
|
||||
AutoUpdateStatisticsAsynchronously = false,
|
||||
DatabaseScopedConfigurations = null
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user