Skip to content

Commit

Permalink
Return context after it has been generated (#2194)
Browse files Browse the repository at this point in the history
* Emit generate scripts complete event to client

* Rename Message to ErrorMessage

* Sets owner URI for complete params obj

* Setting complete flag explicitly

* Making errorMessage prop nullable

* Localizes error messages

* Return context scripts and remove script tabs

* Send event when script gen isn't needed

* Change notification to request endpoint

* test get context when context doesn't exist

* Stop reading old context files
  • Loading branch information
lewis-sanchez authored Aug 31, 2023
1 parent 3ba514c commit c0a0f27
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 77 deletions.
19 changes: 19 additions & 0 deletions src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,14 @@ public static string SqlCmdUnsupportedToken
}
}

public static string FailedToGenerateServerContextualizationScripts
{
get
{
return Keys.GetString(Keys.FailedToGenerateServerContextualizationScripts);
}
}

public static string PeekDefinitionNoResultsError
{
get
Expand Down Expand Up @@ -10862,6 +10870,11 @@ public static string ScriptTooLarge(int maxChars, int currentChars)
return Keys.GetString(Keys.ScriptTooLarge, maxChars, currentChars);
}

public static string WritingServerContextualizationToCacheError(string message)
{
return Keys.GetString(Keys.WritingServerContextualizationToCacheError, message);
}

public static string SerializationServiceUnsupportedFormat(string formatName)
{
return Keys.GetString(Keys.SerializationServiceUnsupportedFormat, formatName);
Expand Down Expand Up @@ -11431,6 +11444,12 @@ public class Keys
public const string ScriptTooLarge = "ScriptTooLarge";


public const string WritingServerContextualizationToCacheError = "WritingServerContextualizationToCacheError";


public const string FailedToGenerateServerContextualizationScripts = "FailedToGenerateServerContextualizationScripts";


public const string SerializationServiceUnsupportedFormat = "SerializationServiceUnsupportedFormat";


Expand Down
9 changes: 9 additions & 0 deletions src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,15 @@
<comment>.
Parameters: 0 - maxChars (int), 1 - currentChars (int) </comment>
</data>
<data name="WritingServerContextualizationToCacheError" xml:space="preserve">
<value>An error was encountered while writing server contextualization scripts to the cache. Error: {0}</value>
<comment>.
Parameters: 0 - message (string) </comment>
</data>
<data name="FailedToGenerateServerContextualizationScripts" xml:space="preserve">
<value>Failed to generate server contextualization scripts</value>
<comment></comment>
</data>
<data name="SerializationServiceUnsupportedFormat" xml:space="preserve">
<value>Unsupported Save Format: {0}</value>
<comment>.
Expand Down
7 changes: 7 additions & 0 deletions src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ ParsingErrorHeader (int lineNumber, int columnNumber) = Line {0}, column {1}

ScriptTooLarge (int maxChars, int currentChars) = The current script is too large for Parameterization for Always Encrypted, please disable Parameterization for Always Encrypted in Query Options (Query > Query Options > Execution > Advanced). Maximum allowable length: {0} characters, Current script length: {1} characters

############################################################################
# Server Contextualization Service

WritingServerContextualizationToCacheError (string message) = An error was encountered while writing server contextualization scripts to the cache. Error: {0}

FailedToGenerateServerContextualizationScripts = Failed to generate server contextualization scripts

############################################################################
# Serialization Service

Expand Down
13 changes: 12 additions & 1 deletion src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en">
<body>
Expand Down Expand Up @@ -7248,6 +7248,17 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Error parsing ScriptingListObjectsCompleteParams.ConnectionString property.</target>
<note></note>
</trans-unit>
<trans-unit id="WritingServerContextualizationToCacheError">
<source>An error was encountered while writing server contextualization scripts to the cache. Error: {0}</source>
<target state="new">An error was encountered while writing server contextualization scripts to the cache. Error: {0}</target>
<note>.
Parameters: 0 - message (string) </note>
</trans-unit>
<trans-unit id="FailedToGenerateServerContextualizationScripts">
<source>Failed to generate server contextualization scripts</source>
<target state="new">Failed to generate server contextualization scripts</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// 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.Metadata.Contracts
{
public class GenerateServerContextualizationParams
{
/// <summary>
/// The URI of the connection to generate context for.
/// </summary>
public string OwnerUri { get; set; }
}

public class GenerateServerContextualizationResult
{
/// <summary>
/// The generated server context.
/// </summary>
public string? Context { get; set; }
}

/// <summary>
/// Generate server context request endpoint.
/// </summary>
public class GenerateServerContextualizationRequest
{
public static readonly RequestType<GenerateServerContextualizationParams, GenerateServerContextualizationResult> Type =
RequestType<GenerateServerContextualizationParams, GenerateServerContextualizationResult>.Create("metadata/generateServerContext");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public class GetServerContextualizationParams
public class GetServerContextualizationResult
{
/// <summary>
/// An array containing the generated server context.
/// The generated server context.
/// </summary>
public string[] Context { get; set; }
public string? Context { get; set; }
}

public class GetServerContextualizationRequest
Expand Down
87 changes: 55 additions & 32 deletions src/Microsoft.SqlTools.ServiceLayer/Metadata/MetadataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void InitializeService(ServiceHost serviceHost)
serviceHost.SetRequestHandler(MetadataListRequest.Type, HandleMetadataListRequest, true);
serviceHost.SetRequestHandler(TableMetadataRequest.Type, HandleGetTableRequest, true);
serviceHost.SetRequestHandler(ViewMetadataRequest.Type, HandleGetViewRequest, true);
serviceHost.SetEventHandler(GenerateServerContextualizationNotification.Type, HandleGenerateServerContextualizationNotification, true);
serviceHost.SetRequestHandler(GenerateServerContextualizationRequest.Type, HandleGenerateServerContextualizationNotification, true);
serviceHost.SetRequestHandler(GetServerContextualizationRequest.Type, HandleGetServerContextualizationRequest, true);
}

Expand Down Expand Up @@ -125,11 +125,11 @@ internal static async Task HandleGetViewRequest(
/// Handles the event for generating server contextualization scripts.
/// </summary>
internal static Task HandleGenerateServerContextualizationNotification(GenerateServerContextualizationParams contextualizationParams,
EventContext eventContext)
RequestContext<GenerateServerContextualizationResult> requestContext)
{
_ = Task.Factory.StartNew(() =>
_ = Task.Factory.StartNew(async () =>
{
GenerateServerContextualization(contextualizationParams);
await GenerateServerContextualization(contextualizationParams, requestContext);
},
CancellationToken.None,
TaskCreationOptions.None,
Expand All @@ -143,7 +143,7 @@ internal static Task HandleGenerateServerContextualizationNotification(GenerateS
/// database objects like tables and views.
/// </summary>
/// <param name="contextualizationParams">The contextualization parameters.</param>
internal static void GenerateServerContextualization(GenerateServerContextualizationParams contextualizationParams)
internal static async Task GenerateServerContextualization(GenerateServerContextualizationParams contextualizationParams, RequestContext<GenerateServerContextualizationResult> requestContext)
{
MetadataService.ConnectionServiceInstance.TryFindConnection(contextualizationParams.OwnerUri, out ConnectionInfo connectionInfo);

Expand All @@ -153,26 +153,39 @@ internal static void GenerateServerContextualization(GenerateServerContextualiza
{
// If scripts have been generated within the last 30 days then there isn't a need to go through the process
// of generating scripts again.
if (!MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
{
return;
}

var scripts = SmoScripterHelpers.GenerateAllServerTableScripts(sqlConn);
if (scripts != null)
if (MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
{
try
var scripts = SmoScripterHelpers.GenerateAllServerTableScripts(sqlConn)?.ToArray();
if (scripts != null)
{
MetadataScriptTempFileStream.Write(connectionInfo.ConnectionDetails.ServerName, scripts);
try
{
await requestContext.SendResult(new GenerateServerContextualizationResult()
{
Context = string.Join('\n', scripts)
});

MetadataScriptTempFileStream.Write(connectionInfo.ConnectionDetails.ServerName, scripts);
}
catch (Exception ex)
{
Logger.Error($"An error was encountered while writing server contextualization scripts to the cache. Error: {ex.Message}");
await requestContext.SendError(ex);
}
}
catch (Exception ex)
else
{
Logger.Error($"An error was encountered while writing to the cache. Error: {ex.Message}");
Logger.Error("Failed to generate server contextualization scripts");
await requestContext.SendError(SR.FailedToGenerateServerContextualizationScripts);
}
}
else
{
Logger.Error("Failed to generate server scripts");
var generateContextResult = new GenerateServerContextualizationResult()
{
Context = null
};
await requestContext.SendResult(generateContextResult);
}
}
}
Expand Down Expand Up @@ -204,28 +217,38 @@ internal static Task HandleGetServerContextualizationRequest(GetServerContextual
internal static async Task GetServerContextualization(GetServerContextualizationParams contextualizationParams, RequestContext<GetServerContextualizationResult> requestContext)
{
MetadataService.ConnectionServiceInstance.TryFindConnection(contextualizationParams.OwnerUri, out ConnectionInfo connectionInfo);

if (connectionInfo != null)
// When the filed context is too old don't read it
if (MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
{
try
await requestContext.SendResult(new GetServerContextualizationResult
{
var scripts = MetadataScriptTempFileStream.Read(connectionInfo.ConnectionDetails.ServerName);
await requestContext.SendResult(new GetServerContextualizationResult
Context = null
});
}
else
{
if (connectionInfo != null)
{
try
{
var scripts = MetadataScriptTempFileStream.Read(connectionInfo.ConnectionDetails.ServerName).ToArray();
await requestContext.SendResult(new GetServerContextualizationResult
{
Context = string.Join('\n', scripts)
});
}
catch (Exception ex)
{
Context = scripts.ToArray()
});
Logger.Error("Failed to read scripts from the script cache");
await requestContext.SendError(ex);
}
}
catch (Exception ex)
else
{
Logger.Error("Failed to read scripts from the script cache");
await requestContext.SendError(ex);
Logger.Error("Failed to find connection info about the server.");
await requestContext.SendError("Failed to find connection info about the server.");
}
}
else
{
Logger.Error("Failed to find connection info about the server.");
await requestContext.SendError("Failed to find connection info about the server.");
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ private static IEnumerable<string> GenerateTableScripts(Server server)
var scripts = new List<string>();
foreach (var s in generatedScripts)
{
// Needed to remove '\r' and '\n' characters from script, so that an entire create script
// Needed to remove '\r', '\n', and '\t' characters from script, so that an entire create script
// can be written and read as a single line to and from a temp file. Since scripts aren't
// going to be read by people, and mainly sent to Copilot to generate accurate suggestions,
// going to be read by people, and sent to Copilot to generate accurate suggestions,
// a lack of formatting is fine.
var script = s.Replace("\r", string.Empty).Replace("\n", string.Empty);
var script = s.Replace("\r", string.Empty).Replace("\n", string.Empty).Replace("\t", string.Empty);
scripts.Add(script);
}

Expand Down
Loading

0 comments on commit c0a0f27

Please sign in to comment.