From 7ec5549a13045bb0eced0893e6f6cbbe21233f4f Mon Sep 17 00:00:00 2001 From: Leila Lali Date: Wed, 17 May 2017 09:35:55 -0700 Subject: [PATCH] fixed the bug with not closing data reader for oe (#352) * fixed the bug with not closing data reader for oe * fixed the bug with triggers not sending back status --- .../SmoModel/SmoChildFactoryBase.cs | 9 +++- .../ObjectExplorer/SmoModel/SmoQuerier.cs | 24 +++++++---- .../SmoModel/SmoTriggerCustomNode.cs | 43 ++++++++++++++++--- .../ObjectExplorerServiceTests.cs | 36 ++++++++++++++++ 4 files changed, 95 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs index 11d61eda..d2b460f9 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoChildFactoryBase.cs @@ -23,18 +23,23 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public override IEnumerable Expand(TreeNode parent, bool refresh) { + List allChildren = new List(); + try { - List allChildren = new List(); OnExpandPopulateFolders(allChildren, parent); RemoveFoldersFromInvalidSqlServerVersions(allChildren, parent); OnExpandPopulateNonFolders(allChildren, parent, refresh); OnBeginAsyncOperations(parent); - return allChildren; + } + catch(Exception ex) + { + Logger.Write(LogLevel.Error, $"Failed expanding oe children. error:{ex.Message} {ex.StackTrace}"); } finally { } + return allChildren; } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs index 5595e27c..3fdc3900 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoQuerier.cs @@ -22,6 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel public abstract class SmoQuerier : IComposableService { public abstract Type[] SupportedObjectTypes { get; } + private static object lockObject = new object(); /// /// Queries SMO for a collection of objects using the @@ -78,21 +79,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel /// protected HashSet GetUrns(EnumResult enumResult) { - HashSet urns = null; - if (enumResult != null && enumResult.Data != null) + lock (lockObject) { - urns = new HashSet(); - IDataReader reader = GetDataReader(enumResult.Data); - if (reader != null) + HashSet urns = null; + if (enumResult != null && enumResult.Data != null) { - while (reader.Read()) + urns = new HashSet(); + using (IDataReader reader = GetDataReader(enumResult.Data)) { - urns.Add(reader.GetString(0)); + if (reader != null) + { + while (reader.Read()) + { + urns.Add(reader.GetString(0)); + } + } } } - } - return urns; + return urns; + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTriggerCustomNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTriggerCustomNode.cs index e2325d82..e663ec84 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTriggerCustomNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/SmoTriggerCustomNode.cs @@ -10,14 +10,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel /// /// Status for triggers /// - public class SmoTriggerCustomNode + internal partial class TriggersChildFactory : SmoChildFactoryBase { - internal partial class TriggersChildFactory : SmoChildFactoryBase + public override string GetNodeStatus(object context) { - public override string GetNodeStatus(object context) - { - return TriggersCustomeNodeHelper.GetStatus(context); - } + return TriggersCustomeNodeHelper.GetStatus(context); + } + } + + internal partial class ServerLevelServerTriggersChildFactory : SmoChildFactoryBase + { + public override string GetNodeStatus(object context) + { + return TriggersCustomeNodeHelper.GetStatus(context); + } + } + + internal partial class DatabaseTriggersChildFactory : SmoChildFactoryBase + { + public override string GetNodeStatus(object context) + { + return TriggersCustomeNodeHelper.GetStatus(context); } } @@ -34,6 +47,24 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel } } + ServerDdlTrigger serverDdlTrigger = context as ServerDdlTrigger; + if (serverDdlTrigger != null) + { + if (!serverDdlTrigger.IsEnabled) + { + return "Disabled"; + } + } + + DatabaseDdlTrigger databaseDdlTrigger = context as DatabaseDdlTrigger; + if (databaseDdlTrigger != null) + { + if (!databaseDdlTrigger.IsEnabled) + { + return "Disabled"; + } + } + return string.Empty; } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs index 7f5e2306..2aadb17a 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectExplorer/ObjectExplorerServiceTests.cs @@ -75,6 +75,42 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer }); } + [Fact] + public async void VerifyServerTriggers() + { + var query = @"IF EXISTS (SELECT * FROM sys.server_triggers WHERE name = 'OE_ddl_trig_database') + + Begin + DROP TRIGGER OE_ddl_trig_database ON ALL SERVER + + ENd + GO + + CREATE TRIGGER OE_ddl_trig_database + ON ALL SERVER + FOR CREATE_DATABASE + AS + PRINT 'Database Created.' + GO + GO + Disable TRIGGER OE_ddl_trig_database ON ALL SERVER ;"; + string databaseName = "tempdb"; + await RunTest(databaseName, query, "TepmDb", async (testDbName, session) => + { + var serverChildren = await _service.ExpandNode(session, session.Root.GetNodePath()); + var serverObjectsNode = serverChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_ServerObjects); + var serverObjectsChildren = await _service.ExpandNode(session, serverObjectsNode.NodePath); + var triggersNode = serverObjectsChildren.FirstOrDefault(x => x.Label == SR.SchemaHierarchy_Triggers); + var triggersChildren = await _service.ExpandNode(session, triggersNode.NodePath); + var trigger = triggersChildren.FirstOrDefault(x => x.Label == "OE_ddl_trig_database"); + Assert.NotNull(trigger); + + Assert.True(trigger.NodeStatus == "Disabled"); + await TestServiceProvider.Instance.RunQueryAsync(TestServerType.OnPrem, testDbName, "DROP TRIGGER OE_ddl_trig_database"); + + }); + } + [Fact] public async void CreateSessionAndExpandOnTheDatabaseShouldReturnDatabaseAsTheRoot() {