mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-25 01:25:40 -05:00
* Make nullable warnings a per file opt-in * Remove unneeded compiler directives * Remove compiler directive for User Data
114 lines
4.6 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|