From 5d2bf7fbe4d0ba32db0bca77b62ec88a0edb5b21 Mon Sep 17 00:00:00 2001 From: Sharon Ravindran Date: Thu, 15 Dec 2016 13:34:33 -0800 Subject: [PATCH] Feature/delete peek scripts (#174) * Delete temp script folder * Delete folder and refactor code * Add unit tests * create folder per workspace * Refactor and move creation to FileUtils * Separate multiple assignment --- .../LanguageServices/LanguageService.cs | 11 +++ .../LanguageServices/PeekDefinition.cs | 7 +- .../Utility/FileUtils.cs | 75 +++++++++++++++++++ .../Utility/TextUtilities.cs | 2 +- .../LanguageServer/PeekDefinitionTests.cs | 28 +++++++ 5 files changed, 118 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs index b123c76c..57096897 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs @@ -21,6 +21,7 @@ using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Workspace; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -216,6 +217,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices serviceHost.RegisterShutdownTask(async (shutdownParams, shutdownRequestContext) => { Logger.Write(LogLevel.Verbose, "Shutting down language service"); + DeletePeekDefinitionScripts(); await Task.FromResult(0); }); @@ -1232,5 +1234,14 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices return false; } } + + internal void DeletePeekDefinitionScripts() + { + // Delete temp folder created to store peek definition scripts + if (FileUtils.SafeDirectoryExists(FileUtils.PeekDefinitionTempFolder)) + { + FileUtils.SafeDirectoryDelete(FileUtils.PeekDefinitionTempFolder, true); + } + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs index d01d1d26..0f556944 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/PeekDefinition.cs @@ -10,8 +10,9 @@ using System.Data.SqlClient; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.SqlParser.Intellisense; -using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.QueryExecution; +using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -47,9 +48,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices { this.serverConnection = serverConnection; this.connectionInfo = connInfo; - - DirectoryInfo tempScriptDirectory = Directory.CreateDirectory(Path.GetTempPath() + "mssql_definition"); - this.tempPath = tempScriptDirectory.FullName; + this.tempPath = FileUtils.GetPeekDefinitionTempFolder(); Initialize(); } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/FileUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/FileUtils.cs index d795c2c2..6f8a3fb8 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Utility/FileUtils.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/FileUtils.cs @@ -8,6 +8,46 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution { internal static class FileUtils { + internal static string PeekDefinitionTempFolder = Path.GetTempPath() + "mssql_definition"; + internal static bool PeekDefinitionTempFolderCreated = false; + + internal static string GetPeekDefinitionTempFolder() + { + string tempPath; + if (!PeekDefinitionTempFolderCreated) + { + try + { + // create new temp folder + string tempFolder = string.Format("{0}_{1}", FileUtils.PeekDefinitionTempFolder, DateTime.Now.ToString("yyyyMMddHHmmssffff")); + DirectoryInfo tempScriptDirectory = Directory.CreateDirectory(tempFolder); + FileUtils.PeekDefinitionTempFolder = tempScriptDirectory.FullName; + tempPath = tempScriptDirectory.FullName; + PeekDefinitionTempFolderCreated = true; + } + catch (Exception) + { + // swallow exception and use temp folder to store scripts + tempPath = Path.GetTempPath(); + } + } + else + { + try + { + // use tempDirectory name created previously + DirectoryInfo tempScriptDirectory = Directory.CreateDirectory(FileUtils.PeekDefinitionTempFolder); + tempPath = tempScriptDirectory.FullName; + } + catch (Exception) + { + // swallow exception and use temp folder to store scripts + tempPath = Path.GetTempPath(); + } + } + return tempPath; + } + /// /// Checks if file exists and swallows exceptions, if any /// @@ -42,5 +82,40 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution } } + /// + /// Checks if file exists and swallows exceptions, if any + /// + /// path of the file + /// + internal static bool SafeDirectoryExists(string path) + { + try + { + return Directory.Exists(path); + } + catch (Exception) + { + // Swallow exception + return false; + } + } + + + /// + /// Deletes a directory and swallows exceptions, if any + /// + /// + internal static void SafeDirectoryDelete(string path, bool recursive) + { + try + { + Directory.Delete(path, recursive); + } + catch (Exception) + { + // Swallow exception, do nothing + } + } + } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/TextUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/TextUtilities.cs index 979d697b..f06c654c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Utility/TextUtilities.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/TextUtilities.cs @@ -6,7 +6,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility { public static class TextUtilities - { + { /// /// Find the position of the cursor in the SQL script content buffer and return previous new line position /// diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs index ac55d9cd..a4490505 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/LanguageServer/PeekDefinitionTests.cs @@ -19,6 +19,7 @@ using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts; using Microsoft.SqlTools.ServiceLayer.LanguageServices; using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; using Microsoft.SqlTools.ServiceLayer.SqlContext; +using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution; using Microsoft.SqlTools.ServiceLayer.Workspace; using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; @@ -194,6 +195,33 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices Assert.Equal(actualSchemaName, expectedSchemaName); } + /// + /// Test Deletion of peek definition scripts for a valid temp folder that exists + /// + [Fact] + public void DeletePeekDefinitionScriptsTest() + { + PeekDefinition peekDefinition = new PeekDefinition(null, null); + var languageService = LanguageService.Instance; + Assert.True(Directory.Exists(FileUtils.PeekDefinitionTempFolder)); + languageService.DeletePeekDefinitionScripts(); + Assert.False(Directory.Exists(FileUtils.PeekDefinitionTempFolder)); + } + + /// + /// Test Deletion of peek definition scripts for a temp folder that does not exist + /// + [Fact] + public void DeletePeekDefinitionScriptsWhenFolderDoesNotExistTest() + { + var languageService = LanguageService.Instance; + PeekDefinition peekDefinition = new PeekDefinition(null, null); + FileUtils.SafeDirectoryDelete(FileUtils.PeekDefinitionTempFolder, true); + Assert.False(Directory.Exists(FileUtils.PeekDefinitionTempFolder)); + // Expected not to throw any exception + languageService.DeletePeekDefinitionScripts(); + } + #if LIVE_CONNECTION_TESTS /// /// Test get definition for a table object with active connection