Ledger Objects Representation in Object Explorer (#1615)

* support for ledger objects in OE

* generated sr files

* update versionKey to sql 2022 in test env config

* more 2019 to 2022 updates

* add sql2022 instead of replacing

* missed filter on table

* add logging

* more logging

* adding Script160Compat options for sql2022

Co-authored-by: Alan Ren <alanren@microsoft.com>
This commit is contained in:
Jordan Hays
2022-08-05 13:53:17 -04:00
committed by GitHub
parent 1789fd1233
commit d78ff94b31
25 changed files with 442 additions and 53 deletions

View File

@@ -11,13 +11,13 @@ steps:
dockerVersion: 17.09.0-ce
releaseType: stable
- script: docker pull mcr.microsoft.com/mssql/server:2019-latest
- script: docker pull mcr.microsoft.com/mssql/server:2022-latest
displayName: Pull MSSQL Docker Image
- bash: echo "##vso[task.setvariable variable=defaultSql2019_password;issecret=true]Test-$(Build.BuildNumber)-$(Get-Date -format yyyyMMdd-Hmmss)"
- bash: echo "##vso[task.setvariable variable=defaultSql2022_password;issecret=true]Test-$(Build.BuildNumber)-$(Get-Date -format yyyyMMdd-Hmmss)"
displayName: Generate password for test server
- script: 'docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=$(defaultSql2019_password)" -e "MSSQL_AGENT_ENABLED=True" -p 1433:1433 --name sql1 -h sql1 -d mcr.microsoft.com/mssql/server:2019-latest'
- script: 'docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=$(defaultSql2022_password)" -e "MSSQL_AGENT_ENABLED=True" -p 1433:1433 --name sql1 -h sql1 -d mcr.microsoft.com/mssql/server:2022-latest'
displayName: Starting Server in Docker Container
- task: UseDotNet@2
@@ -51,7 +51,7 @@ steps:
arguments: $(testEnvironmentPath.secureFilePath)
testRunTitle: 'Setting tests'
env:
defaultSql2019_password: '$(defaultSql2019_password)'
defaultSql2022_password: '$(defaultSql2022_password)'
- task: AzureKeyVault@1
displayName: 'Azure Key Vault: SqlToolsSecretStore'

View File

@@ -123,8 +123,9 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting.Contracts
/// Script110Compat
/// Script120Compat
/// Script130Compat
/// Script140Compat
/// Script150Compat
/// Script140Compat
/// Script150Compat
/// Script160Compat
/// </summary>
/// <remarks>
/// The default is Script140Compat.

View File

@@ -296,7 +296,9 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting
/// Script110Compat
/// Script120Compat
/// Script130Compat
/// Script140Compat
/// Script140Compat
/// Script150Compat
/// Script160Compat
/// </summary>
/// <remarks>
/// The default is Script140Compat.

View File

@@ -193,6 +193,7 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting
{
return new Dictionary<string, SqlServerVersion>
{
{SqlScriptOptions.ScriptCompatibilityOptions.Script160Compat.ToString(), SqlServerVersion.Version160},
{SqlScriptOptions.ScriptCompatibilityOptions.Script150Compat.ToString(), SqlServerVersion.Version150},
{SqlScriptOptions.ScriptCompatibilityOptions.Script140Compat.ToString(), SqlServerVersion.Version140},
{SqlScriptOptions.ScriptCompatibilityOptions.Script130Compat.ToString(), SqlServerVersion.Version130},

View File

@@ -2245,6 +2245,30 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
public static string UpdatableLedger_LabelPart
{
get
{
return Keys.GetString(Keys.UpdatableLedger_LabelPart);
}
}
public static string AppendOnlyLedger_LabelPart
{
get
{
return Keys.GetString(Keys.AppendOnlyLedger_LabelPart);
}
}
public static string Ledger_LabelPart
{
get
{
return Keys.GetString(Keys.Ledger_LabelPart);
}
}
public static string External_LabelPart
{
get
@@ -10622,6 +10646,15 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string SystemVersioned_LabelPart = "SystemVersioned_LabelPart";
public const string UpdatableLedger_LabelPart = "UpdatableLedger_LabelPart";
public const string AppendOnlyLedger_LabelPart = "AppendOnlyLedger_LabelPart";
public const string Ledger_LabelPart = "Ledger_LabelPart";
public const string External_LabelPart = "External_LabelPart";

View File

@@ -1380,6 +1380,18 @@
<value>System-Versioned</value>
<comment></comment>
</data>
<data name="UpdatableLedger_LabelPart" xml:space="preserve">
<value>Updatable Ledger</value>
<comment></comment>
</data>
<data name="AppendOnlyLedger_LabelPart" xml:space="preserve">
<value>Append-Only Ledger</value>
<comment></comment>
</data>
<data name="Ledger_LabelPart" xml:space="preserve">
<value>Ledger</value>
<comment></comment>
</data>
<data name="External_LabelPart" xml:space="preserve">
<value>External</value>
<comment></comment>

View File

@@ -680,6 +680,12 @@ History_LabelPart = History
SystemVersioned_LabelPart = System-Versioned
UpdatableLedger_LabelPart = Updatable Ledger
AppendOnlyLedger_LabelPart = Append-Only Ledger
Ledger_LabelPart = Ledger
External_LabelPart = External
FileTable_LabelPart = File Table

View File

@@ -6254,6 +6254,21 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Average Row Size</target>
<note></note>
</trans-unit>
<trans-unit id="UpdatableLedger_LabelPart">
<source>Updatable Ledger</source>
<target state="new">Updatable Ledger</target>
<note></note>
</trans-unit>
<trans-unit id="AppendOnlyLedger_LabelPart">
<source>Append-Only Ledger</source>
<target state="new">Append-Only Ledger</target>
<note></note>
</trans-unit>
<trans-unit id="Ledger_LabelPart">
<source>Ledger</source>
<target state="new">Ledger</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -17,27 +17,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
/// <summary>
/// Property name
/// </summary>
public string Property { get; set; }
public string Property { get; set; } = string.Empty;
/// <summary>
/// Filter values
/// </summary>
public List<object> Values { get; set; }
public List<object> Values { get; set; } = default!;
/// <summary>
/// Type of the filter values
/// </summary>
public Type Type { get; set; }
public Type Type { get; set; } = default!;
/// <summary>
/// Indicates which platforms a filter is valid for
/// </summary>
public ValidForFlag ValidFor { get; set; }
public ValidForFlag ValidFor { get; set; } = ValidForFlag.None;
/// <summary>
/// The type of the Querier the filter can be applied to
/// </summary>
public Type TypeToReverse { get; set; }
public Type TypeToReverse { get; set; } = default!;
/// <summary>
/// Returns true if the filter can be apply to the given type and Server type

View File

@@ -29,6 +29,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
child.IsAlwaysLeaf = true;
}
}
public override string GetNodeSubType(object smoObject, SmoQueryContext smoContext)
{
try
{
Database? db = smoObject as Database;
if (db != null && IsPropertySupported("IsLedger", smoContext, db, CachedSmoProperties) && db.IsLedger)
{
return "Ledger";
}
}
catch
{
//Ignore the exception and just not change create custom name
}
return string.Empty;
}
}
internal static class DatabasesCustomNodeHelper
@@ -38,12 +56,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
internal static bool GetDatabaseIsUnavailable(object smoObject, SmoQueryContext smoContext, IEnumerable<NodeSmoProperty> supportedProperties)
{
Database db = smoObject as Database;
Database? db = smoObject as Database;
if (db != null && SmoChildFactoryBase.IsPropertySupported("Status", smoContext, db, supportedProperties))
{
DatabaseStatus status;
try
{
{
status = db.Status;
}
catch (SqlServer.Management.Common.ConnectionFailureException)
@@ -66,12 +84,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
internal static string GetStatus(object smoObject, SmoQueryContext smoContext, IEnumerable<NodeSmoProperty> supportedProperties)
{
Database db = smoObject as Database;
Database? db = smoObject as Database;
if (db != null && SmoChildFactoryBase.IsPropertySupported("Status", smoContext, db, supportedProperties))
{
DatabaseStatus status;
try
{
{
status = db.Status;
}
catch (SqlServer.Management.Common.ConnectionFailureException)
@@ -102,7 +120,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
else if ((status & DatabaseStatus.Inaccessible) == DatabaseStatus.Inaccessible)
{
return "Inaccessible";
}
}
else if ((status & DatabaseStatus.Shutdown) == DatabaseStatus.Shutdown)
{
return "Shutdown";
@@ -118,7 +136,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
else if ((status & DatabaseStatus.AutoClosed) == DatabaseStatus.AutoClosed)
{
return "Auto Closed";
}
}
}
return string.Empty;

View File

@@ -16,7 +16,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
try
{
Table table = smoObject as Table;
Table? table = smoObject as Table;
if (table != null && IsPropertySupported("LedgerType", smoContext, table, CachedSmoProperties))
{
if (table.LedgerType == LedgerTableType.AppendOnlyLedgerTable)
{
return $"{table.Schema}.{table.Name} ({SR.AppendOnlyLedger_LabelPart})";
}
else if (table.LedgerType == LedgerTableType.UpdatableLedgerTable)
{
return $"{table.Schema}.{table.Name} ({SR.UpdatableLedger_LabelPart})";
}
}
if (table != null && IsPropertySupported("IsSystemVersioned", smoContext, table, CachedSmoProperties) && table.IsSystemVersioned)
{
return $"{table.Schema}.{table.Name} ({SR.SystemVersioned_LabelPart})";
@@ -42,7 +53,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
try
{
Table table = smoObject as Table;
Table? table = smoObject as Table;
if (table != null && IsPropertySupported("LedgerType", smoContext, table, CachedSmoProperties) &&
(table.LedgerType == LedgerTableType.AppendOnlyLedgerTable || table.LedgerType == LedgerTableType.UpdatableLedgerTable))
{
return "Ledger";
}
if (table != null && IsPropertySupported("TemporalType", smoContext, table, CachedSmoProperties) && table.TemporalType != TableTemporalType.None)
{
return "Temporal";
@@ -70,13 +86,13 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
}
/// <summary>
/// Custom name for history table
/// Custom name and icon for history table
/// </summary>
internal partial class TableChildFactory : SmoChildFactoryBase
{
public override string GetNodeCustomName(object smoObject, SmoQueryContext smoContext)
{
Table table = smoObject as Table;
Table? table = smoObject as Table;
if (table != null)
{
return $"{table.Schema}.{table.Name} ({SR.History_LabelPart})";
@@ -85,6 +101,22 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
return string.Empty;
}
public override string GetNodeSubType(object smoObject, SmoQueryContext smoContext)
{
try
{
Table? table = smoObject as Table;
if (table != null && IsPropertySupported("LedgerType", smoContext, table, CachedSmoProperties) &&
table.LedgerType == LedgerTableType.HistoryTable)
{
return "LedgerHistory";
}
}
catch {}
return string.Empty;
}
public override string GetNodePathName(object smoObject)
{
return TableCustomNodeHelper.GetPathName(smoObject);
@@ -95,7 +127,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
internal static string GetPathName(object smoObject)
{
Table table = smoObject as Table;
Table? table = smoObject as Table;
if (table != null)
{
return $"{table.Schema}.{table.Name}";

View File

@@ -785,6 +785,18 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{ TableTemporalType.SystemVersioned }
}
});
filters.Add(new NodePropertyFilter
{
Property = "LedgerType",
Type = typeof(Enum),
ValidFor = ValidForFlag.Sql2022|ValidForFlag.AzureV12,
Values = new List<object>
{
{ LedgerTableType.None },
{ LedgerTableType.AppendOnlyLedgerTable },
{ LedgerTableType.UpdatableLedgerTable }
}
});
return filters;
}
}
@@ -810,6 +822,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12
});
properties.Add(new NodeSmoProperty
{
Name = "LedgerType",
ValidFor = ValidForFlag.Sql2022|ValidForFlag.AzureV12
});
properties.Add(new NodeSmoProperty
{
Name = "IsExternal",
ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12|ValidForFlag.SqlOnDemand
@@ -1312,21 +1329,56 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
get
{
var filters = new List<INodeFilter>();
filters.Add(new NodePropertyFilter
filters.Add(new NodeOrFilter
{
Property = "TemporalType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlHistoryTableQuerier),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12,
Values = new List<object>
{
{ TableTemporalType.HistoryTable }
FilterList = new List<NodePropertyFilter> {
new NodePropertyFilter
{
Property = "TemporalType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlHistoryTableQuerier),
ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12,
Values = new List<object>
{
{ TableTemporalType.HistoryTable }
}
},
new NodePropertyFilter
{
Property = "LedgerType",
Type = typeof(Enum),
TypeToReverse = typeof(SqlHistoryTableQuerier),
ValidFor = ValidForFlag.Sql2022|ValidForFlag.AzureV12,
Values = new List<object>
{
{ LedgerTableType.HistoryTable }
}
},
}
});
return filters;
}
}
public override IEnumerable<NodeSmoProperty> SmoProperties
{
get
{
var properties = new List<NodeSmoProperty>();
properties.Add(new NodeSmoProperty
{
Name = "LedgerType",
ValidFor = ValidForFlag.Sql2022|ValidForFlag.AzureV12
});
properties.Add(new NodeSmoProperty
{
Name = "TemporalType",
ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12
});
return properties;
}
}
protected override void OnExpandPopulateFolders(IList<TreeNode> currentChildren, TreeNode parent)
{
currentChildren.Add(new FolderNode {

View File

@@ -71,17 +71,23 @@
</Node>
<Node Name="Tables" LocLabel="SR.SchemaHierarchy_Tables" BaseClass="ModelBased" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable" TreeNode="TableTreeNode">
<Filters >
<Filters>
<Filter Property="IsSystemObject" Value="0" Type="bool" />
<Filter Property="TemporalType" Type="Enum" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12">
<Value>TableTemporalType.None</Value>
<Value>TableTemporalType.SystemVersioned</Value>
</Filter>
<Filter Property="LedgerType" Type="Enum" ValidFor="Sql2022|AzureV12">
<Value>LedgerTableType.None</Value>
<Value>LedgerTableType.AppendOnlyLedgerTable</Value>
<Value>LedgerTableType.UpdatableLedgerTable</Value>
</Filter>
</Filters>
<Properties>
<Property Name="IsFileTable" ValidFor="Sql2012|Sql2014|Sql2016|Sql2017|Sql2019|Sql2022"/>
<Property Name="IsSystemVersioned" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12"/>
<Property Name="TemporalType" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12"/>
<Property Name="TemporalType" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12"/>
<Property Name="LedgerType" ValidFor="Sql2022|AzureV12"/>
<Property Name="IsExternal" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12|SqlOnDemand"/>
</Properties>
<Child Name="SystemTables" IsSystemObject="1"/>
@@ -169,10 +175,19 @@
-->
<Node Name="Table" LocLabel="string.Empty" BaseClass="ModelBased" IsAsyncLoad="" Strategy="MultipleElementsOfType" ChildQuerierTypes="SqlTable;SqlHistoryTable" TreeNode="HistoryTableTreeNode">
<Filters>
<Filter TypeToReverse="SqlHistoryTable" Property="TemporalType" Type="Enum" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12">
<Value>TableTemporalType.HistoryTable</Value>
</Filter>
<Or>
<Filter TypeToReverse="SqlHistoryTable" Property="TemporalType" Type="Enum" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12">
<Value>TableTemporalType.HistoryTable</Value>
</Filter>
<Filter TypeToReverse="SqlHistoryTable" Property="LedgerType" Type="Enum" ValidFor="Sql2022|AzureV12">
<Value>LedgerTableType.HistoryTable</Value>
</Filter>
</Or>
</Filters>
<Properties>
<Property Name="LedgerType" ValidFor="Sql2022|AzureV12"/>
<Property Name="TemporalType" ValidFor="Sql2016|Sql2017|Sql2019|Sql2022|AzureV12"/>
</Properties>
<Child Name="Columns"/>
<Child Name="Keys"/>
<Child Name="Constraints"/>

View File

@@ -0,0 +1,67 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlServer.Management.Smo;
namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel
{
/// <summary>
/// Custom name for view
/// </summary>
internal partial class ViewsChildFactory : SmoChildFactoryBase
{
public override string GetNodeCustomName(object smoObject, SmoQueryContext smoContext)
{
try
{
View? view = smoObject as View;
if (view != null &&
IsPropertySupported("LedgerViewType", smoContext, view, CachedSmoProperties) &&
view.LedgerViewType == LedgerViewType.LedgerView)
{
return $"{view.Schema}.{view.Name} ({SR.Ledger_LabelPart})";
}
}
catch {} //Ignore the exception and just not change create custom name
return string.Empty;
}
public override string GetNodeSubType(object smoObject, SmoQueryContext smoContext)
{
try
{
View? view = smoObject as View;
if (view != null && IsPropertySupported("LedgerViewType", smoContext, view, CachedSmoProperties) &&
view.LedgerViewType == LedgerViewType.LedgerView)
{
return "Ledger";
}
}
catch {} //Ignore the exception and just not change create custom name
return string.Empty;
}
public override string GetNodePathName(object smoObject)
{
return ViewCustomNodeHelper.GetPathName(smoObject);
}
}
internal static class ViewCustomNodeHelper
{
internal static string GetPathName(object smoObject)
{
View? view = smoObject as View;
if (view != null)
{
return $"{view.Schema}.{view.Name}";
}
return string.Empty;
}
}
}

View File

@@ -123,8 +123,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts
/// Script110Compat
/// Script120Compat
/// Script130Compat
/// Script140Compat
/// Script150Compat
/// Script140Compat
/// Script150Compat
/// Script160Compat
/// </summary>
/// <remarks>
/// The default is Script140Compat.

View File

@@ -296,7 +296,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
/// Script110Compat
/// Script120Compat
/// Script130Compat
/// Script140Compat
/// Script140Compat
/// Script150Compat
/// Script160Compat
/// </summary>
/// <remarks>
/// The default is Script140Compat.

View File

@@ -552,6 +552,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
{
return new Dictionary<string, SqlServerVersion>
{
{SqlScriptOptions.ScriptCompatibilityOptions.Script160Compat.ToString(), SqlServerVersion.Version160},
{SqlScriptOptions.ScriptCompatibilityOptions.Script150Compat.ToString(), SqlServerVersion.Version150},
{SqlScriptOptions.ScriptCompatibilityOptions.Script140Compat.ToString(), SqlServerVersion.Version140},
{SqlScriptOptions.ScriptCompatibilityOptions.Script130Compat.ToString(), SqlServerVersion.Version130},

View File

@@ -46,6 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
serverVersionMap.Add(13, "Script140Compat");
serverVersionMap.Add(14, "Script140Compat");
serverVersionMap.Add(15, "Script140Compat");
serverVersionMap.Add(16, "Script160Compat");
// Mapping the object types for scripting
objectScriptMap.Add("table", "Table");

View File

@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -471,7 +472,28 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
if (!string.IsNullOrEmpty(baseline))
{
string actual = stringBuilder.ToString();
Assert.That(actual, Is.EqualTo(baseline), $"Baseline comparison for {baselineFileName} failed");
// write output to a bin directory for easier comparison
string outputRegeneratedFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
@"ObjectExplorerServiceTests\Baselines\Regenerated");
string outputRegeneratedFilePath = Path.Combine(outputRegeneratedFolder, baselineFileName);
string msg = "";
try
{
Directory.CreateDirectory(outputRegeneratedFolder);
File.WriteAllText(outputRegeneratedFilePath, actual);
msg = $"Generated output written to :\t{outputRegeneratedFilePath}\n\t" +
$"Baseline output located at :\t{GetBaseLineFile(baselineFileName)}";
}
catch (Exception e)
{
//We don't want to fail the test completely if we failed to write the regenerated baseline
//(especially if the test passed).
msg = $"Errors also occurred while attempting to write the new baseline file {outputRegeneratedFilePath} : {e.Message}";
}
Assert.That(actual, Is.EqualTo(baseline), $"Baseline comparison for {baselineFileName} failed\n\t" + msg);
}
});

View File

@@ -50,12 +50,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{
if (!string.IsNullOrEmpty(instance.Password))
{
if (!credentialService.SaveCredential(instance))
{
Console.WriteLine("Failed to store the password for server: " + instance.ServerName);
}
instance.Password = null; //Make sure the password is not stored in sqlConnectionSettings.json
instance.AuthenticationType = AuthenticationType.SqlLogin;
}
@@ -64,7 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
instance.AuthenticationType = AuthenticationType.Integrated;
}
}
Console.WriteLine("The SQL connection instances will be written to " + DefaultSettingFileName);
string jsonContent = JsonConvert.SerializeObject(connectionSetting);
@@ -133,8 +133,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{
testServerNameFilePath = FileUtils.TestServerNamesDefaultFileName;
}
Console.WriteLine($"Test server name file path: {testServerNameFilePath}");
string testServerNamesFileContent = string.IsNullOrEmpty(testServerNameFilePath) ? string.Empty : File.ReadAllText(testServerNameFilePath);
Console.WriteLine($"Test server name file content: {testServerNamesFileContent}");
return testServerNamesFileContent;
}
@@ -171,7 +172,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
}
string settingsFileContents = string.IsNullOrEmpty(settingsFileName) ? string.Empty : File.ReadAllText(settingsFileName);
Console.WriteLine($"SQL Connection settings file content: {settingsFileContents}");
return settingsFileContents;
}
}

View File

@@ -32,6 +32,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
public const string DefaultSqlAzureV12InstanceKey = "defaultSqlAzureV12";
public const string DefaultSql2016InstanceKey = "defaultSql2016";
public const string DefaultSql2019InstanceKey = "defaultSql2019";
public const string DefaultSql2022InstanceKey = "defaultSql2022";
public const string DefaultSqlvNextInstanceKey = "defaultSqlvNext";
private TestConnectionProfileService()
@@ -72,11 +73,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
get { return GetInstance(DefaultSql2016InstanceKey); }
}
public static InstanceInfo DefaultSql2019
public static InstanceInfo DefaultSql2019
{
get { return GetInstance(DefaultSql2019InstanceKey); }
}
public static InstanceInfo DefaultSql2022
{
get { return GetInstance(DefaultSql2022InstanceKey); }
}
public static InstanceInfo DefaultSqlvNext
{
get { return GetInstance(DefaultSqlvNextInstanceKey); }
@@ -93,7 +99,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
return instanceInfo;
}
public ConnectParams GetConnectionParameters(string key = DefaultSql2019InstanceKey, string databaseName = null)
public ConnectParams GetConnectionParameters(string key = DefaultSql2022InstanceKey, string databaseName = null)
{
InstanceInfo instanceInfo = GetInstance(key);
if (instanceInfo != null)
@@ -111,7 +117,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
public ConnectParams GetConnectionParameters(TestServerType serverType = TestServerType.OnPrem, string databaseName = null)
{
string key = ConvertServerTypeToVersionKey(serverType);
return GetConnectionParameters(key, databaseName);
return GetConnectionParameters(key, databaseName);
}
/// <summary>
@@ -134,7 +140,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
foreach (var serverIdentity in testServers)
{
var instance = settings != null ? settings.GetConnectionProfile(serverIdentity.ProfileName, serverIdentity.ServerName) : null;
if (instance.ServerType == TestServerType.None)
if (instance?.ServerType == TestServerType.None)
{
instance.ServerType = serverIdentity.ServerType;
AddInstance(instance);
@@ -149,7 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
}
}
}
catch(Exception ex)
catch (Exception ex)
{
Assert.True(false, "Fail to load the SQL connection instances. error: " + ex.Message);
}
@@ -157,6 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
private static void AddInstance(InstanceInfo instance)
{
Console.WriteLine($"Checking whether instance should be added to connections cache, server type: {instance.ServerType.ToString()}, version key: {instance.VersionKey}");
if (instance != null && (instance.ServerType != TestServerType.None || !string.IsNullOrEmpty(instance.VersionKey)))
{
TestServerType serverType = instance.ServerType == TestServerType.None ? TestServerType.OnPrem : instance.ServerType; //Default to onPrem
@@ -170,13 +177,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
instance.Password = credential.Password;
}
connectionProfilesCache.Add(versionKey, instance);
Console.WriteLine("Instance added.");
}
else
{
Console.WriteLine("Instance already in the cache.");
}
}
else
{
Console.WriteLine("Instance skipped.");
}
}
private static string ConvertServerTypeToVersionKey(TestServerType serverType)
{
return serverType == TestServerType.OnPrem ? DefaultSql2019InstanceKey : DefaultSqlAzureV12InstanceKey;
return serverType == TestServerType.OnPrem ? DefaultSql2022InstanceKey : DefaultSqlAzureV12InstanceKey;
}
/// <summary>

View File

@@ -51,6 +51,59 @@ NodeType: Index Label: NonClusteredIndex-Login (Non-Unique, Non-Clustered) SubTy
NodeType: Index Label: PK_Employee_BusinessEntityID (Unique, Clustered) SubType:PrimaryKey Status:
NodeType: Statistic Label: NonClusteredIndex-Login SubType: Status:
NodeType: Statistic Label: PK_Employee_BusinessEntityID SubType: Status:
NodeType: Table Label: HumanResources.Employee_Ledger (Updatable Ledger) SubType:Ledger Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
NodeType: Column Label: LoginID (nvarchar(256), not null) SubType: Status:
NodeType: Column Label: OrganizationNode (hierarchyid, null) SubType: Status:
NodeType: Column Label: OrganizationLevel (Computed, smallint, null) SubType: Status:
NodeType: Column Label: JobTitle (nvarchar(50), not null) SubType: Status:
NodeType: Column Label: BirthDate (date, not null) SubType: Status:
NodeType: Column Label: MaritalStatus (nchar(1), not null) SubType: Status:
NodeType: Column Label: Gender (nchar(1), not null) SubType: Status:
NodeType: Column Label: HireDate (date, not null) SubType: Status:
NodeType: Column Label: VacationHours (smallint, not null) SubType: Status:
NodeType: Column Label: SickLeaveHours (smallint, not null) SubType: Status:
NodeType: Column Label: ledger_start_transaction_id (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_end_transaction_id (bigint, null) SubType: Status:
NodeType: Column Label: ledger_start_sequence_number (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_end_sequence_number (bigint, null) SubType: Status:
NodeType: HistoryTable Label: HumanResources.Employee_Ledger_History (History) SubType:LedgerHistory Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
NodeType: Column Label: LoginID (nvarchar(256), not null) SubType: Status:
NodeType: Column Label: OrganizationNode (hierarchyid, null) SubType: Status:
NodeType: Column Label: OrganizationLevel (smallint, null) SubType: Status:
NodeType: Column Label: JobTitle (nvarchar(50), not null) SubType: Status:
NodeType: Column Label: BirthDate (date, not null) SubType: Status:
NodeType: Column Label: MaritalStatus (nchar(1), not null) SubType: Status:
NodeType: Column Label: Gender (nchar(1), not null) SubType: Status:
NodeType: Column Label: HireDate (date, not null) SubType: Status:
NodeType: Column Label: VacationHours (smallint, not null) SubType: Status:
NodeType: Column Label: SickLeaveHours (smallint, not null) SubType: Status:
NodeType: Column Label: ledger_start_transaction_id (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_end_transaction_id (bigint, null) SubType: Status:
NodeType: Column Label: ledger_start_sequence_number (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_end_sequence_number (bigint, null) SubType: Status:
NodeType: Table Label: HumanResources.Employee_Ledger_AppendOnly (Append-Only Ledger) SubType:Ledger Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
NodeType: Column Label: LoginID (nvarchar(256), not null) SubType: Status:
NodeType: Column Label: OrganizationNode (hierarchyid, null) SubType: Status:
NodeType: Column Label: OrganizationLevel (Computed, smallint, null) SubType: Status:
NodeType: Column Label: JobTitle (nvarchar(50), not null) SubType: Status:
NodeType: Column Label: BirthDate (date, not null) SubType: Status:
NodeType: Column Label: MaritalStatus (nchar(1), not null) SubType: Status:
NodeType: Column Label: Gender (nchar(1), not null) SubType: Status:
NodeType: Column Label: HireDate (date, not null) SubType: Status:
NodeType: Column Label: SalariedFlag (Flag(bit), not null) SubType: Status:
NodeType: Column Label: VacationHours (smallint, not null) SubType: Status:
NodeType: Column Label: SickLeaveHours (smallint, not null) SubType: Status:
NodeType: Column Label: CurrentFlag (Flag(bit), not null) SubType: Status:
NodeType: Column Label: rowguid (uniqueidentifier, not null) SubType: Status:
NodeType: Column Label: ModifiedDate (datetime, not null) SubType: Status:
NodeType: Column Label: ledger_start_transaction_id (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_start_sequence_number (bigint, not null) SubType: Status:
NodeType: Table Label: HumanResources.Employee_Temporal (System-Versioned) SubType:Temporal Status:
NodeType: Column Label: BusinessEntityID (PK, int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
@@ -107,6 +160,44 @@ NodeType: Constraint Label: DF_Person_ModifiedDate SubType: Status:
NodeType: Trigger Label: TableTrigger SubType: Status:
NodeType: Index Label: PK_Person_BusinessEntityID (Unique, Clustered) SubType:PrimaryKey Status:
NodeType: Statistic Label: PK_Person_BusinessEntityID SubType: Status:
NodeType: View Label: HumanResources.Employee_Ledger_AppendOnly_Ledger (Ledger) SubType:Ledger Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
NodeType: Column Label: LoginID (nvarchar(256), not null) SubType: Status:
NodeType: Column Label: OrganizationNode (hierarchyid, null) SubType: Status:
NodeType: Column Label: OrganizationLevel (smallint, null) SubType: Status:
NodeType: Column Label: JobTitle (nvarchar(50), not null) SubType: Status:
NodeType: Column Label: BirthDate (date, not null) SubType: Status:
NodeType: Column Label: MaritalStatus (nchar(1), not null) SubType: Status:
NodeType: Column Label: Gender (nchar(1), not null) SubType: Status:
NodeType: Column Label: HireDate (date, not null) SubType: Status:
NodeType: Column Label: SalariedFlag (Flag(bit), not null) SubType: Status:
NodeType: Column Label: VacationHours (smallint, not null) SubType: Status:
NodeType: Column Label: SickLeaveHours (smallint, not null) SubType: Status:
NodeType: Column Label: CurrentFlag (Flag(bit), not null) SubType: Status:
NodeType: Column Label: rowguid (uniqueidentifier, not null) SubType: Status:
NodeType: Column Label: ModifiedDate (datetime, not null) SubType: Status:
NodeType: Column Label: ledger_transaction_id (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_sequence_number (bigint, not null) SubType: Status:
NodeType: Column Label: ledger_operation_type (int, not null) SubType: Status:
NodeType: Column Label: ledger_operation_type_desc (nvarchar(6), not null) SubType: Status:
NodeType: View Label: HumanResources.Employee_Ledger_Ledger (Ledger) SubType:Ledger Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: NationalIDNumber (nvarchar(15), not null) SubType: Status:
NodeType: Column Label: LoginID (nvarchar(256), not null) SubType: Status:
NodeType: Column Label: OrganizationNode (hierarchyid, null) SubType: Status:
NodeType: Column Label: OrganizationLevel (smallint, null) SubType: Status:
NodeType: Column Label: JobTitle (nvarchar(50), not null) SubType: Status:
NodeType: Column Label: BirthDate (date, not null) SubType: Status:
NodeType: Column Label: MaritalStatus (nchar(1), not null) SubType: Status:
NodeType: Column Label: Gender (nchar(1), not null) SubType: Status:
NodeType: Column Label: HireDate (date, not null) SubType: Status:
NodeType: Column Label: VacationHours (smallint, not null) SubType: Status:
NodeType: Column Label: SickLeaveHours (smallint, not null) SubType: Status:
NodeType: Column Label: ledger_transaction_id (bigint, null) SubType: Status:
NodeType: Column Label: ledger_sequence_number (bigint, null) SubType: Status:
NodeType: Column Label: ledger_operation_type (int, not null) SubType: Status:
NodeType: Column Label: ledger_operation_type_desc (nvarchar(6), not null) SubType: Status:
NodeType: View Label: HumanResources.vEmployee SubType: Status:
NodeType: Column Label: BusinessEntityID (int, not null) SubType: Status:
NodeType: Column Label: Title (nvarchar(8), null) SubType: Status:

View File

@@ -94,9 +94,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TestEnvConfig
private static void SaveSettings(string settingFile)
{
Console.WriteLine($"settings file content: {File.ReadAllText(settingFile)}");
var xdoc = XDocument.Load(settingFile);
List<InstanceInfo> settings = new List<InstanceInfo>();
foreach (var setting in xdoc.Descendants("Instance"))
{
var passwordEnvVariableValue = Environment.GetEnvironmentVariable((setting.Attribute("VersionKey").Value + "_password"));

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Instances>
<Instance VersionKey="defaultSql2019">
<Instance VersionKey="defaultSql2022">
<DataSource>[server name]</DataSource>
<UserId>[user name for SQL authentication]</UserId>
<Password>[password for SQL authentication]</Password>