Files
sqltoolsservice/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ExecutionPlanService.cs
Karl Burtram f288bee294 Make nullable warnings a per file opt-in (#1842)
* Make nullable warnings a per file opt-in

* Remove unneeded compiler directives

* Remove compiler directive for User Data
2023-02-03 18:10:07 -08:00

114 lines
4.6 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using System.Threading.Tasks;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts;
using Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan;
using Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan.Comparison;
using Microsoft.SqlTools.ServiceLayer.Hosting;
namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
{
/// <summary>
/// Main class for Execution Plan Service functionality
/// </summary>
public sealed class ExecutionPlanService : IDisposable
{
private static readonly Lazy<ExecutionPlanService> instance = new Lazy<ExecutionPlanService>(() => new ExecutionPlanService());
private bool disposed;
/// <summary>
/// Construct a new Execution Plan Service instance with default parameters
/// </summary>
private ExecutionPlanService()
{
}
/// <summary>
/// Gets the singleton instance object
/// </summary>
public static ExecutionPlanService Instance
{
get { return instance.Value; }
}
/// <summary>
/// Service host object for sending/receiving requests/events.
/// Internal for testing purposes.
/// </summary>
internal IProtocolEndpoint ServiceHost { get; set; }
/// <summary>
/// Initializes the Execution Plan Service instance
/// </summary>
public void InitializeService(ServiceHost serviceHost)
{
ServiceHost = serviceHost;
ServiceHost.SetRequestHandler(GetExecutionPlanRequest.Type, HandleGetExecutionPlan, true);
ServiceHost.SetRequestHandler(ExecutionPlanComparisonRequest.Type, HandleExecutionPlanComparisonRequest, true);
}
private async Task HandleGetExecutionPlan(GetExecutionPlanParams requestParams, RequestContext<GetExecutionPlanResult> requestContext)
{
var plans = ExecutionPlanGraphUtils.CreateShowPlanGraph(requestParams.GraphInfo.GraphFileContent, "");
await requestContext.SendResult(new GetExecutionPlanResult
{
Graphs = plans
});
}
/// <summary>
/// Handles requests for color matching similar nodes.
/// </summary>
internal async Task HandleExecutionPlanComparisonRequest(
ExecutionPlanComparisonParams requestParams,
RequestContext<ExecutionPlanComparisonResult> requestContext)
{
var nodeBuilder = new XmlPlanNodeBuilder(ShowPlanType.Unknown);
var firstPlanXml = nodeBuilder.GetSingleStatementXml(requestParams.FirstExecutionPlanGraphInfo.GraphFileContent, requestParams.FirstExecutionPlanGraphInfo.PlanIndexInFile);
var firstGraphSet = ShowPlanGraph.ParseShowPlanXML(firstPlanXml, ShowPlanType.Unknown);
var firstRootNode = firstGraphSet?[0]?.Root;
var secondPlanXml = nodeBuilder.GetSingleStatementXml(requestParams.SecondExecutionPlanGraphInfo.GraphFileContent, requestParams.SecondExecutionPlanGraphInfo.PlanIndexInFile);
var secondGraphSet = ShowPlanGraph.ParseShowPlanXML(secondPlanXml, ShowPlanType.Unknown);
var secondRootNode = secondGraphSet?[0]?.Root;
var manager = new SkeletonManager();
var firstSkeletonNode = manager.CreateSkeleton(firstRootNode);
var secondSkeletonNode = manager.CreateSkeleton(secondRootNode);
manager.ColorMatchingSections(firstSkeletonNode, secondSkeletonNode, requestParams.IgnoreDatabaseName);
var firstGraphComparisonResultDTO = firstSkeletonNode.ConvertToDTO();
var secondGraphComparisonResultDTO = secondSkeletonNode.ConvertToDTO();
ExecutionPlanGraphUtils.CopyMatchingNodesIntoSkeletonDTO(firstGraphComparisonResultDTO, secondGraphComparisonResultDTO);
ExecutionPlanGraphUtils.CopyMatchingNodesIntoSkeletonDTO(secondGraphComparisonResultDTO, firstGraphComparisonResultDTO);
var result = new ExecutionPlanComparisonResult()
{
FirstComparisonResult = firstGraphComparisonResultDTO,
SecondComparisonResult = secondGraphComparisonResultDTO
};
await requestContext.SendResult(result);
}
/// <summary>
/// Disposes the Execution Plan Service
/// </summary>
public void Dispose()
{
if (!disposed)
{
disposed = true;
}
}
}
}