Merge create db work in progress (#341)

* Port over initial block of create db implementation

* Test case placeholder

* In-progress work

* Stage changes to other machine

* Add database prototype strings

* Stage changes to other machine

* Stage changes

* Hook the database info into capabilities discovery

* Stage changes

* Update SMO to latest from ssms_main

* Various clean-ups

* Update localization files
This commit is contained in:
Karl Burtram
2017-05-09 17:56:32 -07:00
committed by GitHub
parent 137335ffd5
commit 2e9843cec1
48 changed files with 16102 additions and 1446 deletions

Binary file not shown.

View File

@@ -12,7 +12,7 @@
"Newtonsoft.Json": "9.0.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "140.17049.0",
"Microsoft.SqlServer.Smo": "140.17050.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",

View File

@@ -5,7 +5,7 @@
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.SqlServer.Smo": "140.17049.0"
"Microsoft.SqlServer.Smo": "140.17050.0"
},
"frameworks": {
"netcoreapp1.0": {

View File

@@ -0,0 +1,20 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.Hosting.Contracts
{
/// <summary>
/// Defines the admin services provider options that the DMP server implements.
/// </summary>
public class AdminServicesProviderOptions
{
public ServiceOption[] DatabaseInfoOptions { get; set; }
public ServiceOption[] DatabaseFileInfoOptions { get; set; }
public ServiceOption[] FileGroupInfoOptions { get; set; }
}
}

View File

@@ -22,41 +22,14 @@ namespace Microsoft.SqlTools.Hosting.Contracts
public string Name { get; set; }
}
public class ConnectionOption
public class ConnectionOption : ServiceOption
{
public static readonly string ValueTypeString = "string";
public static readonly string ValueTypeMultiString = "multistring";
public static readonly string ValueTypePassword = "password";
public static readonly string ValueTypeNumber = "number";
public static readonly string ValueTypeCategory = "category";
public static readonly string ValueTypeBoolean = "boolean";
public static readonly string SpecialValueServerName = "serverName";
public static readonly string SpecialValueDatabaseName = "databaseName";
public static readonly string SpecialValueAuthType = "authType";
public static readonly string SpecialValueUserName = "userName";
public static readonly string SpecialValuePasswordName = "password";
public string Name { get; set; }
public string DisplayName { get; set; }
public string Description {get; set; }
public string GroupName {get; set; }
/// <summary>
/// Type of the parameter. Can be either string, number, or category.
/// </summary>
public string ValueType { get; set; }
public string DefaultValue { get; set; }
/// <summary>
/// Set of permitted values if ValueType is category.
/// </summary>
public CategoryValue[] CategoryValues { get; set; }
/// <summary>
/// Determines if the parameter is one of the 'special' known values.
/// Can be either Server Name, Database Name, Authentication Type,
@@ -68,11 +41,6 @@ namespace Microsoft.SqlTools.Hosting.Contracts
/// Flag to indicate that this option is part of the connection identity
/// </summary>
public bool IsIdentity { get; set; }
/// <summary>
/// Flag to indicate that this option is required
/// </summary>
public bool IsRequired { get; set; }
}
}

View File

@@ -17,5 +17,7 @@ namespace Microsoft.SqlTools.Hosting.Contracts
public string ProviderDisplayName { get; set; }
public ConnectionProviderOptions ConnectionProvider { get; set; }
public AdminServicesProviderOptions AdminServicesProvider { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.Hosting.Contracts
{
public class ServiceOption
{
public static readonly string ValueTypeString = "string";
public static readonly string ValueTypeMultiString = "multistring";
public static readonly string ValueTypePassword = "password";
public static readonly string ValueTypeNumber = "number";
public static readonly string ValueTypeCategory = "category";
public static readonly string ValueTypeBoolean = "boolean";
public static readonly string ValueTypeObject = "object";
public string Name { get; set; }
public string DisplayName { get; set; }
public string Description {get; set; }
public string GroupName {get; set; }
/// <summary>
/// Type of the parameter. Can be either string, number, or category.
/// </summary>
public string ValueType { get; set; }
public string DefaultValue { get; set; }
public string ObjectType { get; set; }
/// <summary>
/// Set of permitted values if ValueType is category.
/// </summary>
public CategoryValue[] CategoryValues { get; set; }
/// <summary>
/// Flag to indicate that this option is required
/// </summary>
public bool IsRequired { get; set; }
public bool IsArray { get; set; }
}
}

View File

@@ -5,10 +5,12 @@
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using System;
using System.Threading.Tasks;
using System.Xml;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
@@ -19,6 +21,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
{
private static readonly Lazy<AdminService> instance = new Lazy<AdminService>(() => new AdminService());
private static ConnectionService connectionService = null;
/// <summary>
/// Default, parameterless constructor.
/// </summary>
@@ -26,6 +30,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
{
}
/// <summary>
/// Internal for testing purposes only
/// </summary>
internal static ConnectionService ConnectionServiceInstance
{
get
{
if (AdminService.connectionService == null)
{
AdminService.connectionService = ConnectionService.Instance;
}
return AdminService.connectionService;
}
set
{
AdminService.connectionService = value;
}
}
/// <summary>
/// Gets the singleton instance object
/// </summary>
@@ -41,6 +65,62 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
{
serviceHost.SetRequestHandler(CreateDatabaseRequest.Type, HandleCreateDatabaseRequest);
serviceHost.SetRequestHandler(CreateLoginRequest.Type, HandleCreateLoginRequest);
serviceHost.SetRequestHandler(DefaultDatabaseInfoRequest.Type, HandleDefaultDatabaseInfoRequest);
}
public static async Task HandleDefaultDatabaseInfoRequest(
DefaultDatabaseInfoParams optionsParams,
RequestContext<DefaultDatabaseInfoResponse> requestContext)
{
var response = new DefaultDatabaseInfoResponse();
ConnectionInfo connInfo;
AdminService.ConnectionServiceInstance.TryFindConnection(
optionsParams.OwnerUri,
out connInfo);
XmlDocument xmlDoc = CreateDataContainerDocument(connInfo);
char[] passwordArray = connInfo.ConnectionDetails.Password.ToCharArray();
unsafe
{
fixed (char* passwordPtr = passwordArray)
{
var dataContainer = new CDataContainer(
CDataContainer.ServerType.SQL,
connInfo.ConnectionDetails.ServerName,
false,
connInfo.ConnectionDetails.UserName,
new System.Security.SecureString(passwordPtr, passwordArray.Length),
xmlDoc.InnerXml);
var taskHelper = new DatabaseTaskHelper();
taskHelper.CreateDatabase(dataContainer);
response.DefaultDatabaseInfo = DatabaseTaskHelper.DatabasePrototypeToDatabaseInfo(taskHelper.Prototype);
}
}
await requestContext.SendResult(response);
}
private static XmlDocument CreateDataContainerDocument(ConnectionInfo connInfo)
{
string xml =
string.Format(@"<?xml version=""1.0""?>
<formdescription><params>
<servername>{0}</servername>
<connectionmoniker>{0} (SQLServer, user = {1})</connectionmoniker>
<servertype>sql</servertype>
<urn>Server[@Name='{0}']</urn>
<itemtype>Database</itemtype>
</params></formdescription> ",
connInfo.ConnectionDetails.ServerName.ToUpper(),
connInfo.ConnectionDetails.UserName);
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
return xmlDoc;
}
/// <summary>

View File

@@ -0,0 +1,114 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Helper class for providing metadata about admin services
/// </summary>
public class AdminServicesProviderOptionsHelper
{
internal const string Name = "name";
internal const string Owner = "owner";
internal const string Collation = "collation";
internal const string FileGroups = "fileGroups";
internal const string DatabaseFiles = "databaseFiles";
internal const string PhysicalName = "physicalName";
internal static AdminServicesProviderOptions BuildAdminServicesProviderOptions()
{
return new AdminServicesProviderOptions
{
DatabaseInfoOptions = new ServiceOption[]
{
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.Name,
DisplayName = "Name",
Description = "Name of the database",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
},
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.Owner,
DisplayName = "Owner",
Description = "Database owner",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
},
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.Collation,
DisplayName = "Collation",
Description = "Database collation",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
},
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.FileGroups,
DisplayName = "File Groups",
Description = "File groups",
ObjectType = "FileGroupInfo",
ValueType = ServiceOption.ValueTypeObject,
IsRequired = true,
IsArray = true,
GroupName = "General"
},
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.DatabaseFiles,
DisplayName = "Database Files",
Description = "Database Files",
ObjectType = "DatabaseFileInfo",
ValueType = ServiceOption.ValueTypeObject,
IsRequired = true,
IsArray = true,
GroupName = "General"
}
},
FileGroupInfoOptions = new ServiceOption[]
{
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.Name,
DisplayName = "Name",
Description = "Name of the file group",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
}
},
DatabaseFileInfoOptions = new ServiceOption[]
{
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.Name,
DisplayName = "Name",
Description = "Name of the database file",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
},
new ServiceOption
{
Name = AdminServicesProviderOptionsHelper.PhysicalName,
DisplayName = "Physical Name",
Description = "Physical name of the database file",
ValueType = ServiceOption.ValueTypeString,
IsRequired = true,
GroupName = "General"
}
}
};
}
}
}

View File

@@ -0,0 +1,466 @@
//
// 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 key for SSMS Azure overrides
/// </summary>
private static readonly string SSMSAzureRegKey =
@"HKEY_CURRENT_USER\Software\Microsoft\SQL Server Management Studio\14.0\Azure";
/// <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()
{
//foreach (AzureEdition edition in Enum.GetValues(typeof (AzureEdition)))
//{
// object value;
// try
// {
// value = Registry.GetValue(
// string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", SSMSAzureRegKey,
// AzureServiceObjectivesRegSubKey), edition.ToString(), null);
// }
// catch (Exception e)
// {
// //We don't really care if we can't read in an override (just fall back to default) so log and move on
// TraceContext.TraceVerbose("Exception reading service objective overrides for {0} - {1}", edition, e.Message);
// continue;
// }
// if (value != null)
// {
// TraceContext.TraceVerbose("Found ServiceObjective override for {0}, value is {1}", edition, value);
// //Key is in format <DefaultIndex>:<ServiceObjectiveList>
// //e.g. 2:S0,S1,S2
// //Only split into 2 parts since the service objectives could
// //be changed in the future to have :'s, so only treat the first
// //as special
// string[] values = value.ToString().Split(new[] {':'}, 2);
// if (values.Length != 2)
// {
// //Badly formatted value, ignore this one
// TraceContext.TraceVerbose("ServiceObjective override for {0} is badly formatted - skipping", edition);
// continue;
// }
// int defaultIndex;
// if (!int.TryParse(values[0], out defaultIndex))
// {
// //Invalid default index, ignore this one
// TraceContext.TraceVerbose("ServiceObjective override for {0} has non-parseable default index - skipping", edition);
// continue;
// }
// //Service objectives are in a comma-separated list
// string[] serviceObjectives = values[1].Split(',');
// if (defaultIndex < 0 || defaultIndex >= serviceObjectives.Length)
// {
// //Index out of bounds, ignore this one
// TraceContext.TraceVerbose("ServiceObjective override for {0} has out of bounds default index - skipping");
// continue;
// }
// if (AzureServiceObjectiveInfo.ContainsKey(edition))
// {
// //Overwrite our default values if the registry key for this edition exists
// AzureServiceObjectiveInfo[edition] = new KeyValuePair<int, string[]>(defaultIndex,
// serviceObjectives);
// }
// else
// {
// AzureServiceObjectiveInfo.Add(edition,
// new KeyValuePair<int, string[]>(defaultIndex, serviceObjectives));
// }
// }
//}
}
/// <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>();
}
}
}

View File

@@ -0,0 +1,717 @@
//
// 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.Sdk.Sfc;
using System;
using System.Text;
using System.Xml;
//using System.Drawing;
//using System.Windows.Forms;
using System.Threading;
using System.IO;
//using Microsoft.NetEnterpriseServers;
//using Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer;
using Microsoft.SqlServer.Management.Common;
using SMO = Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Diagnostics;
//using Microsoft.SqlServer.Management.SqlMgmt;
using System.Data.SqlClient;
// using System.Management;
using System.Collections;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Summary description for CUtils.
/// </summary>
internal class CUtils
{
private const int ObjectPermissionsDeniedErrorNumber = 229;
private const int ColumnPermissionsDeniedErrorNumber = 230;
public CUtils()
{
//
// TODO: Add constructor logic here
//
}
//public Bitmap LoadBitmap(string szBitmapName)
//{
// Bitmap bmp = null;
// Stream s = null;
// string strQualifiedName;
// strQualifiedName = typeof(CUtils).Namespace + ".Images." + szBitmapName;
// s = typeof(CUtils).Assembly.GetManifestResourceStream(strQualifiedName);
// if (s != null)
// {
// bmp = new Bitmap(s);
// return bmp;
// }
// return null;
//}
//public Icon LoadIcon(string strName)
//{
// Icon ico = null;
// Stream s = null;
// string strQualifiedName;
// strQualifiedName = typeof(CUtils).Namespace + ".Images." + strName;
// s = typeof(CUtils).Assembly.GetManifestResourceStream(strQualifiedName);
// if (s != null)
// {
// int iconSize = DpiUtil.GetScaledImageSize();
// ico = new Icon(s, iconSize, iconSize);
// return ico;
// }
// return null;
//}
//public void LoadAddIcon(ImageList imageList, string strName)
//{
// Icon ico = null;
// Stream s = null;
// string strQualifiedName;
// strQualifiedName = typeof(CUtils).Namespace + ".Images." + strName;
// s = typeof(CUtils).Module.Assembly.GetManifestResourceStream(strQualifiedName);
// if (s != null)
// {
// try
// {
// ico = new Icon(s, 16, 16);
// imageList.Images.Add(ico);
// }
// finally
// {
// if (ico != null)
// ico.Dispose();
// }
// }
//}
public static void UseMaster(SMO.Server server)
{
server.ConnectionContext.ExecuteNonQuery("use master");
}
///// <summary>
///// returns height of my border (depending on its style)
///// </summary>
//public static int GetBorderHeight(BorderStyle style)
//{
// if (style == BorderStyle.FixedSingle)
// {
// return SystemInformation.BorderSize.Height;
// }
// else if (style == BorderStyle.Fixed3D)
// {
// return SystemInformation.Border3DSize.Height;
// }
// else
// {
// return 0;
// }
//}
//public static int GetBorderWidth(BorderStyle style)
//{
// if (style == BorderStyle.FixedSingle)
// {
// return SystemInformation.BorderSize.Width;
// }
// else if (style == BorderStyle.Fixed3D)
// {
// return SystemInformation.Border3DSize.Width;
// }
// else
// {
// return 0;
// }
//}
/// <summary>
/// Get a SMO Server object that is connected to the connection
/// </summary>
/// <param name="ci">Conenction info</param>
/// <returns>Smo Server object for the connection</returns>
public static Microsoft.SqlServer.Management.Smo.Server GetSmoServer(IManagedConnection mc)
{
SqlOlapConnectionInfoBase ci = mc.Connection;
if (ci == null)
{
throw new ArgumentNullException("ci");
}
SMO.Server server = null;
// see what type of connection we have been passed
SqlConnectionInfoWithConnection ciWithCon = ci as SqlConnectionInfoWithConnection;
if (ciWithCon != null)
{
server = new SMO.Server(ciWithCon.ServerConnection);
}
else
{
SqlConnectionInfo sqlCi = ci as SqlConnectionInfo;
if (sqlCi != null)
{
server = new SMO.Server(new ServerConnection(sqlCi));
}
}
if (server == null)
{
throw new InvalidOperationException();
}
return server;
}
public static int GetServerVersion(SMO.Server server)
{
return server.Information.Version.Major;
}
/// <summary>
/// validates current value of given numeric control. Shows message if the value is not valid
/// </summary>
/// <param name="numControl"></param>
/// <param name="errMessageToShow"></param>
/// <returns>true if control's value is valid, false otherwise</returns>
//public static bool ValidateNumeric(NumericUpDown numControl, string errMessageToShow, bool displayException)
//{
// try
// {
// int curValue = int.Parse(numControl.Text, System.Globalization.CultureInfo.CurrentCulture);
// if (curValue < numControl.Minimum || curValue > numControl.Maximum)
// {
// if (true == displayException)
// {
// ExceptionMessageBox box = new ExceptionMessageBox();
// box.Caption = SRError.SQLWorkbench;
// box.Message = new Exception(errMessageToShow);
// box.Symbol = ExceptionMessageBoxSymbol.Error;
// box.Buttons = ExceptionMessageBoxButtons.OK;
// box.Options = ExceptionMessageBoxOptions.RightAlign;
// box.Show(null);
// }
// try
// {
// numControl.Value = Convert.ToDecimal(numControl.Tag, System.Globalization.CultureInfo.CurrentCulture);
// numControl.Update();
// numControl.Text = Convert.ToString(numControl.Value, System.Globalization.CultureInfo.CurrentCulture);
// numControl.Refresh();
// }
// catch
// {
// }
// numControl.Focus();
// return false;
// }
// return true;
// }
// catch
// {
// if (true == displayException)
// {
// ExceptionMessageBox box = new ExceptionMessageBox();
// box.Caption = SRError.SQLWorkbench;
// box.Message = new Exception(errMessageToShow);
// box.Symbol = ExceptionMessageBoxSymbol.Error;
// box.Buttons = ExceptionMessageBoxButtons.OK;
// box.Options = ExceptionMessageBoxOptions.RightAlign;
// box.Show(null);
// }
// numControl.Focus();
// return false;
// }
//}
/// <summary>
/// Determines the oldest date based on the type of time units and the number of time units
/// </summary>
/// <param name="numUnits"></param>
/// <param name="typeUnits"></param>
/// <returns></returns>
public static DateTime GetOldestDate(int numUnits, TimeUnitType typeUnits)
{
DateTime result = DateTime.Now;
switch (typeUnits)
{
case TimeUnitType.Week:
{
result = (DateTime.Now).AddDays(-1 * 7 * numUnits);
break;
}
case TimeUnitType.Month:
{
result = (DateTime.Now).AddMonths(-1 * numUnits);
break;
}
case TimeUnitType.Year:
{
result = (DateTime.Now).AddYears(-1 * numUnits);
break;
}
default:
{
result = (DateTime.Now).AddDays(-1 * numUnits);
break;
}
}
return result;
}
public static string TokenizeXml(string s)
{
if (null == s) return String.Empty;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (char c in s)
{
switch (c)
{
case '<':
sb.Append("&lt;");
break;
case '>':
sb.Append("&gt;");
break;
case '&':
sb.Append("&amp;");
break;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
/// <summary>
/// Tries to get the SqlException out of an Enumerator exception
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static SqlException GetSqlException(Exception e)
{
SqlException sqlEx = null;
Exception exception = e;
while (exception != null)
{
sqlEx = exception as SqlException;
if (null != sqlEx)
{
break;
}
exception = exception.InnerException;
}
return sqlEx;
}
/// <summary>
/// computes the name of the machine based on server's name (as returned by smoServer.Name)
/// </summary>
/// <param name="sqlServerName">name of server ("",".","Server","Server\Instance",etc)</param>
/// <returns>name of the machine hosting sql server instance</returns>
public static string GetMachineName(string sqlServerName)
{
System.Diagnostics.Debug.Assert(sqlServerName != null);
string machineName = sqlServerName;
if (sqlServerName.Trim().Length != 0)
{
// [0] = machine, [1] = instance (if any)
return sqlServerName.Split('\\')[0];
}
else
{
// we have default instance of default machine
return machineName;
}
}
/// <summary>
/// Determines if a SqlException is Permission denied exception
/// </summary>
/// <param name="sqlException"></param>
/// <returns></returns>
public static bool IsPermissionDeniedException(SqlException sqlException)
{
bool isPermDenied = false;
if (null != sqlException.Errors)
{
foreach (SqlError sqlError in sqlException.Errors)
{
int errorNumber = GetSqlErrorNumber(sqlError);
if ((ObjectPermissionsDeniedErrorNumber == errorNumber) ||
(ColumnPermissionsDeniedErrorNumber == errorNumber))
{
isPermDenied = true;
break;
}
}
}
return isPermDenied;
}
/// <summary>
/// Returns the error number of a sql exeception
/// </summary>
/// <param name="sqlerror"></param>
/// <returns></returns>
public static int GetSqlErrorNumber(SqlError sqlerror)
{
return sqlerror.Number;
}
/// <summary>
/// Function doubles up specified character in a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String EscapeString(string s, char cEsc)
{
StringBuilder sb = new StringBuilder(s.Length * 2);
foreach (char c in s)
{
sb.Append(c);
if (cEsc == c)
sb.Append(c);
}
return sb.ToString();
}
/// <summary>
/// Function doubles up ']' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringCBracket(string s)
{
return CUtils.EscapeString(s, ']');
}
/// <summary>
/// Function doubles up '\'' character in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String EscapeStringSQuote(string s)
{
return CUtils.EscapeString(s, '\'');
}
/// <summary>
/// Function removes doubled up specified character from a string
/// </summary>
/// <param name="s"></param>
/// <param name="cEsc"></param>
/// <returns></returns>
public static String UnEscapeString(string s, char cEsc)
{
StringBuilder sb = new StringBuilder(s.Length);
bool foundBefore = false;
foreach (char c in s)
{
if (cEsc == c) // character to unescape
{
if (foundBefore) // skip second occurrence
{
foundBefore = false;
}
else // set the flag to skip next time around
{
sb.Append(c);
foundBefore = true;
}
}
else
{
sb.Append(c);
foundBefore = false;
}
}
return sb.ToString();
}
/// <summary>
/// Function removes doubled up ']' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringCBracket(string s)
{
return CUtils.UnEscapeString(s, ']');
}
/// <summary>
/// Function removes doubled up '\'' character from a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static String UnEscapeStringSQuote(string s)
{
return CUtils.UnEscapeString(s, '\'');
}
/// <summary>
/// Helper method to convert DMTF format to DateTime from WMI property value
/// ManagementDateTimeConverter.ToDateTime() does not adjust time to UTC offset,
/// hence additional step to adjust datetime.
/// </summary>
/// <param name="dateTimeInDMTFFormat"></param>
/// <returns></returns>
//public static DateTime GetDateTimeFromDMTFTime(string dateTimeInDMTFFormat)
//{
// string[] dateTimeInfo = dateTimeInDMTFFormat.Split(new char[] { '+', '-' });
// DateTime dateTime = ManagementDateTimeConverter.ToDateTime(dateTimeInDMTFFormat);
// TimeSpan timeSpan = TimeSpan.FromMinutes(Convert.ToDouble(dateTimeInfo[1]));
// if (dateTimeInDMTFFormat.Contains("+"))
// {
// dateTime = dateTime - timeSpan;
// }
// else
// {
// dateTime = dateTime + timeSpan;
// }
// return dateTime;
//}
/// <summary>
/// Helper method to sort ManagementObjectCollection based ArchiveNumber property
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
//public static ArrayList Sort(ManagementObjectCollection collection)
//{
// ArrayList array = new ArrayList();
// array.AddRange(collection);
// ArchiveNoComparer comparer = new ArchiveNoComparer();
// array.Sort(comparer);
// return array;
//}
/// <summary>
/// Helper function to execute WQL
/// </summary>
/// <param name="wmiNamespace"></param>
/// <param name="wql"></param>
/// <returns></returns>
//public static ManagementObjectCollection ExecuteWQL(WmiSqlMgmtConnectionInfo wmiCi, string wql)
//{
// ObjectQuery qry = new ObjectQuery(wql);
// ManagementScope scope = new ManagementScope(wmiCi.Namespace, wmiCi.ConnectionOptions);
// scope.Connect();
// ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, qry);
// return searcher.Get();
//}
/// <summary>
/// Get the windows login name with the domain portion in all-caps
/// </summary>
/// <param name="windowsLoginName">The windows login name</param>
/// <returns>The windows login name with the domain portion in all-caps</returns>
public static string CanonicalizeWindowsLoginName(string windowsLoginName)
{
string result;
int lastBackslashIndex = windowsLoginName.LastIndexOf("\\", StringComparison.Ordinal);
if (-1 != lastBackslashIndex)
{
string domainName = windowsLoginName.Substring(0, lastBackslashIndex).ToUpperInvariant();
string afterDomain = windowsLoginName.Substring(lastBackslashIndex);
result = String.Concat(domainName, afterDomain);
}
else
{
result = windowsLoginName;
}
return result;
}
/// <summary>
/// Launches object picker and gets the user selected login
/// </summary>
/// <param name="sender"></param>
/// <param name="server"></param>
/// <param name="errorMsgToShowForTooManyLogins"></param>
/// <returns>Returns null in case Object picker doesn't returns any loginName</returns>
//public static string GetWindowsLoginNameFromObjectPicker(object sender,
// Smo.Server server,
// string errorMsgToShowForTooManyLogins)
//{
// string loginName = null;
// ObjectPickerWrapper.TargetMachine = server.Information.NetName;
// ObjectPickerWrapper.SingleObjectSelection = true;
// ObjectPickerWrapper.GetUsersList(sender);
// int userCount = ObjectPickerWrapper.UsersList.Count;
// // if the user selected one NT login, set the edit control text to the selected login
// if (1 == userCount)
// {
// loginName = ObjectPickerWrapper.UsersList[0].ToString();
// if (loginName.Length != 0)
// {
// loginName = CanonicalizeWindowsLoginName(loginName);
// }
// }
// // if the user selected more than one login, display an error
// else if (1 < userCount)
// {
// SqlManagementUserControl sm = sender as SqlManagementUserControl;
// if (sm != null)
// {
// sm.DisplayExceptionMessage(new Exception(errorMsgToShowForTooManyLogins));
// }
// else
// {
// throw new InvalidOperationException(errorMsgToShowForTooManyLogins);
// }
// }
// return loginName;
//}
/// <summary>
/// Determines how a feature should behave (e.g. enabled or disabled) for a SQL instance's SKU/edition.
/// </summary>
/// <param name="server">A SMO Server object connected to a local or remote SQL instance</param>
/// <param name="setting">The setting to check (one of the feature constants used in settings.dat)</param>
/// <returns>The value of the setting (e.g. SqlbootConst.SKU_YES, SqlbootConst.VALUE_UNLIMITED, etc)</returns>
//public static uint QueryRemoteSqlProductValue(ServerConnection serverConnection, uint setting)
//{
// if (serverConnection == null)
// {
// throw new ArgumentNullException("serverConnection");
// }
// // The instance could be remote, so we use GetSettingValueForSKUAbsolute because it allows us to
// // query the client-side SQLBOOT.DLL to ask what the setting's value would be for the server's SKU.
// // (Most other SQLBOOT APIs can only be used for locally-installed instances.)
// // First we must retrieve the server's edition ID (SKU ID).
// int editionId = (int)serverConnection.ExecuteScalar("SELECT SERVERPROPERTY('EditionId') AS EditionId");
// // Then ask SQLBOOT what the setting's value should be for that SKU.
// uint value = Sqlboot.GetSettingValueForSKUAbsolute(setting, unchecked((uint)editionId));
// return value;
//}
}
/// <summary>
/// Enum of time units types ( used in cleaning up history based on age )
/// </summary>
internal enum TimeUnitType
{
Day,
Week,
Month,
Year
}
/// <summary>
/// class to sort files based on archivenumber
/// </summary>
//internal class ArchiveNoComparer : IComparer
//{
// public int Compare(Object x, Object y)
// {
// ManagementObject lhs = x as ManagementObject;
// ManagementObject rhs = y as ManagementObject;
// if (null == lhs || null == rhs)
// {
// throw new ArgumentException("Object is not of type ManagementObject");
// }
// UInt32 l = Convert.ToUInt32(lhs.Properties["archivenumber"].Value);
// UInt32 r = Convert.ToUInt32(rhs.Properties["archivenumber"].Value);
// int retVal = l.CompareTo(r);
// return retVal;
// }
//}
/// <summary>
/// Object used to populate default language in
/// database and user dialogs.
/// </summary>
internal class LanguageDisplay
{
private SMO.Language language;
public string LanguageAlias
{
get
{
return language.Alias;
}
}
public SMO.Language Language
{
get
{
return language;
}
}
public LanguageDisplay(SMO.Language language)
{
this.language = language;
}
public override string ToString()
{
return language.Alias;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,315 @@
//
// 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.SqlMgmt;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Diagnostics;
// using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database properties for SqlServer 2008
/// </summary>
[TypeConverter(typeof(DynamicValueTypeConverter))]
// [StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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")]
//TypeConverter(typeof(DatabaseScopedConfigurationOnOffTypes))]
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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", 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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", 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
}
}

View File

@@ -0,0 +1,232 @@
//
// 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.Drawing.Design;
using Microsoft.SqlServer.Management.Common;
// using Microsoft.SqlServer.Management.SqlMgmt;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
// using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database properties for SqlServer 2011
/// </summary>
[TypeConverter(typeof(DynamicValueTypeConverter))]
// [StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
internal class DatabasePrototype110 : DatabasePrototype100 //, ILanguageLcidWithConnectionInfo
{
/// <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();
}
}
//[
//// Editor(typeof(DefaultLanguageEditor), typeof(UITypeEditor)),
//Category("Category_ContainedDatabases"),
//DisplayNameAttribute("Property_DefaultLanguage")
//]
//public LanguageChoice DefaultLanguage
//{
// get
// {
// return LanguageUtils.GetLanguageChoiceAlias(this.context.Server,
// this.currentState.defaultLanguageLcid);
// }
// set
// {
// this.currentState.defaultLanguageLcid = value.lcid;
// 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.DefaultLanguage.Lcid != this.DefaultLanguage.lcid))
//{
// db.DefaultLanguage.Lcid = this.DefaultLanguage.lcid;
//}
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;
}
}
}
#region ILanguageLcidWithConnectionInfo Members
//int ILanguageLcidWithConnectionInfo.Lcid
//{
// get { return this.DefaultLanguage.lcid; }
//}
//ServerConnection ILanguageLcidWithConnectionInfo.Connection
//{
// get { return this.context.ServerConnection; }
//}
#endregion
}
}

View File

@@ -0,0 +1,285 @@
//
// 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.SqlMgmt;
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;
//using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database Prototype for SqlServer 2000 and later servers
/// </summary>
//[TypeConverter(typeof(DynamicValueTypeConverter))]
//[StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype80).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype80).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", 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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype80).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
}
}

View File

@@ -0,0 +1,39 @@
//
// 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.SqlMgmt;
using Microsoft.SqlServer.Management.Sdk.Sfc;
// using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database Prototype for SqlServer 2000 SP3 and later servers
/// </summary>
[TypeConverter(typeof(DynamicValueTypeConverter))]
//[StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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) { }
}
}

View File

@@ -0,0 +1,289 @@
//
// 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.SqlMgmt;
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;
// using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database Prototype for SqlServer 2005 and later servers
/// </summary>
//[TypeConverter(typeof(DynamicValueTypeConverter))]
//[StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype80).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype80).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype90).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype90).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.SqlServer.Management.SqlManagerUI.CreateDatabaseStrings", typeof(DatabasePrototype90).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
}
}

View File

@@ -0,0 +1,62 @@
//
// 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.SqlMgmt;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
// using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Database Prototype for SqlServer 2005 Enterprise SP2 and later servers
/// </summary>
[TypeConverter(typeof(DynamicValueTypeConverter))]
//[StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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;
}
}
}
}

View File

@@ -0,0 +1,393 @@
//
// 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 System.Windows.Forms;
//using Microsoft.SqlServer.Management.AzureSqlDbUtils;
//using Microsoft.SqlServer.Management.SqlMgmt;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Diagnostics;
using System.Globalization;
using System.Data.SqlClient;
//using DisplayNameAttribute = Microsoft.SqlServer.Management.SqlMgmt.DisplayNameAttribute;
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))]
//[StringResourceClass(typeof(Microsoft.SqlServer.Management.SqlManagerUI.CreateDatabaseOptionsSR))]
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
//private DesignableObject wrapper;
//[Browsable(false)]
//public DesignableObject Wrapper
//{
// get
// {
// return wrapper;
// }
// set
// {
// this.wrapper = value;
// //Now that we have a new wrapper make sure to update the dynamic visibility for the SLO options
// SetServiceLevelObjectiveOptionVisibility();
// }
//}
[Category(Category_Azure),
DisplayNameAttribute(Property_AzureMaxSize)]
//TypeConverter(typeof(DynamicValuesConverter))]
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)]
//TypeConverter(typeof(DynamicValuesConverter))]
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)]
// TypeConverter(typeof(DynamicValuesConverter))]
//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.SetServiceLevelObjectiveOptionVisibility();
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
/// <summary>
/// Sets the visibility of the SLO options based on the current configured Edition
/// </summary>
//private void SetServiceLevelObjectiveOptionVisibility()
//{
// if (this.wrapper == null)
// {
// return;
// }
// if (this.AzureEdition == AzureEdition.Business || this.AzureEdition == AzureEdition.Web)
// { //Business and Web editions don't support SLO so hide those options
// this.wrapper.SetupDynamicVisibility(Property_AzureCurrentServiceLevelObjective, false);
// this.wrapper.SetupDynamicVisibility(Property_AzureConfiguredServiceLevelObjective, false);
// }
// else
// { //Reset SLO options to visible in case they were hidden before
// this.wrapper.SetupDynamicVisibility(Property_AzureCurrentServiceLevelObjective, true);
// this.wrapper.SetupDynamicVisibility(Property_AzureConfiguredServiceLevelObjective, true);
// }
//}
#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(Control marshallingControl)
//{
// // For v12 Non-DW DBs lets use SMO
// if (this.ServerVersion.Major >= 12 && this.AzureEdition != AzureEdition.DataWarehouse)
// {
// return base.ApplyChanges(marshallingControl);
// }
// //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);
}
}
}

View File

@@ -0,0 +1,130 @@
//
// 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 void CreateDatabase(CDataContainer context)
{
InitializeDataMembers(context);
}
private void InitializeDataMembers(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();
//this.databasesCreated = new ArrayList();
}
else
{
this.DataContainer = null;
this.document = null;
this.prototype = null;
//this.databasesCreated = 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);
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);
}
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);
}
return databaseInfo;
}
}
}

View File

@@ -0,0 +1,173 @@
//
// 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.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Management.Common;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Helper class to describe the size of an Azure database
/// </summary>
public class DbSize
{
public enum SizeUnits
{
MB,
GB,
TB
}
#region Member Vars
private readonly int size;
private readonly SizeUnits sizeUnit;
#endregion
public DbSize(int size, SizeUnits sizeUnit)
{
this.size = size;
this.sizeUnit = sizeUnit;
}
/// <summary>
/// Copy constructor
/// </summary>
public DbSize(DbSize copy)
{
this.size = copy.Size;
this.sizeUnit = copy.SizeUnit;
}
/// <summary>
/// Size of the DB
/// </summary>
public int Size
{
get
{
return size;
}
}
/// <summary>
/// Units that the size is measured in
/// </summary>
public SizeUnits SizeUnit
{
get
{
return sizeUnit;
}
}
/// <summary>
/// Returns the number of bytes represented by the DbSize
/// </summary>
public double SizeInBytes
{
get
{
var sizeBase = Convert.ToDouble(this.size);
switch (SizeUnit)
{
case SizeUnits.MB:
return sizeBase*1024.0*1024.0;
case SizeUnits.GB:
return sizeBase*1024.0*1024.0*1024.0;
case SizeUnits.TB:
return sizeBase*1024.0*1024.0*1024.0*1024.0;
}
throw new InvalidOperationException("SR.UnknownSizeUnit(SizeUnit.ToString())");
}
}
#region Object Overrides
/// <summary>
/// Displays the size in the format ####UU (e.g. 100GB)
/// </summary>
/// <returns></returns>
public override string ToString()
{
return size + sizeUnit.ToString();
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return this == (DbSize)obj;
}
public override int GetHashCode()
{
return this.size.GetHashCode() ^ this.sizeUnit.GetHashCode();
}
#endregion Object Overrides
/// <summary>
/// Parses a string in the format ####UU into a DbSize object. The number of
/// numeric characters must be parseable into an int and the last two characters
/// mapped to one of the SizeUnits enum values.
/// </summary>
/// <param name="dbSizeString"></param>
/// <returns></returns>
public static DbSize ParseDbSize(string dbSizeString)
{
if (dbSizeString == null || dbSizeString.Length < 3)
{ //Sanity check
throw new ArgumentException("DbSize string must be at least 3 characters (#UU)");
}
int size;
//Try and parse all but the last two characters into the size
if (int.TryParse(dbSizeString.Substring(0, dbSizeString.Length - 2), out size))
{
//Get the unit portion (last two characters)
string unitPortion = dbSizeString.Substring(dbSizeString.Length - 2 );
SizeUnits unit;
if (Enum.TryParse(unitPortion, true, out unit))
{
return new DbSize(size, unit);
}
else
{
throw new ArgumentException("DbSize string does not contain a valid unit portion");
}
}
else
{
throw new ArgumentException("DbSize string does not contain a valid numeric portion");
}
}
public static bool operator ==(DbSize x, DbSize y)
{
if(ReferenceEquals(x, y))
{ //Both null or both same instance, are equal
return true;
}
if((object)x == null || (object)y == null)
{ //Only one null, never equal (cast to object to avoid infinite loop of ==)
return false;
}
return x.size == y.size && x.sizeUnit == y.sizeUnit;
}
public static bool operator !=(DbSize x, DbSize y)
{
return !(x == y);
}
}
}

View File

@@ -0,0 +1,12 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace System
{
internal interface ICloneable
{
object Clone();
}
}

View File

@@ -0,0 +1,198 @@
using System;
using System.Collections;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Diagnostics;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Provides connection and enumerator context for a node
/// </summary>
public interface IManagedConnection : IDisposable
{
/// <summary>
/// Connection information.
/// </summary>
SqlOlapConnectionInfoBase Connection
{
get;
}
/// <summary>
/// Free any resources for this connection
/// </summary>
void Close();
}
/// <summary>
/// interface used by the objectexplorer. Allows us to "pool" the main connection
/// </summary>
internal interface IManagedConnection2 : IManagedConnection
{
}
/// <summary>
/// Implementation of IManagedConnection. Allows the use of a direct or indirect connection
/// in the object explorer that takes care of the connection.
/// </summary>
internal class ManagedConnection : IManagedConnection2
{
#region private members
private bool connectionAddedToActiveConnections = false;
private bool closeOnDispose = false;
private SqlOlapConnectionInfoBase connection;
private bool closed = false;
#endregion
#region Construction
/// <summary>
/// Create a new managed connection
/// </summary>
/// <param name="connection">connection wish to manage</param>
public ManagedConnection(SqlOlapConnectionInfoBase connection)
: this(connection, false)
{
}
/// <summary>
/// create a new managed connection.
/// </summary>
/// <param name="connection">connection</param>
/// <param name="attemptToPool">true if we are going to try and reuse the
/// connection if possible</param>
public ManagedConnection(SqlOlapConnectionInfoBase sourceConnection, bool attemptToPool)
{
// parameter check
if (sourceConnection == null)
{
throw new ArgumentNullException("sourceConnection");
}
// see if the connection can restrict access (single user mode)
IRestrictedAccess access = sourceConnection as IRestrictedAccess;
// see if it is cloneable
ICloneable cloneable = sourceConnection as ICloneable;
lock (ActiveConnections)
{
// if it's not single user mode then we can see if the object can be cloned
if (access == null || access.SingleConnection == false)
{
// if we are going to attempt to pool, see if the connection is in use
if (attemptToPool && !ActiveConnections.Contains(SharedConnectionUtil.GetConnectionKeyName(sourceConnection)))
{
// add it to the hashtable to indicate use.
ActiveConnections.Add(SharedConnectionUtil.GetConnectionKeyName(sourceConnection), sourceConnection);
this.connection = sourceConnection;
this.closeOnDispose = false;
this.connectionAddedToActiveConnections = true;
}
else if (cloneable != null)
{
this.connection = (SqlOlapConnectionInfoBase)cloneable.Clone();
this.closeOnDispose = true;
}
else if (sourceConnection is SqlConnectionInfoWithConnection)
{
this.connection = ((SqlConnectionInfoWithConnection)sourceConnection).Copy();
this.closeOnDispose = true;
}
}
}
// if everything else has failed just use to passed in connection.
if (this.connection == null)
{
this.connection = sourceConnection;
}
// always set the lock timeout to prevent the shell from not responding
if (this.connection is SqlConnectionInfoWithConnection)
{
// set lock_timeout to 10 seconds
((SqlConnectionInfoWithConnection)this.connection).ServerConnection.LockTimeout = 10;
}
}
#endregion
#region IDisposable implementation
public void Dispose()
{
Close();
}
#endregion
#region IManagedConnection implementation
/// <summary>
/// Connection
/// </summary>
public SqlOlapConnectionInfoBase Connection
{
get
{
return this.connection;
}
}
/// <summary>
/// Close the current connection if applicable.
/// </summary>
public void Close()
{
if (this.closed)
return;
if (this.closeOnDispose)
{
IDisposable disp = this.connection as IDisposable;
if (disp != null)
{
disp.Dispose();
}
}
else
{
// if we are not closing the connection and it is a sql connection then ensure it
// is left in the master database.
SqlConnectionInfoWithConnection sqlConnection = this.connection as SqlConnectionInfoWithConnection;
if (sqlConnection != null && sqlConnection.ServerConnection.DatabaseEngineType == DatabaseEngineType.Standalone)
{
try
{
sqlConnection.ServerConnection.ExecuteNonQuery("use [master]");
}
// don't error if this fails
catch
{ }
}
}
if (this.connectionAddedToActiveConnections)
{
lock (ActiveConnections)
{
ActiveConnections.Remove(SharedConnectionUtil.GetConnectionKeyName(connection));
}
}
this.connection = null;
this.closed = true;
}
#endregion
#region static helpers
/// <summary>
/// hashtable we use to keep track of actively used main connections
/// </summary>
private static Hashtable activeConnections = null;
private Hashtable ActiveConnections
{
get
{
if (activeConnections == null)
{
activeConnections = new Hashtable();
}
return activeConnections;
}
}
#endregion
}
}

View File

@@ -0,0 +1,31 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// To access DataModelingSandbox from NavigableItem
/// </summary>
public interface ISandboxLoader
{
/// <summary>
/// Get sandbox
/// </summary>
/// <returns>DataModelingSandbox object associated with this NavigableItem</returns>
object GetSandbox();
/// <summary>
/// Refresh sandbox data associated with this NavigableItem
/// </summary>
void RefreshSandboxData();
/// <summary>
/// Delete sandbox from cache
/// </summary>
void DeleteSandbox();
}
}

View File

@@ -0,0 +1,488 @@
//
// 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.Xml;
using System.Collections;
using System.Diagnostics;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// SqlTools Parameters, used to define what goes into starting up a Workbench Form
/// AKA a dbCommander, AKA a "dialog"
/// These parameters are xml snippets
/// </summary>
public class STParameters
{
public XmlDocument m_doc;
/// <summary>
/// The data type we are interested in
/// </summary>
public enum STType { eNULL, eInt, eLong, eString };
/// <summary>
/// default constructor
/// </summary>
public STParameters()
{
//
// TODO: Add constructor logic here
//
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="xmlDoc">The xml snippet used to control the dbCommander</param>
public STParameters(XmlDocument xmlDoc)
{
m_doc = xmlDoc;
}
/// <summary>
/// Changing the xml snippet we are using
/// </summary>
/// <param name="xmlDoc">the new xml snippet</param>
public void SetDocument(XmlDocument xmlDoc)
{
m_doc = xmlDoc;
}
/// <summary>
/// Access to the xml we are using for dbCommander parameters
/// </summary>
/// <returns>our current parameters</returns>
public XmlDocument GetDocument()
{
return m_doc;
}
/// <summary>
/// Search for an xml tag, and return its value
/// </summary>
/// <param name="parameterName">the xml tag name</param>
/// <param name="value">the value of that tag</param>
/// <returns>flag that is true if the data was found, false if not</returns>
public bool GetBaseParam(string parameterName, ref object value)
{
XmlNodeList nodeList = null;
bool parameterExists;
if (m_doc == null)
return false;
parameterExists = false;
nodeList = m_doc.GetElementsByTagName(parameterName);
if (nodeList.Count > 1)
{
value = null;
}
else if (nodeList.Count != 0) // anything there?
{
try
{
XmlNode node = nodeList.Item(0);
if (null != node)
{
value = node.InnerText as object;
parameterExists = true;
}
}
catch (Exception /*e*/)
{
}
}
return parameterExists;
}
/// <summary>
/// Finds an existing xml tag, and sets it to a new value, or if the tag is not found
/// create it and set it's value
/// </summary>
/// <param name="parameterName">tag name</param>
/// <param name="value">new value</param>
/// <returns>flag that is true if the tag was set, false if not</returns>
public bool SetBaseParam(string parameterName, object value)
{
XmlNodeList nodeList;
bool success = false;
nodeList = m_doc.GetElementsByTagName(parameterName);
if (nodeList.Count == 1)
{
try
{
nodeList.Item(0).InnerText = (string)value;
success = true;
}
catch (InvalidCastException /*e*/)
{
success = false;
}
}
if (nodeList.Count == 0)
{
try
{
XmlElement xmlElement = m_doc.CreateElement(parameterName);
XmlNode root = m_doc.DocumentElement;
nodeList = m_doc.GetElementsByTagName("params");
if (nodeList.Count == 1 && value is string)
{
xmlElement.InnerText = (string)value;
nodeList.Item(0).InsertAfter(xmlElement, nodeList.Item(0).LastChild);
success = true;
}
}
catch (Exception e)
{
string sz = e.ToString();
success = false;
}
}
return success;
}
/// <summary>
/// Get back an interger parameter.
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
/// An exception of type 'System.FormatException'
/// with Additional information: Could not find any parsible digits.
/// </summary>
/// <param name="parameterName">xml tag name for the parameter of interest</param>
/// <param name="iValue">out value of parameter</param>
/// <returns>flag that is true if the data was found, false if not</returns>
public bool GetParam(string parameterName, out int value)
{
bool parameterExists = false;
value = 0;
try
{
object oAux = null;
if (parameterExists = GetBaseParam(parameterName, ref oAux))
{
try
{
value = Convert.ToInt32((string)oAux, 10); // data is always a string, it is the value of XmlNode.InnerText
}
catch (FormatException e)
{
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non numeric data in tag: {0}", parameterName));
Debug.WriteLine(e.Message);
throw;
}
}
}
catch (InvalidCastException /*e*/)
{
}
return parameterExists;
}
/// <summary>
/// Accessor for a boolean parameter
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
/// An exception of type 'System.FormatException'
/// with Additional information: Could not find any parsible digits.
/// </summary>
/// <param name="parameterName">xml tag name for the parameter of interest</param>
/// <param name="value">out value of parameter</param>
/// <returns>flag that is true if the data was found, false if not</returns>
public bool GetParam(string parameterName, ref bool value)
{
bool parameterExists = false;
value = false;
try
{
object oAux = null;
if (parameterExists = GetBaseParam(parameterName, ref oAux))
{
try
{
value = Convert.ToBoolean((string)oAux, System.Globalization.CultureInfo.InvariantCulture); // data is always a string, it is the value of XmlNode.InnerText
}
catch (FormatException e)
{
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non boolean data in tag: {0}", parameterName));
Debug.WriteLine(e.Message);
throw;
}
}
}
catch (InvalidCastException /*e*/)
{
}
return parameterExists;
}
/// <summary>
/// Accessor to a string parameter
/// </summary>
/// <param name="parameterName">xml tag name for the parameter of interest</param>
/// <param name="value">out value of parameter</param>
/// <returns>flag that is true if the data was found, false if not</returns>
public bool GetParam(string parameterName, ref string value)
{
bool parameterExists;
value = "";
parameterExists = false;
try
{
object oAux = null;
if (parameterExists = GetBaseParam(parameterName, ref oAux))
{
value = (string)oAux;
}
}
catch (InvalidCastException /*e*/)
{
}
return parameterExists;
}
/// <summary>
/// Accessor to long parameter (Int64)
/// NOTE: if the tag exists, but it contains non-numeric data, this will throw
/// An exception of type 'System.FormatException'
/// with Additional information: Could not find any parsible digits.
/// </summary>
/// <param name="parameterName">xml tag name for the parameter of interest</param>
/// <param name="value">out value of parameter</param>
/// <returns>flag that is true if the data was found, false if not</returns>
public bool GetParam(string parameterName, out long value)
{
bool parameterExists = false;
value = 0;
try
{
object oAux = null;
if (parameterExists = GetBaseParam(parameterName, ref oAux))
{
try
{
value = Convert.ToInt64((string)oAux, 10); // data is always a string, it is the value of XmlNode.InnerText
}
catch (FormatException e)
{
Debug.WriteLine(String.Format(System.Globalization.CultureInfo.CurrentCulture, "Non numeric data in tag: {0}", parameterName));
Debug.WriteLine(e.Message);
throw;
}
}
}
catch (InvalidCastException /*e*/)
{
}
return parameterExists;
}
/// <summary>
/// Set an int (Int32) parameter
/// </summary>
/// <param name="parameterName">tag name for parameter</param>
/// <param name="value">integer value</param>
/// <returns>true if set was successful, false if not</returns>
public bool SetParam(string parameterName, int value)
{
bool success;
success = SetBaseParam(parameterName, (object)value);
return success;
}
/// <summary>
/// Set a string parameter
/// </summary>
/// <param name="parameterName">tag name for parameter</param>
/// <param name="value">string value</param>
/// <returns>true if set was successful, false if not</returns>
public bool SetParam(string parameterName, string value)
{
bool success;
success = SetBaseParam(parameterName, (object)value);
return success;
}
/// <summary>
/// Set a long (Int64) parameter
/// </summary>
/// <param name="parameterName">tag name for parameter</param>
/// <param name="value">long value</param>
/// <returns>true if set was successful, false if not</returns>
public bool SetParam(string parameterName, long value)
{
bool success;
success = SetBaseParam(parameterName, (object)value);
return success;
}
/// <summary>
/// Get a string collection parameter
/// </summary>
/// <param name="parameterName">name of collection</param>
/// <param name="list">collection that gets filled up with parameters</param>
/// <param name="getInnerXml">true if we want to get at inner nodes, false if not</param>
/// <returns>true if parameter(s) exist</returns>
public bool GetParam(string parameterName, System.Collections.Specialized.StringCollection list, bool getInnerXml)
{
/// necessary for OALP objects path that is in an XML form
if (true == getInnerXml)
{
XmlNodeList nodeList;
bool parameterExists;
long lCount;
parameterExists = false;
nodeList = m_doc.GetElementsByTagName(parameterName);
list.Clear();
lCount = nodeList.Count;
if (lCount > 0)
{
parameterExists = true;
for (long i = 0; i < lCount; i++)
{
list.Add(nodeList.Item((int)i).InnerXml);
}
}
else
{
parameterExists = false;
}
return parameterExists;
}
else
{
return GetParam(parameterName, list);
}
}
/// <summary>
/// Access to a collection of parameters
/// </summary>
/// <param name="parameterName">name of collection</param>
/// <param name="list">list to fill with parameters</param>
/// <returns>parameter(s) exist</returns>
public bool GetParam(string parameterName, System.Collections.Specialized.StringCollection list)
{
XmlNodeList nodeList;
bool parameterExists;
long lCount;
parameterExists = false;
nodeList = m_doc.GetElementsByTagName(parameterName);
list.Clear();
lCount = nodeList.Count;
if (lCount > 0)
{
parameterExists = true;
for (long i = 0; i < lCount; i++)
{
list.Add(nodeList.Item((int)i).InnerText);
}
}
else
{
parameterExists = false;
}
return parameterExists;
}
public bool GetParam(string parameterName, ref ArrayList list)
{
System.Collections.Specialized.StringCollection stringList = new System.Collections.Specialized.StringCollection();
bool parameterExists = GetParam(parameterName, stringList);
list.Clear();
if (!parameterExists)
{
return false;
}
else
{
for (int i = 0; i < stringList.Count; i++)
{
list.Add(stringList[i]);
}
return true;
}
}
/// <summary>
/// This function does nothing but return false
/// </summary>
/// <param name="parameterName">ignored</param>
/// <param name="type">ignored</param>
/// <returns>always false</returns>
public bool GetParamType(string parameterName, STType type)
{
bool whatever = false;
return whatever;
}
/// <summary>
/// This function does nothing but return false
/// </summary>
/// <param name="parameterName">ignored</param>
/// <param name="type">ignored</param>
/// <returns>always false</returns>
public bool SetParamType(string parameterName, STType type)
{
bool whatever = false;
return whatever;
}
}
}

View File

@@ -0,0 +1,108 @@
//
// 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 Microsoft.SqlServer.Management.AzureCredential;
using Microsoft.SqlServer.Management.Common;
//using Microsoft.SqlServer.Management.Smo.RegSvrEnum;
using SFC = Microsoft.SqlServer.Management.Sdk.Sfc;
//using Microsoft.SqlServer.StorageClient;
//using Microsoft.SqlServer.Management.SqlMgmt;
/// <summary>
/// Summary description for SharedConectionUtil
/// Moved GetConnectionName static call in a public class acessible for both
/// OEXM and OE
/// </summary>
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
internal class SharedConnectionUtil
{
public SharedConnectionUtil()
{
}
/// <summary>
///
/// </summary>
/// <param name="ci"></param>
/// <returns></returns>
public static string GetConnectionKeyName(SqlOlapConnectionInfoBase ci)
{
//// Note that these strings are not localized. The returned string is used by OE in a
//// hash of connections so it can tell if it already has such a connection open. This
//// string is never seen by the user. For the string seen by the user, see
//// ServerNameHandler.cs.
string displayName = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0} (", ci.ServerName);
if (!string.IsNullOrEmpty(ci.DatabaseName))
{
displayName += ", " + ci.DatabaseName;
}
return displayName;
//switch (ci.ServerType)
//{
// case ConnectionType.AzureStorage:
// AzureStorageConnectionInfo azureCI = ci as AzureStorageConnectionInfo;
// displayName = "AzureStorage," + azureCI.BlobClient.BaseUri;
// break;
// case ConnectionType.AzureAccount:
// if (ci is CertificateBasedAuthenticationInfo)
// {
// displayName = "AzureSubscription," + (ci as CertificateBasedAuthenticationInfo).SubscriptionId;
// }
// else
// {
// displayName = "AzureSubscription";
// }
// break;
// case ConnectionType.Sql:
// displayName += "SQLServer";
// SqlConnectionInfo sqlCi = ci as SqlConnectionInfo;
// if (sqlCi.UseIntegratedSecurity == true)
// {
// displayName += ", trusted";
// }
// else
// {
// displayName += String.Format(System.Globalization.CultureInfo.InvariantCulture, ", user = {0}", sqlCi.UserName);
// //In Cloud a user can have access to only a few UDBs without access to master DB
// // and hence need to show different OE hierarchy trees for each DB
// //Same is the case with a contained user.
// if (ServerInfoCache.GetDatabaseEngineType(ci.ServerName) == DatabaseEngineType.SqlAzureDatabase
// || SFC.ExecuteSql.GetDatabaseEngineType(ci) == DatabaseEngineType.SqlAzureDatabase
// || SFC.ExecuteSql.IsContainedAuthentication(ci))
// {
// if (!string.IsNullOrEmpty(ci.DatabaseName))
// {
// displayName += ", " + ci.DatabaseName;
// }
// }
// }
// break;
// case ConnectionType.Olap:
// displayName += "OLAP";
// break;
// case ConnectionType.SqlCE:
// displayName += "SqlCE";
// break;
// case ConnectionType.ReportServer:
// displayName += "Rs";
// displayName += String.Format(System.Globalization.CultureInfo.InvariantCulture, ", connection = {0}", ci.ConnectionString);
// break;
// case ConnectionType.IntegrationServer:
// displayName += "SSIS";
// break;
//}
//displayName += ")";
//return displayName;
}
}
}

View File

@@ -0,0 +1,410 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
//extern alias VSShell2;
//extern alias VSShell2Iop;
using System;
using System.Reflection;
using System.Globalization;
using Microsoft.SqlServer.Management.Diagnostics;
using SMO = Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
//using VSShell2Iop.Microsoft.VisualStudio.Shell.Interop;
//using VSShell2.Microsoft.VisualStudio.Shell;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
/// <summary>
/// Internal reusable helpers
/// </summary>
internal class Utils
{
/// <summary>
/// only static methods
/// </summary>
private Utils() { }
/// <summary>
/// returns all instances of the given custom attribute on a given object
/// </summary>
/// <param name="objectToGetAttributeFrom"></param>
/// <param name="customAttribute"></param>
/// <returns></returns>
public static Attribute GetCustomAttribute(object objectToGetAttributeFrom, Type customAttribute)
{
//first, see if the object implemented this interface to override standard behavior
System.Reflection.ICustomAttributeProvider attribProvider = objectToGetAttributeFrom as System.Reflection.ICustomAttributeProvider;
if (attribProvider == null)
{
//if not, get it from its type
attribProvider = (System.Reflection.ICustomAttributeProvider)objectToGetAttributeFrom.GetType();
}
object[] attribs = attribProvider.GetCustomAttributes(customAttribute, true);
if (attribs != null && attribs.Length > 0)
{
//NOTE: important that we'll always use the first one in collection.
//Our implementation of ICustomAttributeProvider knows about that and
//relies on this behavior
return attribs[0] as Attribute;
}
return null;
}
/// <summary>
/// called to create SqlConnectionInfo out of the given CDataContainer object
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static SqlConnectionInfo GetSqlConnectionInfoFromDataContainer(CDataContainer dc)
{
if (dc != null)
{
// we may have been given conneciton information by the object explorer. in which case there is no need
// to build it ourselves.
SqlConnectionInfo result = dc.ConnectionInfo as SqlConnectionInfo;
if (result == null)
{
throw new InvalidOperationException();
}
return result;
}
else
{
return null;
}
}
public static int InitialTreeViewWidth
{
get
{
return 175;
}
}
/// <summary>
/// Try to set the CLR thread name.
/// Will not throw if the name is already set.
/// </summary>
/// <param name="name"></param>
public static void TrySetThreadName(String name)
{
try
{
System.Threading.Thread.CurrentThread.Name = name;
}
catch (InvalidOperationException)
{ }
}
public static bool IsKatmaiOrLater(int version)
{
return (10 <= version);
}
public static bool IsKjOrLater(ServerVersion version)
{
return (version.Major > 10
|| (version.Major == 10 && version.Minor >= 50));
}
public static bool IsSql11OrLater(ServerVersion version)
{
return IsSql11OrLater(version.Major);
}
public static bool IsSql11OrLater(int versionMajor)
{
return (versionMajor >= 11);
}
public static bool IsSql12OrLater(ServerVersion version)
{
return IsSql12OrLater(version.Major);
}
public static bool IsSql12OrLater(int versionMajor)
{
return (versionMajor >= 12);
}
public static bool IsSql13OrLater(ServerVersion version)
{
return IsSql13OrLater(version.Major);
}
public static bool IsSql13OrLater(int versionMajor)
{
return (versionMajor >= 13);
}
public static bool IsSql14OrLater(ServerVersion version)
{
return IsSql14OrLater(version.Major);
}
public static bool IsSql14OrLater(int versionMajor)
{
return (versionMajor >= 14);
}
/// <summary>
/// Check if the version is SQL 2016 SP1 or later.
/// </summary>
/// <param name="version"></param>
/// <returns>true if the version is SQL 2016 SP1 or later, false otherwise</returns>
public static bool IsSql13SP1OrLater(Version version)
{
return (version >= new Version(13, 0, 3510));
}
public static bool IsXTPSupportedOnServer(SMO.Server server)
{
bool isXTPSupported = false;
if (server.ConnectionContext.ExecuteScalar("SELECT SERVERPROPERTY('IsXTPSupported')") != DBNull.Value)
{
isXTPSupported = server.IsXTPSupported;
}
return isXTPSupported;
}
/// <summary>
/// Returns true if given database has memory optimized filegroup on given server.
/// </summary>
/// <param name="server"></param>
/// <param name="dbName"></param>
/// <returns></returns>
public static bool HasMemoryOptimizedFileGroup(SMO.Server server, string dbName)
{
bool hasMemoryOptimizedFileGroup = false;
if (server.ServerType != DatabaseEngineType.SqlAzureDatabase)
{
string query = string.Format(CultureInfo.InvariantCulture,
"select top 1 1 from [{0}].sys.filegroups where type = 'FX'",
CUtils.EscapeString(dbName, ']'));
if (server.ConnectionContext.ExecuteScalar(query) != null)
{
hasMemoryOptimizedFileGroup = true;
}
}
return hasMemoryOptimizedFileGroup;
}
public static bool IsPolybasedInstalledOnServer(SMO.Server server)
{
bool isPolybaseInstalled = false;
if (server.IsSupportedProperty("IsPolyBaseInstalled"))
{
isPolybaseInstalled = server.IsPolyBaseInstalled;
}
return isPolybaseInstalled;
}
/// <summary>
/// Returns true if current user has given permission on given server.
/// </summary>
/// <param name="server"></param>
/// <param name="permissionName"></param>
/// <returns></returns>
public static bool HasPermissionOnServer(SMO.Server server, string permissionName)
{
return Convert.ToBoolean(server.ConnectionContext.ExecuteScalar(
string.Format(CultureInfo.InvariantCulture,
"SELECT HAS_PERMS_BY_NAME(null, null, '{0}');",
permissionName)));
}
public static bool FilestreamEnabled(SMO.Server svr)
{
bool result = false;
if (svr != null)
{
if (IsKatmaiOrLater(svr.Information.Version.Major)
&& svr.ServerType != DatabaseEngineType.SqlAzureDatabase) //Azure doesn't support filestream
{
if (svr.Configuration.FilestreamAccessLevel.RunValue != 0)
{
result = true;
}
}
}
return result;
}
/// <summary>
/// This function returns true if SSMS is the running application
/// and if it contains only the core relational packages.
/// </summary>
/// <returns></returns>
//public static bool IsSsmsMinimalSet()
//{
// IVsShell vsShell = Package.GetGlobalService(typeof(SVsShell)) as IVsShell;
// const string guidSqlStudioPkgString = "04401ff3-8b0f-4d2d-85eb-2a3542867a8b";
// Guid guidSqlStudioPkg = new Guid(guidSqlStudioPkgString);
// //Applications like 'AS Migration wizard' are non-ssms/non-VS shell applications
// if (vsShell == null)
// {
// return false;
// }
// else
// {
// IVsPackage ssmsPackage;
// vsShell.IsPackageLoaded(ref guidSqlStudioPkg, out ssmsPackage);
// return ((ssmsPackage != null) &&
// !AreExtendedFeaturesAvailable());
// }
//}
/// <summary>
/// This function checks if extended SSMS packages are loaded
///
/// </summary>
/// <returns></returns>
//public static bool AreExtendedFeaturesAvailable()
//{
// return Microsoft.SqlServer.Management.UI.VSIntegration.SsmsInformation.CanShowNonExpressFeatures;
//}
/// <summary>
/// Execute a static method by reflection
/// </summary>
/// <param name="assemblyShortName">The short name of the assembly, like Microsoft.SqlServer.Management.RegisteredServersUI.dll</param>
/// <param name="className">The fully qualified name of the class, like Microsoft.SqlServer.Management.RegisteredServers.Utils</param>
/// <param name="methodName">THe name of the static method to call, like DoSomething</param>
/// <param name="parameters">params array of arguments to pass to the method</param>
/// <returns></returns>
//public static object ReflectionExecuteStatic(
// string assemblyShortName,
// string className,
// string methodName,
// params object[] parameters)
//{
// STrace.Params(
// SqlMgmtDiag.TName,
// "Utils.ReflectionExecuteStatic(string, string, string, object[])",
// "assemblyShortName='{0}', className='{1}', methodName='{2}'",
// assemblyShortName,
// className,
// methodName);
// Assembly assembly = Assembly.Load(
// Microsoft.SqlServer.Management.SqlMgmt.AssemblyLoadUtil.GetFullAssemblyName(assemblyShortName));
// if (assembly == null)
// {
// STrace.LogExThrow();
// throw new ArgumentException("Couldn't load assembly by reflection");
// }
// Type type = assembly.GetType(className);
// if (type == null)
// {
// STrace.LogExThrow();
// throw new ArgumentException("Couldn't find class by reflection");
// }
// // if we need to call a polymorphic method, use type.GetMethod(string, BindingFlags, null, Type[], null)
// MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
// if (method == null)
// {
// STrace.LogExThrow();
// throw new ArgumentException("Couldn't find method by reflection");
// }
// return method.Invoke(null, parameters);
//}
public static bool IsYukonOrAbove(SMO.Server server)
{
return server.Version.Major >= 9;
}
public static bool IsBelowYukon(SMO.Server server)
{
return server.Version.Major < 9;
}
/// <summary>
/// Some calendars, such as the UmAlQuraCalendar, support an upper date range that is earlier than MaxValue.
/// In these cases, trying to access MaxValue in variable assignments or formatting and parsing operations can throw
/// an ArgumentOutOfRangeException. Rather than retrieving the value of DateTime.MaxValue, you can retrieve the value
/// of the specified culture's latest valid date value from the
/// System.Globalization.CultureInfo.DateTimeFormat.Calendar.MaxSupportedDateTime property.
/// http://msdn.microsoft.com/en-us/library/system.datetime.maxvalue(v=VS.90).aspx
/// </summary>
/// <returns></returns>
//public static DateTime GetMaxCultureDateTime()
//{
// CultureInfo currentCulture = System.Threading.Thread.CurrentThread.CU;
// return currentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime;
//}
public static string MakeSqlBracket(string s)
{
return "[" + s.Replace("]", "]]") + "]";
}
/// <summary>
/// Displays F1 Help link
/// </summary>
/// <param name="serviceProvider">Service provider to display help</param>
/// <param name="dialogF1Keyword">F1 help link</param>
//public static void DisplayHelp(IServiceProvider serviceProvider, string dialogF1Keyword)
//{
// if (serviceProvider == null)
// {
// return;
// }
// IHelpService helpService = (IHelpService)serviceProvider.GetService(typeof(IHelpService));
// if (helpService == null)
// {
// IHelpProvider helpProvider = (IHelpProvider)serviceProvider.GetService(typeof(IHelpProvider));
// if (helpProvider != null)
// {
// helpProvider.DisplayTopicFromF1Keyword(dialogF1Keyword);
// }
// }
// else
// {
// helpService.DisplayHelp(dialogF1Keyword);
// }
//}
}
/// <summary>
/// Public reusable helpers
/// </summary>
public class SqlMgmtUtils
{
/// <summary>
/// only static methods
/// </summary>
private SqlMgmtUtils() { }
/// <summary>
/// Returns whether the server is in AS Azure
/// </summary>
/// <param name="serverName"></param>
/// <returns></returns>
public static bool IsASAzure(string serverName)
{
return !string.IsNullOrEmpty(serverName) && serverName.StartsWith("asazure://", StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@@ -4,10 +4,6 @@
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.Admin.Contracts
{

View File

@@ -3,10 +3,24 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Admin.Contracts
{
public class DatabaseInfo
{
public string Name { get; set; }
/// <summary>
/// Gets or sets the options
/// </summary>
public Dictionary<string, object> Options { get; set; }
public DatabaseInfo()
{
Options = new Dictionary<string, object>();
}
}
}

View File

@@ -0,0 +1,28 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.Admin.Contracts
{
public class DefaultDatabaseInfoParams
{
public string OwnerUri { get; set; }
}
public class DefaultDatabaseInfoResponse
{
public DatabaseInfo DefaultDatabaseInfo { get; set; }
}
public class DefaultDatabaseInfoRequest
{
public static readonly
RequestType<DefaultDatabaseInfoParams, DefaultDatabaseInfoResponse> Type =
RequestType<DefaultDatabaseInfoParams, DefaultDatabaseInfoResponse>.Create("admin/defaultdatabaseinfo");
}
}

View File

@@ -0,0 +1,300 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.Connection
{
/// <summary>
/// Helper class for providing metadata about connection options
/// </summary>
internal class ConnectionProviderOptionsHelper
{
internal static ConnectionProviderOptions BuildConnectionProviderOptions()
{
return new ConnectionProviderOptions
{
Options = new ConnectionOption[]
{
new ConnectionOption
{
Name = "server",
DisplayName = "Server Name",
Description = "Name of the SQL Server instance",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueServerName,
IsIdentity = true,
IsRequired = true,
GroupName = "Source"
},
new ConnectionOption
{
Name = "database",
DisplayName = "Database Name",
Description = "The name of the initial catalog or database int the data source",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueDatabaseName,
IsIdentity = true,
IsRequired = false,
GroupName = "Source"
},
new ConnectionOption
{
Name = "authenticationType",
DisplayName = "Authentication Type",
Description = "Specifies the method of authenticating with SQL Server",
ValueType = ConnectionOption.ValueTypeCategory,
SpecialValueType = ConnectionOption.SpecialValueAuthType,
CategoryValues = new CategoryValue[]
{ new CategoryValue {DisplayName = "SQL Login", Name = "SqlLogin" },
new CategoryValue {DisplayName = "Integrated Auth", Name= "Integrated" }
},
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "user",
DisplayName = "User Name",
Description = "Indicates the user ID to be used when connecting to the data source",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueUserName,
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "password",
DisplayName = "Password",
Description = "Indicates the password to be used when connecting to the data source",
ValueType = ConnectionOption.ValueTypePassword,
SpecialValueType = ConnectionOption.SpecialValuePasswordName,
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "applicationIntent",
DisplayName = "Application Intent",
Description = "Declares the application workload type when connecting to a server",
ValueType = ConnectionOption.ValueTypeCategory,
CategoryValues = new CategoryValue[] {
new CategoryValue { Name = "ReadWrite", DisplayName = "ReadWrite" },
new CategoryValue {Name = "ReadOnly", DisplayName = "ReadOnly" }
},
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "asynchronousProcessing",
DisplayName = "Asynchronous processing enabled",
Description = "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "connectTimeout",
DisplayName = "Connect Timeout",
Description =
"The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "15",
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "currentLanguage",
DisplayName = "Current Language",
Description = "The SQL Server language record name",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "columnEncryptionSetting",
DisplayName = "Column Encryption Setting",
Description = "Default column encryption setting for all the commands on the connection",
ValueType = ConnectionOption.ValueTypeCategory,
GroupName = "Security",
CategoryValues = new CategoryValue[] {
new CategoryValue { Name = "Disabled" },
new CategoryValue {Name = "Enabled" }
}
},
new ConnectionOption
{
Name = "encrypt",
DisplayName = "Encrypt",
Description =
"When true, SQL Server uses SSL encryption for all data sent between the client and server if the servers has a certificate installed",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "persistSecurityInfo",
DisplayName = "Persist Security Info",
Description = "When false, security-sensitive information, such as the password, is not returned as part of the connection",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "trustServerCertificate",
DisplayName = "Trust Server Certificate",
Description = "When true (and encrypt=true), SQL Server uses SSL encryption for all data sent between the client and server without validating the server certificate",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "attachedDBFileName",
DisplayName = "Attached DB File Name",
Description = "The name of the primary file, including the full path name, of an attachable database",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Source"
},
new ConnectionOption
{
Name = "contextConnection",
DisplayName = "Context Connection",
Description = "When true, indicates the connection should be from the SQL server context. Available only when running in the SQL Server process",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Source"
},
new ConnectionOption
{
Name = "port",
DisplayName = "Port",
ValueType = ConnectionOption.ValueTypeNumber
},
new ConnectionOption
{
Name = "connectRetryCount",
DisplayName = "Connect Retry Count",
Description = "Number of attempts to restore connection",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "1",
GroupName = "Connection Resiliency"
},
new ConnectionOption
{
Name = "connectRetryInterval",
DisplayName = "Connect Retry Interval",
Description = "Delay between attempts to restore connection",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "10",
GroupName = "Connection Resiliency"
},
new ConnectionOption
{
Name = "applicationName",
DisplayName = "Application Name",
Description = "The name of the application",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Context"
},
new ConnectionOption
{
Name = "workstationId",
DisplayName = "Workstation Id",
Description = "The name of the workstation connecting to SQL Server",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Context"
},
new ConnectionOption
{
Name = "pooling",
DisplayName = "Pooling",
Description = "When true, the connection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "maxPoolSize",
DisplayName = "Max Pool Size",
Description = "The maximum number of connections allowed in the pool",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "minPoolSize",
DisplayName = "Min Pool Size",
Description = "The minimum number of connections allowed in the pool",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "loadBalanceTimeout",
DisplayName = "Load Balance Timeout",
Description = "The minimum amount of time (in seconds) for this connection to live in the pool before being destroyed",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "replication",
DisplayName = "Replication",
Description = "Used by SQL Server in Replication",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Replication"
},
new ConnectionOption
{
Name = "attachDbFilename",
DisplayName = "Attach Db Filename",
ValueType = ConnectionOption.ValueTypeString
},
new ConnectionOption
{
Name = "failoverPartner",
DisplayName = "Failover Partner",
Description = "the name or network address of the instance of SQL Server that acts as a failover partner",
ValueType = ConnectionOption.ValueTypeString,
GroupName = " Source"
},
new ConnectionOption
{
Name = "multiSubnetFailover",
DisplayName = "Multi Subnet Failover",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "multipleActiveResultSets",
DisplayName = "Multiple Active ResultSets",
Description = "When true, multiple result sets can be returned and read from one connection",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Advanced"
},
new ConnectionOption
{
Name = "packetSize",
DisplayName = "Packet Size",
Description = "Size in bytes of the network packets used to communicate with an instance of SQL Server",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Advanced"
},
new ConnectionOption
{
Name = "typeSystemVersion",
DisplayName = "Type System Version",
Description = "Indicates which server type system then provider will expose through the DataReader",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Advanced"
}
}
};
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1351,4 +1351,448 @@
<value>Error parsing ScriptingListObjectsCompleteParams.ConnectionString property.</value>
<comment></comment>
</data>
<data name="unavailable" xml:space="preserve">
<value>Unavailable</value>
<comment></comment>
</data>
<data name="filegroup_dialog_defaultFilegroup" xml:space="preserve">
<value>Current default filegroup: {0}</value>
<comment></comment>
</data>
<data name="filegroup_dialog_title" xml:space="preserve">
<value>New Filegroup for {0}</value>
<comment></comment>
</data>
<data name="filegroups_default" xml:space="preserve">
<value>Default</value>
<comment></comment>
</data>
<data name="filegroups_files" xml:space="preserve">
<value>Files</value>
<comment></comment>
</data>
<data name="filegroups_name" xml:space="preserve">
<value>Name</value>
<comment></comment>
</data>
<data name="filegroups_readonly" xml:space="preserve">
<value>Read-Only</value>
<comment></comment>
</data>
<data name="general_autogrowth" xml:space="preserve">
<value>Autogrowth / Maxsize</value>
<comment></comment>
</data>
<data name="general_builderText" xml:space="preserve">
<value>...</value>
<comment></comment>
</data>
<data name="general_default" xml:space="preserve">
<value>&lt;default&gt;</value>
<comment></comment>
</data>
<data name="general_fileGroup" xml:space="preserve">
<value>Filegroup</value>
<comment></comment>
</data>
<data name="general_fileName" xml:space="preserve">
<value>Logical Name</value>
<comment></comment>
</data>
<data name="general_fileType" xml:space="preserve">
<value>File Type</value>
<comment></comment>
</data>
<data name="general_initialSize" xml:space="preserve">
<value>Initial Size (MB)</value>
<comment></comment>
</data>
<data name="general_newFilegroup" xml:space="preserve">
<value>&lt;new filegroup&gt;</value>
<comment></comment>
</data>
<data name="general_path" xml:space="preserve">
<value>Path</value>
<comment></comment>
</data>
<data name="general_physicalFileName" xml:space="preserve">
<value>File Name</value>
<comment></comment>
</data>
<data name="general_rawDevice" xml:space="preserve">
<value>&lt;raw device&gt;</value>
<comment></comment>
</data>
<data name="general_recoveryModel_bulkLogged" xml:space="preserve">
<value>Bulk-logged</value>
<comment></comment>
</data>
<data name="general_recoveryModel_full" xml:space="preserve">
<value>Full</value>
<comment></comment>
</data>
<data name="general_recoveryModel_simple" xml:space="preserve">
<value>Simple</value>
<comment></comment>
</data>
<data name="general_titleSearchOwner" xml:space="preserve">
<value>Select Database Owner</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_disabled" xml:space="preserve">
<value>None</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_restrictedGrowthByMB" xml:space="preserve">
<value>By {0} MB, Limited to {1} MB</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_restrictedGrowthByPercent" xml:space="preserve">
<value>By {0} percent, Limited to {1} MB</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unrestrictedGrowthByMB" xml:space="preserve">
<value>By {0} MB, Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unrestrictedGrowthByPercent" xml:space="preserve">
<value>By {0} percent, Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unlimitedfilestream" xml:space="preserve">
<value>Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_limitedfilestream" xml:space="preserve">
<value>Limited to {0} MB</value>
<comment></comment>
</data>
<data name="prototype_db_category_automatic" xml:space="preserve">
<value>Automatic</value>
<comment></comment>
</data>
<data name="prototype_db_category_servicebroker" xml:space="preserve">
<value>Service Broker</value>
<comment></comment>
</data>
<data name="prototype_db_category_collation" xml:space="preserve">
<value>Collation</value>
<comment></comment>
</data>
<data name="prototype_db_category_cursor" xml:space="preserve">
<value>Cursor</value>
<comment></comment>
</data>
<data name="prototype_db_category_misc" xml:space="preserve">
<value>Miscellaneous</value>
<comment></comment>
</data>
<data name="prototype_db_category_recovery" xml:space="preserve">
<value>Recovery</value>
<comment></comment>
</data>
<data name="prototype_db_category_state" xml:space="preserve">
<value>State</value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiNullDefault" xml:space="preserve">
<value>ANSI NULL Default</value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiNulls" xml:space="preserve">
<value>ANSI NULLS Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiPadding" xml:space="preserve">
<value>ANSI Padding Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiWarnings" xml:space="preserve">
<value>ANSI Warnings Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_arithabort" xml:space="preserve">
<value>Arithmetic Abort Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoClose" xml:space="preserve">
<value>Auto Close</value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoCreateStatistics" xml:space="preserve">
<value>Auto Create Statistics</value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoShrink" xml:space="preserve">
<value>Auto Shrink</value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoUpdateStatistics" xml:space="preserve">
<value>Auto Update Statistics </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoUpdateStatisticsAsync" xml:space="preserve">
<value>Auto Update Statistics Asynchronously</value>
<comment></comment>
</data>
<data name="prototype_db_prop_caseSensitive" xml:space="preserve">
<value>Case Sensitive</value>
<comment></comment>
</data>
<data name="prototype_db_prop_closeCursorOnCommit" xml:space="preserve">
<value>Close Cursor on Commit Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_collation" xml:space="preserve">
<value>Collation</value>
<comment></comment>
</data>
<data name="prototype_db_prop_concatNullYieldsNull" xml:space="preserve">
<value>Concatenate Null Yields Null </value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseCompatibilityLevel" xml:space="preserve">
<value>Database Compatibility Level</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState" xml:space="preserve">
<value>Database State </value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor" xml:space="preserve">
<value>Default Cursor</value>
<comment></comment>
</data>
<data name="prototype_db_prop_fullTextIndexing" xml:space="preserve">
<value>Full-Text Indexing Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_numericRoundAbort" xml:space="preserve">
<value>Numeric Round-Abort </value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify" xml:space="preserve">
<value>Page Verify </value>
<comment></comment>
</data>
<data name="prototype_db_prop_quotedIdentifier" xml:space="preserve">
<value>Quoted Identifiers Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_readOnly" xml:space="preserve">
<value>Database Read-Only</value>
<comment></comment>
</data>
<data name="prototype_db_prop_recursiveTriggers" xml:space="preserve">
<value>Recursive Triggers Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess" xml:space="preserve">
<value>Restrict Access</value>
<comment></comment>
</data>
<data name="prototype_db_prop_selectIntoBulkCopy" xml:space="preserve">
<value>Select Into/Bulk Copy</value>
<comment></comment>
</data>
<data name="prototype_db_prop_honorBrokerPriority" xml:space="preserve">
<value>Honor Broker Priority</value>
<comment></comment>
</data>
<data name="prototype_db_prop_serviceBrokerGuid" xml:space="preserve">
<value>Service Broker Identifier</value>
<comment></comment>
</data>
<data name="prototype_db_prop_brokerEnabled" xml:space="preserve">
<value>Broker Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_truncateLogOnCheckpoint" xml:space="preserve">
<value>Truncate Log on Checkpoint </value>
<comment></comment>
</data>
<data name="prototype_db_prop_dbChaining" xml:space="preserve">
<value>Cross-database Ownership Chaining Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_trustworthy" xml:space="preserve">
<value>Trustworthy</value>
<comment></comment>
</data>
<data name="prototype_db_prop_dateCorrelationOptimization" xml:space="preserve">
<value>Date Correlation Optimization Enabledprototype_db_prop_parameterization = Parameterization</value>
<comment></comment>
</data>
<data name="prototype_db_prop_parameterization_value_forced" xml:space="preserve">
<value>Forced</value>
<comment></comment>
</data>
<data name="prototype_db_prop_parameterization_value_simple" xml:space="preserve">
<value>Simple</value>
<comment></comment>
</data>
<data name="prototype_file_dataFile" xml:space="preserve">
<value>ROWS Data</value>
<comment></comment>
</data>
<data name="prototype_file_logFile" xml:space="preserve">
<value>LOG</value>
<comment></comment>
</data>
<data name="prototype_file_filestreamFile" xml:space="preserve">
<value>FILESTREAM Data</value>
<comment></comment>
</data>
<data name="prototype_file_noFileGroup" xml:space="preserve">
<value>Not Applicable</value>
<comment></comment>
</data>
<data name="prototype_file_defaultpathstring" xml:space="preserve">
<value>&lt;default path&gt;</value>
<comment></comment>
</data>
<data name="title_openConnectionsMustBeClosed" xml:space="preserve">
<value>Open Connections</value>
<comment></comment>
</data>
<data name="warning_openConnectionsMustBeClosed" xml:space="preserve">
<value>To change the database properties, SQL Server must close all other connections to the database_ Are you sure you want to change the properties and close all other connections?</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_autoClosed" xml:space="preserve">
<value>AUTO_CLOSED</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_emergency" xml:space="preserve">
<value>EMERGENCY</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_inaccessible" xml:space="preserve">
<value>INACCESSIBLE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_normal" xml:space="preserve">
<value>NORMAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_offline" xml:space="preserve">
<value>OFFLINE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_recovering" xml:space="preserve">
<value>RECOVERING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_recoveryPending" xml:space="preserve">
<value>RECOVERY PENDING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_restoring" xml:space="preserve">
<value>RESTORING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_shutdown" xml:space="preserve">
<value>SHUTDOWN</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_standby" xml:space="preserve">
<value>STANDBY</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_suspect" xml:space="preserve">
<value>SUSPECT</value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor_value_global" xml:space="preserve">
<value>GLOBAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor_value_local" xml:space="preserve">
<value>LOCAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_multiple" xml:space="preserve">
<value>MULTI_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_restricted" xml:space="preserve">
<value>RESTRICTED_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_single" xml:space="preserve">
<value>SINGLE_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_checksum" xml:space="preserve">
<value>CHECKSUM</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_none" xml:space="preserve">
<value>NONE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_tornPageDetection" xml:space="preserve">
<value>TORN_PAGE_DETECTION</value>
<comment></comment>
</data>
<data name="prototype_db_prop_varDecimalEnabled" xml:space="preserve">
<value>VarDecimal Storage Format Enabled</value>
<comment></comment>
</data>
<data name="compatibilityLevel_katmai" xml:space="preserve">
<value>SQL Server 2008 (100)</value>
<comment></comment>
</data>
<data name="prototype_db_prop_encryptionEnabled" xml:space="preserve">
<value>Encryption Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databasescopedconfig_value_off" xml:space="preserve">
<value>OFF</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databasescopedconfig_value_on" xml:space="preserve">
<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>
</data>
<data name="compatibilityLevel_denali" xml:space="preserve">
<value>SQL Server 2012 (110)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sql14" xml:space="preserve">
<value>SQL Server 2014 (120)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sql15" xml:space="preserve">
<value>SQL Server 2016 (130)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sqlvNext" xml:space="preserve">
<value>SQL Server vNext (140)</value>
<comment></comment>
</data>
<data name="general_containmentType_None" xml:space="preserve">
<value>None</value>
<comment></comment>
</data>
<data name="general_containmentType_Partial" xml:space="preserve">
<value>Partial</value>
<comment></comment>
</data>
<data name="filegroups_filestreamFiles" xml:space="preserve">
<value>FILESTREAM Files</value>
<comment></comment>
</data>
<data name="prototype_file_noApplicableFileGroup" xml:space="preserve">
<value>No Applicable Filegroup</value>
<comment></comment>
</data>
</root>

View File

@@ -675,4 +675,126 @@ ScriptingParams_ConnectionString_Property_Invalid = Error parsing ScriptingParam
ScriptingParams_FilePath_Property_Invalid = Invalid directory specified by the ScriptingParams.FilePath property.
ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = Error parsing ScriptingListObjectsCompleteParams.ConnectionString property.
ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid = Error parsing ScriptingListObjectsCompleteParams.ConnectionString property.
############################################################################
# Admin Service
unavailable = Unavailable
filegroup_dialog_defaultFilegroup = Current default filegroup: {0}
filegroup_dialog_title = New Filegroup for {0}
filegroups_default = Default
filegroups_files = Files
filegroups_name = Name
filegroups_readonly = Read-Only
general_autogrowth = Autogrowth / Maxsize
general_builderText = ...
general_default = &lt;default&gt;
general_fileGroup = Filegroup
general_fileName = Logical Name
general_fileType = File Type
general_initialSize = Initial Size (MB)
general_newFilegroup = &lt;new filegroup&gt;
general_path = Path
general_physicalFileName = File Name
general_rawDevice = &lt;raw device&gt;
general_recoveryModel_bulkLogged = Bulk-logged
general_recoveryModel_full = Full
general_recoveryModel_simple = Simple
general_titleSearchOwner = Select Database Owner
prototype_autogrowth_disabled = None
prototype_autogrowth_restrictedGrowthByMB = By {0} MB, Limited to {1} MB
prototype_autogrowth_restrictedGrowthByPercent = By {0} percent, Limited to {1} MB
prototype_autogrowth_unrestrictedGrowthByMB = By {0} MB, Unlimited
prototype_autogrowth_unrestrictedGrowthByPercent = By {0} percent, Unlimited
prototype_autogrowth_unlimitedfilestream = Unlimited
prototype_autogrowth_limitedfilestream = Limited to {0} MB
prototype_db_category_automatic = Automatic
prototype_db_category_servicebroker = Service Broker
prototype_db_category_collation = Collation
prototype_db_category_cursor = Cursor
prototype_db_category_misc = Miscellaneous
prototype_db_category_recovery = Recovery
prototype_db_category_state = State
prototype_db_prop_ansiNullDefault = ANSI NULL Default
prototype_db_prop_ansiNulls = ANSI NULLS Enabled
prototype_db_prop_ansiPadding = ANSI Padding Enabled
prototype_db_prop_ansiWarnings = ANSI Warnings Enabled
prototype_db_prop_arithabort = Arithmetic Abort Enabled
prototype_db_prop_autoClose = Auto Close
prototype_db_prop_autoCreateStatistics = Auto Create Statistics
prototype_db_prop_autoShrink = Auto Shrink
prototype_db_prop_autoUpdateStatistics = Auto Update Statistics
prototype_db_prop_autoUpdateStatisticsAsync = Auto Update Statistics Asynchronously
prototype_db_prop_caseSensitive = Case Sensitive
prototype_db_prop_closeCursorOnCommit = Close Cursor on Commit Enabled
prototype_db_prop_collation = Collation
prototype_db_prop_concatNullYieldsNull = Concatenate Null Yields Null
prototype_db_prop_databaseCompatibilityLevel = Database Compatibility Level
prototype_db_prop_databaseState = Database State
prototype_db_prop_defaultCursor = Default Cursor
prototype_db_prop_fullTextIndexing = Full-Text Indexing Enabled
prototype_db_prop_numericRoundAbort = Numeric Round-Abort
prototype_db_prop_pageVerify = Page Verify
prototype_db_prop_quotedIdentifier = Quoted Identifiers Enabled
prototype_db_prop_readOnly = Database Read-Only
prototype_db_prop_recursiveTriggers = Recursive Triggers Enabled
prototype_db_prop_restrictAccess = Restrict Access
prototype_db_prop_selectIntoBulkCopy = Select Into/Bulk Copy
prototype_db_prop_honorBrokerPriority = Honor Broker Priority
prototype_db_prop_serviceBrokerGuid = Service Broker Identifier
prototype_db_prop_brokerEnabled = Broker Enabled
prototype_db_prop_truncateLogOnCheckpoint = Truncate Log on Checkpoint
prototype_db_prop_dbChaining = Cross-database Ownership Chaining Enabled
prototype_db_prop_trustworthy = Trustworthy
prototype_db_prop_dateCorrelationOptimization = Date Correlation Optimization Enabledprototype_db_prop_parameterization = Parameterization
prototype_db_prop_parameterization_value_forced = Forced
prototype_db_prop_parameterization_value_simple = Simple
prototype_file_dataFile = ROWS Data
prototype_file_logFile = LOG
prototype_file_filestreamFile = FILESTREAM Data
prototype_file_noFileGroup = Not Applicable
prototype_file_defaultpathstring = &lt;default path&gt;
title_openConnectionsMustBeClosed = Open Connections
warning_openConnectionsMustBeClosed=To change the database properties, SQL Server must close all other connections to the database_ Are you sure you want to change the properties and close all other connections?
prototype_db_prop_databaseState_value_autoClosed = AUTO_CLOSED
prototype_db_prop_databaseState_value_emergency = EMERGENCY
prototype_db_prop_databaseState_value_inaccessible = INACCESSIBLE
prototype_db_prop_databaseState_value_normal = NORMAL
prototype_db_prop_databaseState_value_offline = OFFLINE
prototype_db_prop_databaseState_value_recovering = RECOVERING
prototype_db_prop_databaseState_value_recoveryPending = RECOVERY PENDING
prototype_db_prop_databaseState_value_restoring = RESTORING
prototype_db_prop_databaseState_value_shutdown=SHUTDOWN
prototype_db_prop_databaseState_value_standby = STANDBY
prototype_db_prop_databaseState_value_suspect = SUSPECT
prototype_db_prop_defaultCursor_value_global = GLOBAL
prototype_db_prop_defaultCursor_value_local = LOCAL
prototype_db_prop_restrictAccess_value_multiple = MULTI_USER
prototype_db_prop_restrictAccess_value_restricted = RESTRICTED_USER
prototype_db_prop_restrictAccess_value_single = SINGLE_USER
prototype_db_prop_pageVerify_value_checksum = CHECKSUM
prototype_db_prop_pageVerify_value_none = NONE
prototype_db_prop_pageVerify_value_tornPageDetection = TORN_PAGE_DETECTION
prototype_db_prop_varDecimalEnabled = VarDecimal Storage Format Enabled
compatibilityLevel_katmai = SQL Server 2008 (100)
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_denali = SQL Server 2012 (110)
compatibilityLevel_sql14 = SQL Server 2014 (120)
compatibilityLevel_sql15 = SQL Server 2016 (130)
compatibilityLevel_sqlvNext = SQL Server vNext (140)
general_containmentType_None = None
general_containmentType_Partial = Partial
filegroups_filestreamFiles = FILESTREAM Files
prototype_file_noApplicableFileGroup = No Applicable Filegroup

View File

@@ -1541,6 +1541,561 @@
<target state="new">System-Versioned</target>
<note></note>
</trans-unit>
<trans-unit id="unavailable">
<source>Unavailable</source>
<target state="new">Unavailable</target>
<note></note>
</trans-unit>
<trans-unit id="filegroup_dialog_defaultFilegroup">
<source>Current default filegroup: {0}</source>
<target state="new">Current default filegroup: {0}</target>
<note></note>
</trans-unit>
<trans-unit id="filegroup_dialog_title">
<source>New Filegroup for {0}</source>
<target state="new">New Filegroup for {0}</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_default">
<source>Default</source>
<target state="new">Default</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_files">
<source>Files</source>
<target state="new">Files</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_name">
<source>Name</source>
<target state="new">Name</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_readonly">
<source>Read-Only</source>
<target state="new">Read-Only</target>
<note></note>
</trans-unit>
<trans-unit id="general_autogrowth">
<source>Autogrowth / Maxsize</source>
<target state="new">Autogrowth / Maxsize</target>
<note></note>
</trans-unit>
<trans-unit id="general_builderText">
<source>...</source>
<target state="new">...</target>
<note></note>
</trans-unit>
<trans-unit id="general_default">
<source>&lt;default&gt;</source>
<target state="new">&lt;default&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileGroup">
<source>Filegroup</source>
<target state="new">Filegroup</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileName">
<source>Logical Name</source>
<target state="new">Logical Name</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileType">
<source>File Type</source>
<target state="new">File Type</target>
<note></note>
</trans-unit>
<trans-unit id="general_initialSize">
<source>Initial Size (MB)</source>
<target state="new">Initial Size (MB)</target>
<note></note>
</trans-unit>
<trans-unit id="general_newFilegroup">
<source>&lt;new filegroup&gt;</source>
<target state="new">&lt;new filegroup&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_path">
<source>Path</source>
<target state="new">Path</target>
<note></note>
</trans-unit>
<trans-unit id="general_physicalFileName">
<source>File Name</source>
<target state="new">File Name</target>
<note></note>
</trans-unit>
<trans-unit id="general_rawDevice">
<source>&lt;raw device&gt;</source>
<target state="new">&lt;raw device&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_bulkLogged">
<source>Bulk-logged</source>
<target state="new">Bulk-logged</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_full">
<source>Full</source>
<target state="new">Full</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_simple">
<source>Simple</source>
<target state="new">Simple</target>
<note></note>
</trans-unit>
<trans-unit id="general_titleSearchOwner">
<source>Select Database Owner</source>
<target state="new">Select Database Owner</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_disabled">
<source>None</source>
<target state="new">None</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_restrictedGrowthByMB">
<source>By {0} MB, Limited to {1} MB</source>
<target state="new">By {0} MB, Limited to {1} MB</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_restrictedGrowthByPercent">
<source>By {0} percent, Limited to {1} MB</source>
<target state="new">By {0} percent, Limited to {1} MB</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unrestrictedGrowthByMB">
<source>By {0} MB, Unlimited</source>
<target state="new">By {0} MB, Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unrestrictedGrowthByPercent">
<source>By {0} percent, Unlimited</source>
<target state="new">By {0} percent, Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unlimitedfilestream">
<source>Unlimited</source>
<target state="new">Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_limitedfilestream">
<source>Limited to {0} MB</source>
<target state="new">Limited to {0} MB</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_automatic">
<source>Automatic</source>
<target state="new">Automatic</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_servicebroker">
<source>Service Broker</source>
<target state="new">Service Broker</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_collation">
<source>Collation</source>
<target state="new">Collation</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_cursor">
<source>Cursor</source>
<target state="new">Cursor</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_misc">
<source>Miscellaneous</source>
<target state="new">Miscellaneous</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_recovery">
<source>Recovery</source>
<target state="new">Recovery</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_state">
<source>State</source>
<target state="new">State</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiNullDefault">
<source>ANSI NULL Default</source>
<target state="new">ANSI NULL Default</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiNulls">
<source>ANSI NULLS Enabled</source>
<target state="new">ANSI NULLS Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiPadding">
<source>ANSI Padding Enabled </source>
<target state="new">ANSI Padding Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiWarnings">
<source>ANSI Warnings Enabled</source>
<target state="new">ANSI Warnings Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_arithabort">
<source>Arithmetic Abort Enabled </source>
<target state="new">Arithmetic Abort Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoClose">
<source>Auto Close</source>
<target state="new">Auto Close</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoCreateStatistics">
<source>Auto Create Statistics</source>
<target state="new">Auto Create Statistics</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoShrink">
<source>Auto Shrink</source>
<target state="new">Auto Shrink</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoUpdateStatistics">
<source>Auto Update Statistics </source>
<target state="new">Auto Update Statistics </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoUpdateStatisticsAsync">
<source>Auto Update Statistics Asynchronously</source>
<target state="new">Auto Update Statistics Asynchronously</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_caseSensitive">
<source>Case Sensitive</source>
<target state="new">Case Sensitive</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_closeCursorOnCommit">
<source>Close Cursor on Commit Enabled </source>
<target state="new">Close Cursor on Commit Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_collation">
<source>Collation</source>
<target state="new">Collation</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_concatNullYieldsNull">
<source>Concatenate Null Yields Null </source>
<target state="new">Concatenate Null Yields Null </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseCompatibilityLevel">
<source>Database Compatibility Level</source>
<target state="new">Database Compatibility Level</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState">
<source>Database State </source>
<target state="new">Database State </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor">
<source>Default Cursor</source>
<target state="new">Default Cursor</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_fullTextIndexing">
<source>Full-Text Indexing Enabled </source>
<target state="new">Full-Text Indexing Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_numericRoundAbort">
<source>Numeric Round-Abort </source>
<target state="new">Numeric Round-Abort </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify">
<source>Page Verify </source>
<target state="new">Page Verify </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_quotedIdentifier">
<source>Quoted Identifiers Enabled </source>
<target state="new">Quoted Identifiers Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_readOnly">
<source>Database Read-Only</source>
<target state="new">Database Read-Only</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_recursiveTriggers">
<source>Recursive Triggers Enabled </source>
<target state="new">Recursive Triggers Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess">
<source>Restrict Access</source>
<target state="new">Restrict Access</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_selectIntoBulkCopy">
<source>Select Into/Bulk Copy</source>
<target state="new">Select Into/Bulk Copy</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_honorBrokerPriority">
<source>Honor Broker Priority</source>
<target state="new">Honor Broker Priority</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_serviceBrokerGuid">
<source>Service Broker Identifier</source>
<target state="new">Service Broker Identifier</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_brokerEnabled">
<source>Broker Enabled</source>
<target state="new">Broker Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_truncateLogOnCheckpoint">
<source>Truncate Log on Checkpoint </source>
<target state="new">Truncate Log on Checkpoint </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_dbChaining">
<source>Cross-database Ownership Chaining Enabled</source>
<target state="new">Cross-database Ownership Chaining Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_trustworthy">
<source>Trustworthy</source>
<target state="new">Trustworthy</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_dateCorrelationOptimization">
<source>Date Correlation Optimization Enabledprototype_db_prop_parameterization = Parameterization</source>
<target state="new">Date Correlation Optimization Enabledprototype_db_prop_parameterization = Parameterization</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_parameterization_value_forced">
<source>Forced</source>
<target state="new">Forced</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_parameterization_value_simple">
<source>Simple</source>
<target state="new">Simple</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_dataFile">
<source>ROWS Data</source>
<target state="new">ROWS Data</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_logFile">
<source>LOG</source>
<target state="new">LOG</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_filestreamFile">
<source>FILESTREAM Data</source>
<target state="new">FILESTREAM Data</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_noFileGroup">
<source>Not Applicable</source>
<target state="new">Not Applicable</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_defaultpathstring">
<source>&lt;default path&gt;</source>
<target state="new">&lt;default path&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="title_openConnectionsMustBeClosed">
<source>Open Connections</source>
<target state="new">Open Connections</target>
<note></note>
</trans-unit>
<trans-unit id="warning_openConnectionsMustBeClosed">
<source>To change the database properties, SQL Server must close all other connections to the database_ Are you sure you want to change the properties and close all other connections?</source>
<target state="new">To change the database properties, SQL Server must close all other connections to the database_ Are you sure you want to change the properties and close all other connections?</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_autoClosed">
<source>AUTO_CLOSED</source>
<target state="new">AUTO_CLOSED</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_emergency">
<source>EMERGENCY</source>
<target state="new">EMERGENCY</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_inaccessible">
<source>INACCESSIBLE</source>
<target state="new">INACCESSIBLE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_normal">
<source>NORMAL</source>
<target state="new">NORMAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_offline">
<source>OFFLINE</source>
<target state="new">OFFLINE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_recovering">
<source>RECOVERING</source>
<target state="new">RECOVERING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_recoveryPending">
<source>RECOVERY PENDING</source>
<target state="new">RECOVERY PENDING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_restoring">
<source>RESTORING</source>
<target state="new">RESTORING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_shutdown">
<source>SHUTDOWN</source>
<target state="new">SHUTDOWN</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_standby">
<source>STANDBY</source>
<target state="new">STANDBY</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_suspect">
<source>SUSPECT</source>
<target state="new">SUSPECT</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor_value_global">
<source>GLOBAL</source>
<target state="new">GLOBAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor_value_local">
<source>LOCAL</source>
<target state="new">LOCAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_multiple">
<source>MULTI_USER</source>
<target state="new">MULTI_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_restricted">
<source>RESTRICTED_USER</source>
<target state="new">RESTRICTED_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_single">
<source>SINGLE_USER</source>
<target state="new">SINGLE_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_checksum">
<source>CHECKSUM</source>
<target state="new">CHECKSUM</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_none">
<source>NONE</source>
<target state="new">NONE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_tornPageDetection">
<source>TORN_PAGE_DETECTION</source>
<target state="new">TORN_PAGE_DETECTION</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_varDecimalEnabled">
<source>VarDecimal Storage Format Enabled</source>
<target state="new">VarDecimal Storage Format Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_katmai">
<source>SQL Server 2008 (100)</source>
<target state="new">SQL Server 2008 (100)</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_encryptionEnabled">
<source>Encryption Enabled</source>
<target state="new">Encryption Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databasescopedconfig_value_off">
<source>OFF</source>
<target state="new">OFF</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databasescopedconfig_value_on">
<source>ON</source>
<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>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_denali">
<source>SQL Server 2012 (110)</source>
<target state="new">SQL Server 2012 (110)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sql14">
<source>SQL Server 2014 (120)</source>
<target state="new">SQL Server 2014 (120)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sql15">
<source>SQL Server 2016 (130)</source>
<target state="new">SQL Server 2016 (130)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sqlvNext">
<source>SQL Server vNext (140)</source>
<target state="new">SQL Server vNext (140)</target>
<note></note>
</trans-unit>
<trans-unit id="general_containmentType_None">
<source>None</source>
<target state="new">None</target>
<note></note>
</trans-unit>
<trans-unit id="general_containmentType_Partial">
<source>Partial</source>
<target state="new">Partial</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_filestreamFiles">
<source>FILESTREAM Files</source>
<target state="new">FILESTREAM Files</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_noApplicableFileGroup">
<source>No Applicable Filegroup</source>
<target state="new">No Applicable Filegroup</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -14,7 +14,9 @@ using Microsoft.SqlTools.Hosting.Contracts;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.Hosting.Protocol.Channel;
using Microsoft.SqlTools.Utility;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Admin;
namespace Microsoft.SqlTools.ServiceLayer.Hosting
{
/// <summary>
@@ -24,6 +26,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
/// </summary>
public sealed class ServiceHost : ServiceHostBase
{
private const string ProviderName = "MSSQL";
private const string ProviderDescription = "Microsoft SQL Server";
private const string ProviderProtocolVersion = "1.0";
/// <summary>
/// This timeout limits the amount of time that shutdown tasks can take to complete
/// prior to the process shutting down.
@@ -186,6 +192,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
});
}
/// <summary>
/// Handles a request for the capabilities request
/// </summary>
internal async Task HandleCapabilitiesRequest(
CapabilitiesRequest initializeParams,
RequestContext<CapabilitiesResult> requestContext)
@@ -195,300 +204,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
{
Capabilities = new DmpServerCapabilities
{
ProtocolVersion = "1.0",
ProviderName = "MSSQL",
ProviderDisplayName = "Microsoft SQL Server",
ConnectionProvider = ServiceHost.BuildConnectionProviderOptions()
ProtocolVersion = ServiceHost.ProviderProtocolVersion,
ProviderName = ServiceHost.ProviderName,
ProviderDisplayName = ServiceHost.ProviderDescription,
ConnectionProvider = ConnectionProviderOptionsHelper.BuildConnectionProviderOptions(),
AdminServicesProvider = AdminServicesProviderOptionsHelper.BuildAdminServicesProviderOptions()
}
}
);
}
internal static ConnectionProviderOptions BuildConnectionProviderOptions()
{
return new ConnectionProviderOptions
{
Options = new ConnectionOption[]
{
new ConnectionOption
{
Name = "server",
DisplayName = "Server Name",
Description = "Name of the SQL Server instance",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueServerName,
IsIdentity = true,
IsRequired = true,
GroupName = "Source"
},
new ConnectionOption
{
Name = "database",
DisplayName = "Database Name",
Description = "The name of the initial catalog or database int the data source",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueDatabaseName,
IsIdentity = true,
IsRequired = false,
GroupName = "Source"
},
new ConnectionOption
{
Name = "authenticationType",
DisplayName = "Authentication Type",
Description = "Specifies the method of authenticating with SQL Server",
ValueType = ConnectionOption.ValueTypeCategory,
SpecialValueType = ConnectionOption.SpecialValueAuthType,
CategoryValues = new CategoryValue[]
{ new CategoryValue {DisplayName = "SQL Login", Name = "SqlLogin" },
new CategoryValue {DisplayName = "Integrated Auth", Name= "Integrated" }
},
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "user",
DisplayName = "User Name",
Description = "Indicates the user ID to be used when connecting to the data source",
ValueType = ConnectionOption.ValueTypeString,
SpecialValueType = ConnectionOption.SpecialValueUserName,
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "password",
DisplayName = "Password",
Description = "Indicates the password to be used when connecting to the data source",
ValueType = ConnectionOption.ValueTypePassword,
SpecialValueType = ConnectionOption.SpecialValuePasswordName,
IsIdentity = true,
IsRequired = true,
GroupName = "Security"
},
new ConnectionOption
{
Name = "applicationIntent",
DisplayName = "Application Intent",
Description = "Declares the application workload type when connecting to a server",
ValueType = ConnectionOption.ValueTypeCategory,
CategoryValues = new CategoryValue[] {
new CategoryValue { Name = "ReadWrite", DisplayName = "ReadWrite" },
new CategoryValue {Name = "ReadOnly", DisplayName = "ReadOnly" }
},
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "asynchronousProcessing",
DisplayName = "Asynchronous processing enabled",
Description = "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "connectTimeout",
DisplayName = "Connect Timeout",
Description =
"The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "15",
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "currentLanguage",
DisplayName = "Current Language",
Description = "The SQL Server language record name",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Initialization"
},
new ConnectionOption
{
Name = "columnEncryptionSetting",
DisplayName = "Column Encryption Setting",
Description = "Default column encryption setting for all the commands on the connection",
ValueType = ConnectionOption.ValueTypeCategory,
GroupName = "Security",
CategoryValues = new CategoryValue[] {
new CategoryValue { Name = "Disabled" },
new CategoryValue {Name = "Enabled" }
}
},
new ConnectionOption
{
Name = "encrypt",
DisplayName = "Encrypt",
Description =
"When true, SQL Server uses SSL encryption for all data sent between the client and server if the servers has a certificate installed",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "persistSecurityInfo",
DisplayName = "Persist Security Info",
Description = "When false, security-sensitive information, such as the password, is not returned as part of the connection",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "trustServerCertificate",
DisplayName = "Trust Server Certificate",
Description = "When true (and encrypt=true), SQL Server uses SSL encryption for all data sent between the client and server without validating the server certificate",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "attachedDBFileName",
DisplayName = "Attached DB File Name",
Description = "The name of the primary file, including the full path name, of an attachable database",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Source"
},
new ConnectionOption
{
Name = "contextConnection",
DisplayName = "Context Connection",
Description = "When true, indicates the connection should be from the SQL server context. Available only when running in the SQL Server process",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Source"
},
new ConnectionOption
{
Name = "port",
DisplayName = "Port",
ValueType = ConnectionOption.ValueTypeNumber
},
new ConnectionOption
{
Name = "connectRetryCount",
DisplayName = "Connect Retry Count",
Description = "Number of attempts to restore connection",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "1",
GroupName = "Connection Resiliency"
},
new ConnectionOption
{
Name = "connectRetryInterval",
DisplayName = "Connect Retry Interval",
Description = "Delay between attempts to restore connection",
ValueType = ConnectionOption.ValueTypeNumber,
DefaultValue = "10",
GroupName = "Connection Resiliency"
},
new ConnectionOption
{
Name = "applicationName",
DisplayName = "Application Name",
Description = "The name of the application",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Context"
},
new ConnectionOption
{
Name = "workstationId",
DisplayName = "Workstation Id",
Description = "The name of the workstation connecting to SQL Server",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Context"
},
new ConnectionOption
{
Name = "pooling",
DisplayName = "Pooling",
Description = "When true, the connection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "maxPoolSize",
DisplayName = "Max Pool Size",
Description = "The maximum number of connections allowed in the pool",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "minPoolSize",
DisplayName = "Min Pool Size",
Description = "The minimum number of connections allowed in the pool",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "loadBalanceTimeout",
DisplayName = "Load Balance Timeout",
Description = "The minimum amount of time (in seconds) for this connection to live in the pool before being destroyed",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Pooling"
},
new ConnectionOption
{
Name = "replication",
DisplayName = "Replication",
Description = "Used by SQL Server in Replication",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Replication"
},
new ConnectionOption
{
Name = "attachDbFilename",
DisplayName = "Attach Db Filename",
ValueType = ConnectionOption.ValueTypeString
},
new ConnectionOption
{
Name = "failoverPartner",
DisplayName = "Failover Partner",
Description = "the name or network address of the instance of SQL Server that acts as a failover partner",
ValueType = ConnectionOption.ValueTypeString,
GroupName = " Source"
},
new ConnectionOption
{
Name = "multiSubnetFailover",
DisplayName = "Multi Subnet Failover",
ValueType = ConnectionOption.ValueTypeBoolean
},
new ConnectionOption
{
Name = "multipleActiveResultSets",
DisplayName = "Multiple Active ResultSets",
Description = "When true, multiple result sets can be returned and read from one connection",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Advanced"
},
new ConnectionOption
{
Name = "packetSize",
DisplayName = "Packet Size",
Description = "Size in bytes of the network packets used to communicate with an instance of SQL Server",
ValueType = ConnectionOption.ValueTypeNumber,
GroupName = "Advanced"
},
new ConnectionOption
{
Name = "typeSystemVersion",
DisplayName = "Type System Version",
Description = "Indicates which server type system then provider will expose through the DataReader",
ValueType = ConnectionOption.ValueTypeString,
GroupName = "Advanced"
}
}
};
}
/// <summary>
/// Handles the version request. Sends back the server version as result.
/// </summary>

View File

@@ -4,8 +4,9 @@
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"preserveCompilationContext": true,
"allowUnsafe": true
},
"configurations": {
"Integration": {
"buildOptions": {
@@ -20,7 +21,7 @@
"Newtonsoft.Json": "9.0.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "140.17049.0",
"Microsoft.SqlServer.Smo": "140.17050.0",
"Microsoft.SqlServer.Management.SqlScriptPublishModel": "140.17049.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
@@ -34,6 +35,7 @@
"System.Diagnostics.Process": "4.1.0",
"System.Threading.Thread": "4.0.0",
"System.Runtime.Loader": "4.0.0",
"System.Xml.XmlDocument": "4.0.1",
"System.Composition": "1.0.31-beta-24326-02",
"Microsoft.Extensions.DependencyModel": "1.0.0",
"Microsoft.SqlTools.Hosting": {

View File

@@ -0,0 +1,86 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Xunit;
using Moq;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
using Microsoft.SqlTools.ServiceLayer.Admin;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.AdminServices
{
/// <summary>
/// Tests for the ServiceHost Language Service tests
/// </summary>
public class CreateDatabaseTests
{
private LiveConnectionHelper.TestConnectionResult GetLiveAutoCompleteTestObjects()
{
var textDocument = new TextDocumentPosition
{
TextDocument = new TextDocumentIdentifier { Uri = Test.Common.Constants.OwnerUri },
Position = new Position
{
Line = 0,
Character = 0
}
};
var result = LiveConnectionHelper.InitLiveConnectionInfo();
result.TextDocumentPosition = textDocument;
return result;
}
/// <summary>
/// Validate creating a database with valid input
/// </summary>
[Fact]
public async void CreateDatabaseWithValidInputTest()
{
var result = GetLiveAutoCompleteTestObjects();
var requestContext = new Mock<RequestContext<CreateDatabaseResponse>>();
requestContext.Setup(x => x.SendResult(It.IsAny<CreateDatabaseResponse>())).Returns(Task.FromResult(new object()));
var dbParams = new CreateDatabaseParams
{
OwnerUri = result.ConnectionInfo.OwnerUri,
DatabaseInfo = new DatabaseInfo()
};
await AdminService.HandleCreateDatabaseRequest(dbParams, requestContext.Object);
requestContext.VerifyAll();
}
/// <summary>
/// Get a default database info object
/// </summary>
[Fact]
public async void GetDefaultDatebaseInfoTest()
{
var result = GetLiveAutoCompleteTestObjects();
var requestContext = new Mock<RequestContext<DefaultDatabaseInfoResponse>>();
requestContext.Setup(x => x.SendResult(It.IsAny<DefaultDatabaseInfoResponse>())).Returns(Task.FromResult(new object()));
var dbParams = new DefaultDatabaseInfoParams
{
OwnerUri = result.ConnectionInfo.OwnerUri
};
await AdminService.HandleDefaultDatabaseInfoRequest(dbParams, requestContext.Object);
requestContext.VerifyAll();
}
}
}

View File

@@ -17,7 +17,7 @@
"System.Runtime.Serialization.Primitives": "4.1.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "140.17049.0",
"Microsoft.SqlServer.Smo": "140.17050.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",

View File

@@ -18,7 +18,7 @@
"System.Runtime.Serialization.Primitives": "4.1.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "140.17049.0",
"Microsoft.SqlServer.Smo": "140.17050.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",

View File

@@ -1,16 +0,0 @@
//
// 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.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Admin
{
public class CreateDatabaseTests
{
}
}

View File

@@ -1,16 +0,0 @@
//
// 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.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Admin
{
public class CreateLoginTests
{
}
}

View File

@@ -7,7 +7,7 @@ using System.Linq;
using Microsoft.SqlTools.Hosting.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Xunit;
using Microsoft.SqlTools.ServiceLayer.Connection;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
{
@@ -121,7 +121,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
public void ConnectionDetailsOptionsShouldBeDefinedInConnectionProviderOptions()
{
ConnectionDetails details = new ConnectionDetails();
ConnectionProviderOptions optionMetadata = Hosting.ServiceHost.BuildConnectionProviderOptions();
ConnectionProviderOptions optionMetadata = ConnectionProviderOptionsHelper.BuildConnectionProviderOptions();
var index = 0;
var expectedForStrings = "Value for strings";

View File

@@ -19,7 +19,7 @@
"System.Runtime.Serialization.Primitives": "4.1.1",
"System.Data.Common": "4.1.0",
"System.Data.SqlClient": "4.4.0-sqltools-24613-04",
"Microsoft.SqlServer.Smo": "140.17049.0",
"Microsoft.SqlServer.Smo": "140.17050.0",
"System.Security.SecureString": "4.0.0",
"System.Collections.Specialized": "4.0.1",
"System.ComponentModel.TypeConverter": "4.1.0",