diff --git a/azure-pipelines/integrationtests.yml b/azure-pipelines/integrationtests.yml index 467b3ca6..5851fb2d 100644 --- a/azure-pipelines/integrationtests.yml +++ b/azure-pipelines/integrationtests.yml @@ -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' diff --git a/src/Microsoft.Kusto.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs b/src/Microsoft.Kusto.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs index e02aea2b..913d5f96 100644 --- a/src/Microsoft.Kusto.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs +++ b/src/Microsoft.Kusto.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs @@ -123,8 +123,9 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting.Contracts /// Script110Compat /// Script120Compat /// Script130Compat - /// Script140Compat - /// Script150Compat + /// Script140Compat + /// Script150Compat + /// Script160Compat /// /// /// The default is Script140Compat. diff --git a/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsOptions.cs b/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsOptions.cs index 745a773f..089bd422 100644 --- a/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsOptions.cs +++ b/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsOptions.cs @@ -296,7 +296,9 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting /// Script110Compat /// Script120Compat /// Script130Compat - /// Script140Compat + /// Script140Compat + /// Script150Compat + /// Script160Compat /// /// /// The default is Script140Compat. diff --git a/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs b/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs index 82fc3ec3..921d2359 100644 --- a/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs +++ b/src/Microsoft.Kusto.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs @@ -193,6 +193,7 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting { return new Dictionary { + {SqlScriptOptions.ScriptCompatibilityOptions.Script160Compat.ToString(), SqlServerVersion.Version160}, {SqlScriptOptions.ScriptCompatibilityOptions.Script150Compat.ToString(), SqlServerVersion.Version150}, {SqlScriptOptions.ScriptCompatibilityOptions.Script140Compat.ToString(), SqlServerVersion.Version140}, {SqlScriptOptions.ScriptCompatibilityOptions.Script130Compat.ToString(), SqlServerVersion.Version130}, diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index 00a0b60c..31c6f8b2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -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"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index 369fd5f6..118bcc61 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -1380,6 +1380,18 @@ System-Versioned + + Updatable Ledger + + + + Append-Only Ledger + + + + Ledger + + External diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 0e07856b..1ac60e70 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -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 diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index 1389dcf5..48338fe5 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -6254,6 +6254,21 @@ The Query Processor estimates that implementing the following index could improv Average Row Size + + Updatable Ledger + Updatable Ledger + + + + Append-Only Ledger + Append-Only Ledger + + + + Ledger + Ledger + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodePropertyFilter.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodePropertyFilter.cs index 2f428134..098d7176 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodePropertyFilter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/Nodes/NodePropertyFilter.cs @@ -17,27 +17,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes /// /// Property name /// - public string Property { get; set; } + public string Property { get; set; } = string.Empty; /// /// Filter values /// - public List Values { get; set; } + public List Values { get; set; } = default!; /// /// Type of the filter values /// - public Type Type { get; set; } + public Type Type { get; set; } = default!; /// /// Indicates which platforms a filter is valid for /// - public ValidForFlag ValidFor { get; set; } + public ValidForFlag ValidFor { get; set; } = ValidForFlag.None; /// /// The type of the Querier the filter can be applied to /// - public Type TypeToReverse { get; set; } + public Type TypeToReverse { get; set; } = default!; /// /// Returns true if the filter can be apply to the given type and Server type diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoDatabaseCustomNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoDatabaseCustomNode.cs index ccd7e221..2bd4201b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoDatabaseCustomNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoDatabaseCustomNode.cs @@ -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 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 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; diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTableCustomNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTableCustomNode.cs index 448f9035..5c7f2e57 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTableCustomNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTableCustomNode.cs @@ -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 } /// - /// Custom name for history table + /// Custom name and icon for history table /// 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}"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs index d290b7ea..8d8b29fa 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodes.cs @@ -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 + { + { 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(); - 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 - { - { TableTemporalType.HistoryTable } + FilterList = new List { + new NodePropertyFilter + { + Property = "TemporalType", + Type = typeof(Enum), + TypeToReverse = typeof(SqlHistoryTableQuerier), + ValidFor = ValidForFlag.Sql2016|ValidForFlag.Sql2017|ValidForFlag.Sql2019|ValidForFlag.Sql2022|ValidForFlag.AzureV12, + Values = new List + { + { TableTemporalType.HistoryTable } + } + }, + new NodePropertyFilter + { + Property = "LedgerType", + Type = typeof(Enum), + TypeToReverse = typeof(SqlHistoryTableQuerier), + ValidFor = ValidForFlag.Sql2022|ValidForFlag.AzureV12, + Values = new List + { + { LedgerTableType.HistoryTable } + } + }, } }); return filters; } } + public override IEnumerable SmoProperties + { + get + { + var properties = new List(); + 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 currentChildren, TreeNode parent) { currentChildren.Add(new FolderNode { diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml index 9bcea17b..b8d68710 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTreeNodesDefinition.xml @@ -71,17 +71,23 @@ - + TableTemporalType.None TableTemporalType.SystemVersioned + + LedgerTableType.None + LedgerTableType.AppendOnlyLedgerTable + LedgerTableType.UpdatableLedgerTable + - + + @@ -169,10 +175,19 @@ --> - - TableTemporalType.HistoryTable - + + + TableTemporalType.HistoryTable + + + LedgerTableType.HistoryTable + + + + + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoViewCustomNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoViewCustomNode.cs new file mode 100644 index 00000000..01b2bb5a --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoViewCustomNode.cs @@ -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 +{ + /// + /// Custom name for view + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs index d6250c3c..1d4d039f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Contracts/ScriptingOptions.cs @@ -123,8 +123,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting.Contracts /// Script110Compat /// Script120Compat /// Script130Compat - /// Script140Compat - /// Script150Compat + /// Script140Compat + /// Script150Compat + /// Script160Compat /// /// /// The default is Script140Compat. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs index d87b7e55..ca253c9b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsOptions.cs @@ -296,7 +296,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting /// Script110Compat /// Script120Compat /// Script130Compat - /// Script140Compat + /// Script140Compat + /// Script150Compat + /// Script160Compat /// /// /// The default is Script140Compat. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs index 398ebeb1..dd990f10 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/ScriptAsScriptingOperation.cs @@ -552,6 +552,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting { return new Dictionary { + {SqlScriptOptions.ScriptCompatibilityOptions.Script160Compat.ToString(), SqlServerVersion.Version160}, {SqlScriptOptions.ScriptCompatibilityOptions.Script150Compat.ToString(), SqlServerVersion.Version150}, {SqlScriptOptions.ScriptCompatibilityOptions.Script140Compat.ToString(), SqlServerVersion.Version140}, {SqlScriptOptions.ScriptCompatibilityOptions.Script130Compat.ToString(), SqlServerVersion.Version130}, diff --git a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs index acb7507c..488678df 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Scripting/Scripter.cs @@ -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"); diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs index 11cc2760..a09ec4a5 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs @@ -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); } }); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConfigPersistenceHelper.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConfigPersistenceHelper.cs index 0e7106e0..d54b9153 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConfigPersistenceHelper.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConfigPersistenceHelper.cs @@ -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; } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs index d191a09d..541ebe11 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestConnectionProfileService.cs @@ -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); } /// @@ -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; } /// diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/Baselines/AllSqlObjects.txt b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/Baselines/AllSqlObjects.txt index 8eba4bdc..e75c9836 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/Baselines/AllSqlObjects.txt +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/Baselines/AllSqlObjects.txt @@ -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: diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/TestScripts/AllSqlObjects.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/TestScripts/AllSqlObjects.sql index af4eea41..1e14691d 100644 Binary files a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/TestScripts/AllSqlObjects.sql and b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/ObjectExplorer/TestScripts/AllSqlObjects.sql differ diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/Program.cs b/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/Program.cs index 1f13269d..45cc7f17 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/Program.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/Program.cs @@ -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 settings = new List(); - foreach (var setting in xdoc.Descendants("Instance")) { var passwordEnvVariableValue = Environment.GetEnvironmentVariable((setting.Attribute("VersionKey").Value + "_password")); diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/SQLConnectionInstancesTemplate.xml b/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/SQLConnectionInstancesTemplate.xml index 422a01c9..8915b031 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/SQLConnectionInstancesTemplate.xml +++ b/test/Microsoft.SqlTools.ServiceLayer.TestEnvConfig/SQLConnectionInstancesTemplate.xml @@ -1,6 +1,6 @@ - + [server name] [user name for SQL authentication] [password for SQL authentication]