mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-23 01:25:42 -05:00
Fix create db resource strings (#348)
* Hook up SMO call into create db handler * Clean-up resource strings * Few additional code clean-ups
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.SqlServer.Diagnostics.STrace;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.Win32;
|
||||
using SizeUnits = Microsoft.SqlTools.ServiceLayer.Admin.DbSize.SizeUnits;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
public static class AzureSqlDbHelper
|
||||
{
|
||||
private static readonly TraceContext TraceContext = TraceContext.GetTraceContext("AzureSqlDbUtils", typeof(AzureSqlDbHelper).Name);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registry sub key for the AzureServiceObjectives overrides
|
||||
/// </summary>
|
||||
private const string AzureServiceObjectivesRegSubKey = @"AzureServiceObjectives";
|
||||
|
||||
/// <summary>
|
||||
/// Contains the various editions available for an Azure Database
|
||||
/// </summary>
|
||||
/// ****IMPORTANT**** - If updating this enum make sure that the other logic in this class is updated as well
|
||||
public enum AzureEdition
|
||||
{
|
||||
Web = 0,
|
||||
Business = 1,
|
||||
Basic = 2,
|
||||
Standard = 3,
|
||||
Premium = 4,
|
||||
DataWarehouse = 5,
|
||||
PremiumRS = 6
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a mapping of Azure DB Editions to their respective size options
|
||||
/// </summary>
|
||||
/// Values below are taken from http://msdn.microsoft.com/en-us/library/dn268335.aspx
|
||||
private static readonly Dictionary<AzureEdition, KeyValuePair<int, DbSize[]>> AzureEditionDatabaseSizeMappings = new Dictionary
|
||||
<AzureEdition, KeyValuePair<int, DbSize[]>>
|
||||
{
|
||||
{
|
||||
AzureEdition.Web, new KeyValuePair<int, DbSize[]>(
|
||||
1, //1GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(100, SizeUnits.MB),
|
||||
new DbSize(1, SizeUnits.GB), //Default
|
||||
new DbSize(5, SizeUnits.GB)
|
||||
})
|
||||
},
|
||||
{
|
||||
AzureEdition.Business, new KeyValuePair<int, DbSize[]>(
|
||||
0, //10GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(10, SizeUnits.GB), //Default
|
||||
new DbSize(20, SizeUnits.GB),
|
||||
new DbSize(30, SizeUnits.GB),
|
||||
new DbSize(40, SizeUnits.GB),
|
||||
new DbSize(50, SizeUnits.GB),
|
||||
new DbSize(100, SizeUnits.GB),
|
||||
new DbSize(150, SizeUnits.GB)
|
||||
})
|
||||
},
|
||||
{
|
||||
AzureEdition.Basic, new KeyValuePair<int, DbSize[]>(
|
||||
3, //2GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(100, SizeUnits.MB),
|
||||
new DbSize(500, SizeUnits.MB),
|
||||
new DbSize(1, SizeUnits.GB),
|
||||
new DbSize(2, SizeUnits.GB) //Default
|
||||
})
|
||||
},
|
||||
{
|
||||
AzureEdition.Standard,
|
||||
new KeyValuePair<int, DbSize[]>(
|
||||
13, //250GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(100, SizeUnits.MB),
|
||||
new DbSize(500, SizeUnits.MB),
|
||||
new DbSize(1, SizeUnits.GB),
|
||||
new DbSize(2, SizeUnits.GB),
|
||||
new DbSize(5, SizeUnits.GB),
|
||||
new DbSize(10, SizeUnits.GB),
|
||||
new DbSize(20, SizeUnits.GB),
|
||||
new DbSize(30, SizeUnits.GB),
|
||||
new DbSize(40, SizeUnits.GB),
|
||||
new DbSize(50, SizeUnits.GB),
|
||||
new DbSize(100, SizeUnits.GB),
|
||||
new DbSize(150, SizeUnits.GB),
|
||||
new DbSize(200, SizeUnits.GB),
|
||||
new DbSize(250, SizeUnits.GB) //Default
|
||||
})
|
||||
},
|
||||
{
|
||||
AzureEdition.Premium,
|
||||
new KeyValuePair<int, DbSize[]>(
|
||||
16, //500GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(100, SizeUnits.MB),
|
||||
new DbSize(500, SizeUnits.MB),
|
||||
new DbSize(1, SizeUnits.GB),
|
||||
new DbSize(2, SizeUnits.GB),
|
||||
new DbSize(5, SizeUnits.GB),
|
||||
new DbSize(10, SizeUnits.GB),
|
||||
new DbSize(20, SizeUnits.GB),
|
||||
new DbSize(30, SizeUnits.GB),
|
||||
new DbSize(40, SizeUnits.GB),
|
||||
new DbSize(50, SizeUnits.GB),
|
||||
new DbSize(100, SizeUnits.GB),
|
||||
new DbSize(150, SizeUnits.GB),
|
||||
new DbSize(200, SizeUnits.GB),
|
||||
new DbSize(250, SizeUnits.GB),
|
||||
new DbSize(300, SizeUnits.GB),
|
||||
new DbSize(400, SizeUnits.GB),
|
||||
new DbSize(500, SizeUnits.GB), //Default
|
||||
new DbSize(1024, SizeUnits.GB) //Following portal to display this as GB instead of 1TB
|
||||
})
|
||||
},
|
||||
|
||||
{
|
||||
AzureEdition.DataWarehouse,
|
||||
new KeyValuePair<int, DbSize[]>(
|
||||
5, //10240GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(250, SizeUnits.GB),
|
||||
new DbSize(500, SizeUnits.GB),
|
||||
new DbSize(750, SizeUnits.GB),
|
||||
new DbSize(1024, SizeUnits.GB),
|
||||
new DbSize(5120, SizeUnits.GB),
|
||||
new DbSize(10240, SizeUnits.GB),
|
||||
new DbSize(20480, SizeUnits.GB),
|
||||
new DbSize(30720, SizeUnits.GB),
|
||||
new DbSize(40960, SizeUnits.GB),
|
||||
new DbSize(51200, SizeUnits.GB)
|
||||
})
|
||||
},
|
||||
{
|
||||
AzureEdition.PremiumRS,
|
||||
new KeyValuePair<int, DbSize[]>(
|
||||
16, //500GB
|
||||
new[]
|
||||
{
|
||||
new DbSize(100, SizeUnits.MB),
|
||||
new DbSize(500, SizeUnits.MB),
|
||||
new DbSize(1, SizeUnits.GB),
|
||||
new DbSize(2, SizeUnits.GB),
|
||||
new DbSize(5, SizeUnits.GB),
|
||||
new DbSize(10, SizeUnits.GB),
|
||||
new DbSize(20, SizeUnits.GB),
|
||||
new DbSize(30, SizeUnits.GB),
|
||||
new DbSize(40, SizeUnits.GB),
|
||||
new DbSize(50, SizeUnits.GB),
|
||||
new DbSize(100, SizeUnits.GB),
|
||||
new DbSize(150, SizeUnits.GB),
|
||||
new DbSize(200, SizeUnits.GB),
|
||||
new DbSize(250, SizeUnits.GB),
|
||||
new DbSize(300, SizeUnits.GB),
|
||||
new DbSize(400, SizeUnits.GB),
|
||||
new DbSize(500, SizeUnits.GB), //Default
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Maps Azure DB Editions to their corresponding Service Objective (Performance Level) options. These values are the default but
|
||||
/// can be overridden by use of the ImportExportWizard registry key (see static initializer above).
|
||||
///
|
||||
/// The key is the index of the default value for the list
|
||||
/// </summary>
|
||||
private static readonly Dictionary<AzureEdition, KeyValuePair<int, string[]>> AzureServiceObjectiveInfo = new Dictionary
|
||||
<AzureEdition, KeyValuePair<int, string[]>>
|
||||
{
|
||||
{AzureEdition.Basic, new KeyValuePair<int, string[]>(0, new[] {"Basic"})},
|
||||
{AzureEdition.Standard, new KeyValuePair<int, string[]>(2, new[] {"S0", "S1", "S2", "S3"})},
|
||||
{AzureEdition.Premium, new KeyValuePair<int, string[]>(0, new[] {"P1", "P2", "P4", "P6", "P11", "P15"})},
|
||||
{AzureEdition.PremiumRS, new KeyValuePair<int, string[]>(0, new []{"PRS1", "PRS2", "PRS4", "PRS6"})},
|
||||
{AzureEdition.DataWarehouse, new KeyValuePair<int, string[]>(3, new[] {"DW100", "DW200", "DW300", "DW400", "DW500", "DW600", "DW1000", "DW1200", "DW1500", "DW2000", "DW3000", "DW6000"})}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Static initializer to read in the registry key values for the Service Objective mappings, which allows the user to override the defaults set for
|
||||
/// the service objective list. We allow them to do this as a temporary measure so that if we change the service objectives in the future we
|
||||
/// can tell people to use the registry key to use the new values until an updated SSMS can be released.
|
||||
/// </summary>
|
||||
static AzureSqlDbHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of databases sizes applicable for the specified Azure DB edition (if such
|
||||
/// a mapping exists) as well as the index of the default size for that edition.
|
||||
///
|
||||
/// Outputs an empty array with an index of -1 if no such mapping exists
|
||||
/// </summary>
|
||||
/// <param name="edition"></param>
|
||||
/// <param name="databaseSizeInfo"></param>
|
||||
/// <returns>TRUE if a mapping exists, FALSE if it does not</returns>
|
||||
public static bool TryGetDatabaseSizeInfo(AzureEdition edition, out KeyValuePair<int, DbSize[]> databaseSizeInfo)
|
||||
{
|
||||
if (AzureEditionDatabaseSizeMappings.TryGetValue(edition, out databaseSizeInfo))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
databaseSizeInfo = new KeyValuePair<int, DbSize[]>(-1, new DbSize[0]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a KeyValuePair containing a list of the ServiceObjective names mapped to a particular Azure DB Edition
|
||||
/// (if such a mapping exists) as well as the index of the default Service Objective for that edition.
|
||||
/// Outputs an empty array with a default index of -1 if no such mapping exists.
|
||||
/// </summary>
|
||||
/// <param name="edition"></param>
|
||||
/// <param name="serviceObjectiveInfo"></param>
|
||||
/// <returns>TRUE if a mapping exists, FALSE if it did not</returns>
|
||||
public static bool TryGetServiceObjectiveInfo(AzureEdition edition,
|
||||
out KeyValuePair<int, string[]> serviceObjectiveInfo)
|
||||
{
|
||||
if (AzureServiceObjectiveInfo.TryGetValue(edition, out serviceObjectiveInfo))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
serviceObjectiveInfo = new KeyValuePair<int, string[]>(-1, new string[0]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default database size for a specified Azure Edition
|
||||
/// </summary>
|
||||
/// <param name="edition"></param>
|
||||
/// <returns>The default size, or NULL if no default exists</returns>
|
||||
public static DbSize GetDatabaseDefaultSize(AzureEdition edition)
|
||||
{
|
||||
DbSize defaultSize = null;
|
||||
|
||||
KeyValuePair<int, DbSize[]> pair;
|
||||
|
||||
if (AzureEditionDatabaseSizeMappings.TryGetValue(edition, out pair))
|
||||
{
|
||||
defaultSize = pair.Value[pair.Key];
|
||||
}
|
||||
|
||||
return defaultSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default Service Objective name for a particular Azure DB edition
|
||||
/// </summary>
|
||||
/// <param name="edition"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetDefaultServiceObjective(AzureEdition edition)
|
||||
{
|
||||
string defaultServiceObjective = "";
|
||||
|
||||
KeyValuePair<int, string[]> pair;
|
||||
|
||||
if (AzureServiceObjectiveInfo.TryGetValue(edition, out pair))
|
||||
{
|
||||
//Bounds check since this value can be entered by users
|
||||
if (pair.Key >= 0 && pair.Key < pair.Value.Length)
|
||||
{
|
||||
defaultServiceObjective = pair.Value[pair.Key];
|
||||
}
|
||||
}
|
||||
|
||||
return defaultServiceObjective;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the localized Azure Edition display name
|
||||
/// </summary>
|
||||
/// <param name="edition"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetAzureEditionDisplayName(AzureEdition edition)
|
||||
{
|
||||
string result;
|
||||
switch (edition)
|
||||
{
|
||||
//case AzureEdition.Business:
|
||||
// result = SR.BusinessAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.Web:
|
||||
// result = SR.WebAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.Basic:
|
||||
// result = SR.BasicAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.Standard:
|
||||
// result = SR.StandardAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.Premium:
|
||||
// result = SR.PremiumAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.DataWarehouse:
|
||||
// result = SR.DataWarehouseAzureEdition;
|
||||
// break;
|
||||
//case AzureEdition.PremiumRS:
|
||||
// result = SR.PremiumRsAzureEdition;
|
||||
// break;
|
||||
default:
|
||||
result = edition.ToString();
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a display name back into its corresponding AzureEdition.
|
||||
/// </summary>
|
||||
/// <param name="displayName"></param>
|
||||
/// <param name="edition"></param>
|
||||
/// <returns>TRUE if the conversion succeeded, FALSE if it did not. </returns>
|
||||
public static bool TryGetAzureEditionFromDisplayName(string displayName, out AzureEdition edition)
|
||||
{
|
||||
//if (string.Compare(displayName, SR.BusinessAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.Business;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.WebAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.Web;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.BasicAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.Basic;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.StandardAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.Standard;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.PremiumAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.Premium;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.DataWarehouseAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.DataWarehouse;
|
||||
//}
|
||||
//else if (string.Compare(displayName, SR.PremiumRsAzureEdition, CultureInfo.CurrentUICulture, CompareOptions.None) == 0)
|
||||
//{
|
||||
// edition = AzureEdition.PremiumRS;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
//"Default" edition is standard - but since we're returning false the user shouldn't look at this anyways
|
||||
edition = AzureEdition.Standard;
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of AzureEditions that are valid values for the EDITION option
|
||||
/// when creating a database.
|
||||
/// </summary>
|
||||
/// We do this so that the AzureEdition enum can have values such as NONE or DEFAULT added
|
||||
/// without requiring clients to explicitly filter out those values themselves each time.
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<AzureEdition> GetValidAzureEditionOptions(ServerVersion version)
|
||||
{
|
||||
//Azure v12 and above doesn't have the Web and Business tiers
|
||||
if (version.Major >= 12)
|
||||
{
|
||||
return new List<AzureEdition>()
|
||||
{
|
||||
AzureEdition.Basic,
|
||||
AzureEdition.Standard,
|
||||
AzureEdition.Premium,
|
||||
AzureEdition.PremiumRS,
|
||||
AzureEdition.DataWarehouse
|
||||
};
|
||||
}
|
||||
|
||||
//Default for now is to return all values since they're currently all valid
|
||||
return Enum.GetValues(typeof(AzureEdition)).Cast<AzureEdition>();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,303 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Resources;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2008
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(DynamicValueTypeConverter))]
|
||||
internal class DatabasePrototype100 : DatabasePrototype90
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether vardecimal compression is enabled on the server
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_VarDecimalEnabled")]
|
||||
public bool VarDecimalEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.varDecimalEnabled;
|
||||
}
|
||||
//there is no set for user database in katmai. By default it's true.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether database is encrypted or not
|
||||
/// </summary>
|
||||
[Category("Category_State"),
|
||||
DisplayNameAttribute("Property_EncryptionEnabled")]
|
||||
public bool EncryptionEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.encryptionEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.encryptionEnabled = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Honor Broker Priority
|
||||
/// </summary>
|
||||
[Category("Category_ServiceBroker"),
|
||||
DisplayNameAttribute("Property_HonorBrokerPriority")]
|
||||
public bool HonorBrokerPriority
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.honorBrokerPriority;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations")]
|
||||
[DisplayNameAttribute("Property_MaxDop")]
|
||||
public int MaxDop
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.maxDop;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.maxDop = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations")]
|
||||
[DisplayNameAttribute("Property_MaxDopForSecondary")]
|
||||
public int? MaxDopForSecondary
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.maxDopForSecondary;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.maxDopForSecondary = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_LegacyCardinalityEstimation")]
|
||||
public string LegacyCardinalityEstimationDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.legacyCardinalityEstimation);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.legacyCardinalityEstimation = SetDatabaseScopedConfigHelper(value, forSecondary: false);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_LegacyCardinalityEstimationForSecondary")]
|
||||
public String LegacyCardinalityEstimationForSecondaryDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.legacyCardinalityEstimationForSecondary);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.legacyCardinalityEstimationForSecondary = SetDatabaseScopedConfigHelper(value, forSecondary: true);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_ParameterSniffing")]
|
||||
public string ParameterSniffingDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.parameterSniffing);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.parameterSniffing = SetDatabaseScopedConfigHelper(value, forSecondary: false);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_ParameterSniffingForSecondary")]
|
||||
public String ParameterSniffingForSecondaryDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.parameterSniffingForSecondary);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.parameterSniffingForSecondary = SetDatabaseScopedConfigHelper(value, forSecondary: true);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_QueryOptimizerHotfixes")]
|
||||
public String QueryOptimizerHotfixesDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.queryOptimizerHotfixes);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.queryOptimizerHotfixes = SetDatabaseScopedConfigHelper(value, forSecondary: false);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_DatabaseScopedConfigurations"),
|
||||
DisplayNameAttribute("Property_QueryOptimizerHotfixesForSecondary")]
|
||||
public String QueryOptimizerHotfixesForSecondaryDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDatabaseScopedConfigDisplayText(this.currentState.queryOptimizerHotfixesForSecondary);
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.queryOptimizerHotfixesForSecondary = SetDatabaseScopedConfigHelper(value, forSecondary: true);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
public DatabasePrototype100(CDataContainer context) : base(context) { }
|
||||
|
||||
/// <summary>
|
||||
/// Commit changes to the database
|
||||
/// </summary>
|
||||
/// <param name="db">The database whose properties we are changing</param>
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
if (!this.Exists || this.originalState.encryptionEnabled != this.currentState.encryptionEnabled)
|
||||
{
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display text for a database scoped configuration setting.
|
||||
/// </summary>
|
||||
/// <param name="onOffValue">The database scoped configuration setting value.</param>
|
||||
/// <returns>A string from the resource manager representing the value.</returns>
|
||||
private string GetDatabaseScopedConfigDisplayText(DatabaseScopedConfigurationOnOff onOffValue)
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
string result = null;
|
||||
|
||||
switch (onOffValue)
|
||||
{
|
||||
case DatabaseScopedConfigurationOnOff.Off:
|
||||
result = manager.GetString("prototype_db_prop_databasescopedconfig_value_off");
|
||||
break;
|
||||
|
||||
case DatabaseScopedConfigurationOnOff.On:
|
||||
result = manager.GetString("prototype_db_prop_databasescopedconfig_value_on");
|
||||
break;
|
||||
|
||||
case DatabaseScopedConfigurationOnOff.Primary:
|
||||
result = manager.GetString("prototype_db_prop_databasescopedconfig_value_primary");
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translates a string to a database scoped configuration enum value for the set method.
|
||||
/// </summary>
|
||||
/// <param name="displayText">The display text.</param>
|
||||
/// <param name="forSecondary">Whether this is for a secondary in which case "PRIMARY" is allowable.</param>
|
||||
/// <returns>The database scoped configuration enum value that matches the display text.</returns>
|
||||
private DatabaseScopedConfigurationOnOff SetDatabaseScopedConfigHelper(string displayText, bool forSecondary)
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
|
||||
if (displayText == manager.GetString("prototype_db_prop_databasescopedconfig_value_off"))
|
||||
{
|
||||
return DatabaseScopedConfigurationOnOff.Off;
|
||||
}
|
||||
else if (displayText == manager.GetString("prototype_db_prop_databasescopedconfig_value_on") || !forSecondary)
|
||||
{
|
||||
return DatabaseScopedConfigurationOnOff.On;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DatabaseScopedConfigurationOnOff.Primary;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database properties for SqlServer 2011
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(DynamicValueTypeConverter))]
|
||||
internal class DatabasePrototype110 : DatabasePrototype100
|
||||
{
|
||||
/// <summary>
|
||||
/// Database compatibility level
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public ContainmentType DatabaseContainmentType
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.databaseContainmentType;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.databaseContainmentType = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_ContainedDatabases"),
|
||||
DisplayNameAttribute("Property_DefaultFullTextLanguageLcid")]
|
||||
public int DefaultFullTextLanguageLcid
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.defaultFulltextLanguageLcid;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.defaultFulltextLanguageLcid = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_ContainedDatabases"),
|
||||
DisplayNameAttribute("Property_NestedTriggersEnabled")]
|
||||
public bool NestedTriggersEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.nestedTriggersEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.nestedTriggersEnabled = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_ContainedDatabases"),
|
||||
DisplayNameAttribute("Property_TransformNoiseWords")]
|
||||
public bool TransformNoiseWords
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.transformNoiseWords;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.transformNoiseWords = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_ContainedDatabases"),
|
||||
DisplayNameAttribute("Property_TwoDigitYearCutoff")]
|
||||
public int TwoDigitYearCutoff
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.twoDigitYearCutoff;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.twoDigitYearCutoff = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_Recovery"),
|
||||
DisplayNameAttribute("Property_TargetRecoveryTime")]
|
||||
public int TargetRecoveryTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.targetRecoveryTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.targetRecoveryTime = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_DelayedDurability")]
|
||||
public DelayedDurability DelayedDurability
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.delayedDurability;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.delayedDurability = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
public DatabasePrototype110(CDataContainer context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commit changes to the database
|
||||
/// </summary>
|
||||
/// <param name="db">The database whose properties we are changing</param>
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
|
||||
if (db.IsSupportedProperty("ContainmentType"))
|
||||
{
|
||||
if (!this.Exists || (db.ContainmentType != this.DatabaseContainmentType))
|
||||
{
|
||||
db.ContainmentType = this.DatabaseContainmentType;
|
||||
}
|
||||
|
||||
if (this.DatabaseContainmentType != ContainmentType.None)
|
||||
{
|
||||
if (!this.Exists || (db.DefaultFullTextLanguage.Lcid != this.DefaultFullTextLanguageLcid))
|
||||
{
|
||||
db.DefaultFullTextLanguage.Lcid = this.DefaultFullTextLanguageLcid;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.NestedTriggersEnabled != this.NestedTriggersEnabled))
|
||||
{
|
||||
db.NestedTriggersEnabled = this.NestedTriggersEnabled;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.TransformNoiseWords != this.TransformNoiseWords))
|
||||
{
|
||||
db.TransformNoiseWords = this.TransformNoiseWords;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.TwoDigitYearCutoff != this.TwoDigitYearCutoff))
|
||||
{
|
||||
db.TwoDigitYearCutoff = this.TwoDigitYearCutoff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (db.IsSupportedProperty("TargetRecoveryTime"))
|
||||
{
|
||||
if (!this.Exists || (db.TargetRecoveryTime != this.TargetRecoveryTime))
|
||||
{
|
||||
db.TargetRecoveryTime = this.TargetRecoveryTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (db.IsSupportedProperty("DelayedDurability"))
|
||||
{
|
||||
if (!this.Exists || (db.DelayedDurability != this.DelayedDurability))
|
||||
{
|
||||
db.DelayedDurability = this.DelayedDurability;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Resources;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Prototype for SqlServer 2000 and later servers
|
||||
/// </summary>
|
||||
internal class DatabasePrototype80 : DatabasePrototype, IDynamicValues
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the database is read-only
|
||||
/// </summary>
|
||||
[
|
||||
Category("Category_State"),
|
||||
DisplayNameAttribute("Property_ReadOnly")
|
||||
]
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.isReadOnly;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.isReadOnly = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether torn page detection is enabled
|
||||
/// </summary>
|
||||
[Category("Category_Recovery"),
|
||||
DisplayNameAttribute("Property_PageVerify"),
|
||||
TypeConverter(typeof(PageVerifyTypes80))]
|
||||
public virtual string PageVerifyDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
string result = null;
|
||||
|
||||
switch (this.currentState.pageVerify)
|
||||
{
|
||||
case PageVerify.Checksum:
|
||||
|
||||
result = manager.GetString("prototype_db_prop_pageVerify_value_checksum");
|
||||
break;
|
||||
|
||||
case PageVerify.None:
|
||||
|
||||
result = manager.GetString("prototype_db_prop_pageVerify_value_none");
|
||||
break;
|
||||
|
||||
case PageVerify.TornPageDetection:
|
||||
|
||||
result = manager.GetString("prototype.db.prop.pageVerify.value.tornPageDetection");
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
if (value == manager.GetString("prototype_db_prop_pageVerify_value_checksum"))
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.Checksum;
|
||||
}
|
||||
else if (value == manager.GetString("prototype_db_prop_pageVerify_value_none"))
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.TornPageDetection;
|
||||
}
|
||||
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ANSI Padding enabled
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_ANSIPadding")]
|
||||
public bool AnsiPadding
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.ansiPadding;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.ansiPadding = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use ANSI warnings
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_ANSIWarnings")]
|
||||
public bool AnsiWarnings
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.ansiWarnings;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.ansiWarnings = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Arithabort
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_ArithAbort")]
|
||||
public bool Arithabort
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.arithabort;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.arithabort = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether contatenating a null string yields a null result
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_ConcatNullYieldsNull")]
|
||||
public bool ConcatNullYieldsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.concatNullYieldsNull;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.concatNullYieldsNull = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Numeric Roundabout
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_NumericRoundAbort")]
|
||||
public bool NumericRoundAbort
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.numericRoundAbort;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.numericRoundAbort = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DatabasePrototype80(CDataContainer context) : base(context) { }
|
||||
|
||||
/// <summary>
|
||||
/// Commit property changes to the database
|
||||
/// </summary>
|
||||
/// <param name="db">The database whose properties we are changing</param>
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
|
||||
// never set the real database collation to "<server default>" - there is no
|
||||
// real collation with that name. "<server default>" is only valid for new
|
||||
// databases and just means "don't set the collation".
|
||||
if ((!this.Exists || (this.Exists && (db.Collation != this.Collation))) &&
|
||||
(this.originalState.defaultCollation != this.Collation))
|
||||
{
|
||||
db.Collation = this.Collation;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.AnsiPaddingEnabled != this.AnsiPadding))
|
||||
{
|
||||
db.DatabaseOptions.AnsiPaddingEnabled = this.AnsiPadding;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.AnsiWarningsEnabled != this.AnsiWarnings))
|
||||
{
|
||||
db.DatabaseOptions.AnsiWarningsEnabled = this.AnsiWarnings;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.ArithmeticAbortEnabled != this.Arithabort))
|
||||
{
|
||||
db.DatabaseOptions.ArithmeticAbortEnabled = this.Arithabort;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.ConcatenateNullYieldsNull != this.ConcatNullYieldsNull))
|
||||
{
|
||||
db.DatabaseOptions.ConcatenateNullYieldsNull = this.ConcatNullYieldsNull;
|
||||
}
|
||||
|
||||
if (db.IsSupportedProperty("PageVerify"))
|
||||
{
|
||||
if (!this.Exists || (db.DatabaseOptions.PageVerify != this.currentState.pageVerify))
|
||||
{
|
||||
db.DatabaseOptions.PageVerify = this.currentState.pageVerify;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.NumericRoundAbortEnabled != this.NumericRoundAbort))
|
||||
{
|
||||
db.DatabaseOptions.NumericRoundAbortEnabled = this.NumericRoundAbort;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.ReadOnly != this.IsReadOnly))
|
||||
{
|
||||
db.DatabaseOptions.ReadOnly = this.IsReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region IDynamicValues Members
|
||||
|
||||
public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
TypeConverter.StandardValuesCollection result = null;
|
||||
|
||||
if (context.PropertyDescriptor.Name == "PageVerifyDisplay")
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
List<string> standardValues = new List<string>();
|
||||
|
||||
if (this.IsYukonOrLater)
|
||||
{
|
||||
standardValues.Add(manager.GetString("prototype_db_prop_pageVerify_value_checksum"));
|
||||
}
|
||||
|
||||
standardValues.Add(manager.GetString("prototype_db_prop_pageVerify_value_tornPageDetection"));
|
||||
standardValues.Add(manager.GetString("prototype_db_prop_pageVerify_value_none"));
|
||||
|
||||
result = new TypeConverter.StandardValuesCollection(standardValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = base.GetStandardValues(context);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Prototype for SqlServer 2000 SP3 and later servers
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(DynamicValueTypeConverter))]
|
||||
internal class DatabasePrototype80SP3 : DatabasePrototype80
|
||||
{
|
||||
/// <summary>
|
||||
/// ANSI Padding enabled
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_DBChaining")]
|
||||
public bool DbChaining
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.dbChaining;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DatabasePrototype80SP3(CDataContainer context) : base(context) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Resources;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Prototype for SqlServer 2005 and later servers
|
||||
/// </summary>
|
||||
internal class DatabasePrototype90 : DatabasePrototype80SP3, IDynamicValues
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether torn page detection is enabled
|
||||
/// </summary>
|
||||
[Category("Category_Automatic"),
|
||||
DisplayNameAttribute("Property_AutoUpdateStateAsync")]
|
||||
public bool AutoUpdateStatisticsAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.autoUpdateStatisticsAsync;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.autoUpdateStatisticsAsync = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether torn page detection is enabled
|
||||
/// </summary>
|
||||
[Category("Category_Recovery"),
|
||||
DisplayNameAttribute("Property_PageVerify"),
|
||||
TypeConverter(typeof(PageVerifyTypes90))]
|
||||
public override string PageVerifyDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
string result = null;
|
||||
|
||||
switch (this.currentState.pageVerify)
|
||||
{
|
||||
case PageVerify.Checksum:
|
||||
|
||||
result = manager.GetString("prototype_db_prop_pageVerify_value_checksum");
|
||||
break;
|
||||
|
||||
case PageVerify.None:
|
||||
|
||||
result = manager.GetString("prototype_db_prop_pageVerify_value_none");
|
||||
break;
|
||||
|
||||
case PageVerify.TornPageDetection:
|
||||
|
||||
result = manager.GetString("prototype_db_prop_pageVerify_value_tornPageDetection");
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
if (value == manager.GetString("prototype_db_prop_pageVerify_value_checksum"))
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.Checksum;
|
||||
}
|
||||
else if (value == manager.GetString("prototype_db_prop_pageVerify_value_none"))
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentState.pageVerify = PageVerify.TornPageDetection;
|
||||
}
|
||||
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use ANSI warnings
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_Trustworthy")]
|
||||
public bool Trustworthy
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.trustworthy;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Arithabort
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_DateCorrelationOptimization")]
|
||||
public bool DateCorrelationOptimization
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.dateCorrelationOptimization;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.dateCorrelationOptimization = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AllowSnapshotIsolation
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_AllowSnapshotIsolation")]
|
||||
public bool AllowSnapshotIsolation
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.allowSnapshotIsolation;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.allowSnapshotIsolation = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// IsReadCommittedSnapshotOn
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_IsReadCommittedSnapshotOn")]
|
||||
public bool IsReadCommittedSnapshotOn
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.isReadCommittedSnapshotOn;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.isReadCommittedSnapshotOn = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// BrokerEnabled
|
||||
/// </summary>
|
||||
[Category("Category_ServiceBroker"),
|
||||
DisplayNameAttribute("Property_BrokerEnabled")]
|
||||
public bool BrokerEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.brokerEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.brokerEnabled = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether contatenating a null string yields a null result
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_Parameterization")]
|
||||
[TypeConverter(typeof(ParameterizationTypes))]
|
||||
public string Parameterization
|
||||
{
|
||||
get
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
string result = this.currentState.parameterization ?
|
||||
manager.GetString("prototype_db_prop_parameterization_value_forced") :
|
||||
manager.GetString("prototype_db_prop_parameterization_value_simple");
|
||||
|
||||
return result;
|
||||
}
|
||||
set
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
this.currentState.parameterization = (value == manager.GetString("prototype_db_prop_parameterization_value_forced"));
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service Broker Guid
|
||||
/// </summary>
|
||||
[Category("Category_ServiceBroker"),
|
||||
DisplayNameAttribute("Property_ServiceBrokerGUID")]
|
||||
public System.Guid ServiceBrokerGuid
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.serviceBrokerGuid;
|
||||
}
|
||||
}
|
||||
|
||||
public DatabasePrototype90(CDataContainer context) : base(context) { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Commit property changes to the database
|
||||
/// </summary>
|
||||
/// <param name="db">The database whose properties we are changing</param>
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.AutoUpdateStatisticsAsync != this.AutoUpdateStatisticsAsync))
|
||||
{
|
||||
db.DatabaseOptions.AutoUpdateStatisticsAsync = this.AutoUpdateStatisticsAsync;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.DateCorrelationOptimization != this.DateCorrelationOptimization))
|
||||
{
|
||||
db.DatabaseOptions.DateCorrelationOptimization = this.DateCorrelationOptimization;
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.DatabaseOptions.IsParameterizationForced != this.currentState.parameterization))
|
||||
{
|
||||
db.DatabaseOptions.IsParameterizationForced = this.currentState.parameterization;
|
||||
}
|
||||
if (db.IsSupportedProperty("BrokerEnabled"))
|
||||
{
|
||||
if (!this.Exists || (db.DatabaseOptions.BrokerEnabled != this.currentState.brokerEnabled))
|
||||
{
|
||||
db.DatabaseOptions.BrokerEnabled = this.currentState.brokerEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.Exists || (db.IsReadCommittedSnapshotOn != this.IsReadCommittedSnapshotOn))
|
||||
{
|
||||
db.IsReadCommittedSnapshotOn = this.IsReadCommittedSnapshotOn;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDynamicValues Members
|
||||
|
||||
public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
||||
{
|
||||
TypeConverter.StandardValuesCollection result = null;
|
||||
|
||||
if (context.PropertyDescriptor.Name == "Parameterization")
|
||||
{
|
||||
ResourceManager manager = new ResourceManager("Microsoft.SqlTools.ServiceLayer.Localization.SR", typeof(DatabasePrototype).GetAssembly());
|
||||
List<string> standardValues = new List<string>();
|
||||
standardValues.Add(manager.GetString("prototype_db_prop_parameterization_value_forced"));
|
||||
standardValues.Add(manager.GetString("prototype_db_prop_parameterization_value_simple"));
|
||||
result = new TypeConverter.StandardValuesCollection(standardValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = base.GetStandardValues(context);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Prototype for SqlServer 2005 Enterprise SP2 and later servers
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(DynamicValueTypeConverter))]
|
||||
internal class DatabasePrototype90EnterpriseSP2 : DatabasePrototype90
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether vardecimal compression is enabled on the server
|
||||
/// </summary>
|
||||
[Category("Category_Misc"),
|
||||
DisplayNameAttribute("Property_VarDecimalEnabled")]
|
||||
public bool VarDecimalEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.varDecimalEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.currentState.varDecimalEnabled = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
public DatabasePrototype90EnterpriseSP2(CDataContainer context) : base(context) { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Commit property changes to the database
|
||||
/// </summary>
|
||||
/// <param name="db">The database whose properties we are changing</param>
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
|
||||
// changing decimal compression status is very expensive, so
|
||||
// only set a value for vardecimal compression if its value has changed
|
||||
if (this.originalState.varDecimalEnabled != this.currentState.varDecimalEnabled)
|
||||
{
|
||||
db.IsVarDecimalStorageFormatEnabled = this.currentState.varDecimalEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Data.SqlClient;
|
||||
using AzureEdition = Microsoft.SqlTools.ServiceLayer.Admin.AzureSqlDbHelper.AzureEdition;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Database properties for SQL Azure DB.
|
||||
/// Business/Web editions are up to compat level 100 now
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(DynamicValueTypeConverter))]
|
||||
internal class DatabasePrototypeAzure : DatabasePrototype100
|
||||
{
|
||||
|
||||
#region Constants
|
||||
|
||||
public const string Category_Azure = "Category_Azure";
|
||||
public const string Property_AzureMaxSize = "Property_AzureMaxSize";
|
||||
public const string Property_AzureCurrentServiceLevelObjective = "Property_AzureCurrentServiceLevelObjective";
|
||||
public const string Property_AzureConfiguredServiceLevelObjective = "Property_AzureConfiguredServiceLevelObjective";
|
||||
public const string Property_AzureEdition = "Property_AzureEdition";
|
||||
#endregion Constants
|
||||
|
||||
public DatabasePrototypeAzure(CDataContainer context, DatabaseEngineEdition editionToCreate = DatabaseEngineEdition.SqlDatabase)
|
||||
: base(context)
|
||||
{
|
||||
EditionToCreate = editionToCreate;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
[Category(Category_Azure),
|
||||
DisplayNameAttribute(Property_AzureMaxSize)]
|
||||
public string MaxSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.maxSize == null ? null : this.currentState.maxSize.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.maxSize = DbSize.ParseDbSize(value);
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category(Category_Azure),
|
||||
DisplayNameAttribute(Property_AzureCurrentServiceLevelObjective)]
|
||||
public string CurrentServiceLevelObjective
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.currentServiceLevelObjective;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.currentState.currentServiceLevelObjective = value;
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
[Category(Category_Azure),
|
||||
DisplayNameAttribute(Property_AzureConfiguredServiceLevelObjective)]
|
||||
public string ConfiguredServiceLevelObjective
|
||||
{
|
||||
//This value is read only because it's changed by changing the current SLO,
|
||||
//we just expose this to show if the DB is currently transitioning
|
||||
get
|
||||
{
|
||||
return this.currentState.configuredServiceLevelObjective;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public AzureEdition AzureEdition
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.currentState.azureEdition;
|
||||
}
|
||||
}
|
||||
|
||||
[Category(Category_Azure),
|
||||
DisplayNameAttribute(Property_AzureEdition)]
|
||||
//We have a separate property here so that the AzureEdition enum value is still exposed
|
||||
//(This property is for the name displayed in the drop down menu, which needs to be a string for casting purposes)
|
||||
public string AzureEditionDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return AzureSqlDbHelper.GetAzureEditionDisplayName(this.currentState.azureEdition);
|
||||
}
|
||||
set
|
||||
{
|
||||
AzureEdition edition;
|
||||
if (AzureSqlDbHelper.TryGetAzureEditionFromDisplayName(value, out edition))
|
||||
{
|
||||
if (edition == this.currentState.azureEdition)
|
||||
{ //No changes, return early since we don't need to do any of the changes below
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentState.azureEdition = edition;
|
||||
this.CurrentServiceLevelObjective = AzureSqlDbHelper.GetDefaultServiceObjective(edition);
|
||||
this.MaxSize = AzureSqlDbHelper.GetDatabaseDefaultSize(edition).ToString();
|
||||
this.NotifyObservers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IList<FilegroupPrototype> Filegroups
|
||||
{
|
||||
get { return Enumerable.Empty<FilegroupPrototype>().ToList(); }
|
||||
}
|
||||
|
||||
|
||||
public override IList<DatabaseFilePrototype> Files
|
||||
{
|
||||
get { return Enumerable.Empty<DatabaseFilePrototype>().ToList(); }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public override bool HideFileSettings
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public override bool AllowScripting
|
||||
{
|
||||
get { return this.ServerVersion.Major > 11 && this.AzureEdition != AzureEdition.DataWarehouse; }
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region DatabasePrototype overrides
|
||||
|
||||
/// <summary>
|
||||
/// Commit changes to the database
|
||||
/// </summary>
|
||||
/// <param name="marshallingControl">The control through which UI interactions are to be marshalled</param>
|
||||
/// <returns>The SMO database object that was created or modified</returns>
|
||||
public override Database ApplyChanges()
|
||||
{
|
||||
// For v12 Non-DW DBs lets use SMO
|
||||
if (this.ServerVersion.Major >= 12 && this.AzureEdition != AzureEdition.DataWarehouse)
|
||||
{
|
||||
return base.ApplyChanges();
|
||||
}
|
||||
|
||||
//Note : We purposely don't call base.ApplyChanges() here since SMO doesn't fully support Azure yet and so will throw
|
||||
//an error if we try to modify the Database object directly
|
||||
string alterDbPropertiesStatement = DatabasePrototypeAzure.CreateModifyAzureDbOptionsStatement(this.Name, this.AzureEdition, this.MaxSize, this.CurrentServiceLevelObjective);
|
||||
if (this.AzureEdition == AzureEdition.DataWarehouse)
|
||||
{
|
||||
alterDbPropertiesStatement = DatabasePrototypeAzure.CreateModifySqlDwDbOptionsStatement(this.Name, this.MaxSize, this.CurrentServiceLevelObjective);
|
||||
}
|
||||
|
||||
string alterAzureDbRecursiveTriggersEnabledStatement = DatabasePrototypeAzure.CreateAzureDbSetRecursiveTriggersStatement(this.Name, this.RecursiveTriggers);
|
||||
string alterAzureDbIsReadOnlyStatement = DatabasePrototypeAzure.CreateAzureDbSetIsReadOnlyStatement(this.Name, this.IsReadOnly);
|
||||
|
||||
Database db = this.GetDatabase();
|
||||
|
||||
//Altering the DB needs to be done on the master DB
|
||||
using (var conn = new SqlConnection(this.context.ServerConnection.GetDatabaseConnection("master").ConnectionString))
|
||||
{
|
||||
var cmd = new SqlCommand();
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
|
||||
//Only run the alter statements for modifications made. This is mostly to allow the non-Azure specific
|
||||
//properties to be updated when a SLO change is in progress, but it also is beneficial to save trips to the
|
||||
//server whenever we can (especially when Azure is concerned)
|
||||
if (currentState.azureEdition != originalState.azureEdition ||
|
||||
currentState.currentServiceLevelObjective != originalState.currentServiceLevelObjective ||
|
||||
currentState.maxSize != originalState.maxSize)
|
||||
{
|
||||
cmd.CommandText = alterDbPropertiesStatement;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
if (currentState.recursiveTriggers != originalState.recursiveTriggers)
|
||||
{
|
||||
cmd.CommandText = alterAzureDbRecursiveTriggersEnabledStatement;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
if (currentState.isReadOnly != originalState.isReadOnly)
|
||||
{
|
||||
cmd.CommandText = alterAzureDbIsReadOnlyStatement;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
//Because we didn't use SMO to do the alter we should refresh the DB object so it picks up the correct properties
|
||||
db.Refresh();
|
||||
|
||||
// For properties that are supported in Database.Alter(), call SaveProperties, and then alter the DB.
|
||||
//
|
||||
if (this.AzureEdition != AzureEdition.DataWarehouse)
|
||||
{
|
||||
this.SaveProperties(db);
|
||||
db.Alter(TerminationClause.FailOnOpenTransactions);
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
#endregion DatabasePrototype overrides
|
||||
|
||||
protected override void SaveProperties(Database db)
|
||||
{
|
||||
base.SaveProperties(db);
|
||||
if (this.ServerVersion.Major >= 12 && this.AzureEdition != AzureEdition.DataWarehouse)
|
||||
{
|
||||
if (!this.Exists || (this.originalState.maxSize != this.currentState.maxSize))
|
||||
{
|
||||
db.MaxSizeInBytes = this.currentState.maxSize.SizeInBytes;
|
||||
}
|
||||
|
||||
if (!this.Exists || (this.originalState.azureEdition != this.currentState.azureEdition))
|
||||
{
|
||||
db.AzureEdition = this.currentState.azureEdition.ToString();
|
||||
}
|
||||
|
||||
if (!this.Exists || (this.originalState.currentServiceLevelObjective != this.currentState.currentServiceLevelObjective))
|
||||
{
|
||||
db.AzureServiceObjective = this.currentState.currentServiceLevelObjective;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private const string AlterDbStatementFormat =
|
||||
@"ALTER DATABASE [{0}] {1}";
|
||||
|
||||
private const string ModifyAzureDbStatementFormat = @"MODIFY (EDITION = '{0}', MAXSIZE={1} {2})";
|
||||
private const string ModifySqlDwDbStatementFormat = @"MODIFY (MAXSIZE={0} {1})";
|
||||
private const string AzureServiceLevelObjectiveOptionFormat = @"SERVICE_OBJECTIVE = '{0}'";
|
||||
private const string SetReadOnlyOption = @"SET READ_ONLY";
|
||||
private const string SetReadWriteOption = @"SET READ_WRITE";
|
||||
private const string SetRecursiveTriggersOptionFormat = @"SET RECURSIVE_TRIGGERS {0}";
|
||||
private const string On = @"ON";
|
||||
private const string Off = @"OFF";
|
||||
|
||||
/// <summary>
|
||||
/// Creates an ALTER DATABASE statement to modify the Read-Only status of the target DB
|
||||
/// </summary>
|
||||
/// <param name="dbName"></param>
|
||||
/// <param name="isReadOnly"></param>
|
||||
/// <returns></returns>
|
||||
protected static string CreateAzureDbSetIsReadOnlyStatement(string dbName, bool isReadOnly)
|
||||
{
|
||||
return CreateAzureAlterDbStatement(dbName,
|
||||
string.Format(CultureInfo.InvariantCulture,
|
||||
isReadOnly ? SetReadOnlyOption : SetReadWriteOption));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an ALTER DATABASE statement to modify the RECURSIVE_TRIGGERS option of the target DB
|
||||
/// </summary>
|
||||
/// <param name="dbName"></param>
|
||||
/// <param name="recursiveTriggersEnabled"></param>
|
||||
/// <returns></returns>
|
||||
protected static string CreateAzureDbSetRecursiveTriggersStatement(string dbName, bool recursiveTriggersEnabled)
|
||||
{
|
||||
return CreateAzureAlterDbStatement(dbName,
|
||||
string.Format(CultureInfo.InvariantCulture,
|
||||
DatabasePrototypeAzure.SetRecursiveTriggersOptionFormat,
|
||||
recursiveTriggersEnabled ? DatabasePrototypeAzure.On : DatabasePrototypeAzure.Off));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an ALTER DATABASE statement to modify the Azure Database properties (Edition, MaxSize and Service Level Objective)
|
||||
/// for the target database
|
||||
/// </summary>
|
||||
/// <param name="dbName"></param>
|
||||
/// <param name="edition"></param>
|
||||
/// <param name="maxSize"></param>
|
||||
/// <param name="serviceLevelObjective"></param>
|
||||
/// <returns></returns>
|
||||
protected static string CreateModifyAzureDbOptionsStatement(string dbName, AzureEdition edition, string maxSize, string serviceLevelObjective)
|
||||
{
|
||||
//We might not have a SLO since some editions don't support it
|
||||
string sloOption = string.IsNullOrEmpty(serviceLevelObjective) ?
|
||||
string.Empty : ", " + string.Format(CultureInfo.InvariantCulture, AzureServiceLevelObjectiveOptionFormat, serviceLevelObjective);
|
||||
|
||||
return CreateAzureAlterDbStatement(dbName,
|
||||
string.Format(CultureInfo.InvariantCulture,
|
||||
ModifyAzureDbStatementFormat,
|
||||
edition,
|
||||
maxSize,
|
||||
sloOption));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an ALTER DATABASE statement to modify the Azure DataWarehouse properties (MaxSize and Service Level Objective)
|
||||
/// for the target database
|
||||
/// </summary>
|
||||
/// <param name="dbName">Name of the database</param>
|
||||
/// <param name="maxSize">MaxSize of the database</param>
|
||||
/// <param name="serviceLevelObjective">New SLO of the database</param>
|
||||
/// <returns>Sql Statement to Alter the database.</returns>
|
||||
protected static string CreateModifySqlDwDbOptionsStatement(string dbName, string maxSize, string serviceLevelObjective)
|
||||
{
|
||||
//We might not have a SLO since some editions don't support it
|
||||
string sloOption = string.IsNullOrEmpty(serviceLevelObjective) ?
|
||||
string.Empty : ", " + string.Format(CultureInfo.InvariantCulture, AzureServiceLevelObjectiveOptionFormat, serviceLevelObjective);
|
||||
|
||||
return CreateAzureAlterDbStatement(dbName,
|
||||
string.Format(CultureInfo.InvariantCulture,
|
||||
ModifySqlDwDbStatementFormat,
|
||||
maxSize,
|
||||
sloOption));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the ALTER DATABASE statement from the given op
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string CreateAzureAlterDbStatement(string dbName, string options)
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, AlterDbStatementFormat,
|
||||
CUtils.EscapeString(CUtils.EscapeString(dbName, ']'), '\''),
|
||||
options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
//
|
||||
// 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.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
{
|
||||
public class DatabaseTaskHelper
|
||||
{
|
||||
private DatabasePrototype prototype;
|
||||
|
||||
private XmlDocument document;
|
||||
|
||||
public CDataContainer DataContainer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Expose database prototype to internal classes
|
||||
/// </summary>
|
||||
public DatabasePrototype Prototype
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.prototype;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.prototype = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseTaskHelper(CDataContainer context)
|
||||
{
|
||||
Initialize(context);
|
||||
}
|
||||
|
||||
internal void Initialize(CDataContainer context)
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
this.DataContainer = context;
|
||||
this.document = context.Document;
|
||||
|
||||
int majorVersionNumber = context.Server.Information.Version.Major;
|
||||
Version sql2000sp3 = new Version(8, 0, 760);
|
||||
Version sql2005sp2 = new Version(9, 0, 3000);
|
||||
|
||||
if (context.Server.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase)
|
||||
{
|
||||
this.prototype = new DatabasePrototypeAzure(context);
|
||||
}
|
||||
else if (Utils.IsSql11OrLater(context.Server.Version.Major))
|
||||
{
|
||||
this.prototype = new DatabasePrototype110(context);
|
||||
}
|
||||
else if (majorVersionNumber == 10)
|
||||
{
|
||||
this.prototype = new DatabasePrototype100(context);
|
||||
}
|
||||
else if ((sql2005sp2 <= context.Server.Information.Version) &&
|
||||
(context.Server.Information.EngineEdition == Edition.EnterpriseOrDeveloper))
|
||||
{
|
||||
this.prototype = new DatabasePrototype90EnterpriseSP2(context);
|
||||
}
|
||||
else if (8 < majorVersionNumber)
|
||||
{
|
||||
this.prototype = new DatabasePrototype90(context);
|
||||
}
|
||||
else if (sql2000sp3 <= context.Server.Information.Version)
|
||||
{
|
||||
this.prototype = new DatabasePrototype80SP3(context);
|
||||
}
|
||||
else if (7 < majorVersionNumber)
|
||||
{
|
||||
this.prototype = new DatabasePrototype80(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.prototype = new DatabasePrototype(context);
|
||||
}
|
||||
|
||||
this.prototype.Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DataContainer = null;
|
||||
this.document = null;
|
||||
this.prototype = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static DatabaseInfo DatabasePrototypeToDatabaseInfo(DatabasePrototype prototype)
|
||||
{
|
||||
var databaseInfo = new DatabaseInfo();
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.Name, prototype.Name);
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.Owner, prototype.Owner);
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.Collation, prototype.Collation);
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.DatabaseState, prototype.DatabaseState.ToString());
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.IsSystemDB, prototype.IsSystemDB.ToString());
|
||||
databaseInfo.Options.Add(AdminServicesProviderOptionsHelper.AnsiNulls, prototype.AnsiNulls.ToString());
|
||||
|
||||
databaseInfo.Options.Add(
|
||||
AdminServicesProviderOptionsHelper.FileGroups + "Count",
|
||||
prototype.Filegroups.Count);
|
||||
|
||||
for (int i = 0; i < prototype.Filegroups.Count; ++i)
|
||||
{
|
||||
var fileGroup = prototype.Filegroups[i];
|
||||
string itemPrefix = AdminServicesProviderOptionsHelper.FileGroups + "." + i + ".";
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Name, fileGroup.Name);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.IsMemoryOptimized, fileGroup.IsMemoryOptimized);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.IsReadOnly, fileGroup.IsReadOnly);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.IsFileStream, fileGroup.IsFileStream);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.IsDefault, fileGroup.IsDefault);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.FileGroupType, fileGroup.FileGroupType.ToString());
|
||||
}
|
||||
|
||||
databaseInfo.Options.Add(
|
||||
AdminServicesProviderOptionsHelper.DatabaseFiles + "Count",
|
||||
prototype.Files.Count);
|
||||
|
||||
for (int i = 0; i < prototype.Files.Count; ++i)
|
||||
{
|
||||
var file = prototype.Files[i];
|
||||
string itemPrefix = AdminServicesProviderOptionsHelper.DatabaseFiles + "." + i + ".";
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Name, file.Name);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.PhysicalName, file.PhysicalName);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Autogrowth, file.DefaultAutogrowth.ToString());
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.DatabaseFileType, file.DatabaseFileType.ToString());
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Folder, file.DefaultFolder);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.Size, file.DefaultSize);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.FileGroup, file.FileGroup != null ? file.FileGroup.Name : string.Empty);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.InitialSize, file.InitialSize);
|
||||
databaseInfo.Options.Add(itemPrefix + AdminServicesProviderOptionsHelper.IsPrimaryFile, file.IsPrimaryFile);
|
||||
}
|
||||
|
||||
return databaseInfo;
|
||||
}
|
||||
|
||||
private static T GetValueOrDefault<T>(string key, Dictionary<string, object> map, T defaultValue)
|
||||
{
|
||||
if (map != null && map.ContainsKey(key))
|
||||
{
|
||||
return map[key] != null ? (T)map[key] : default(T);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static int logicalNameCount = 0;
|
||||
|
||||
public static DatabasePrototype ApplyToPrototype(DatabaseInfo databaseInfo, DatabasePrototype prototype)
|
||||
{
|
||||
if (databaseInfo != null && prototype != null)
|
||||
{
|
||||
prototype.Name = GetValueOrDefault(AdminServicesProviderOptionsHelper.Name, databaseInfo.Options, prototype.Name);
|
||||
|
||||
foreach (var file in prototype.Files)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(file.Name))
|
||||
{
|
||||
file.Name = prototype.Name + "_" + logicalNameCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return prototype;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user