mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
* initial commit * Initial SqlProjects service + tests * Added SqlObject script tests; PR feedback * Added comments for contracts * Swapping SqlProjectResult for ResultStatus * Updating tests * Added automatic test base that provides a working directory and automatic cleanup.
141 lines
5.7 KiB
C#
141 lines
5.7 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.SqlServer.Dac.Projects;
|
|
using Microsoft.SqlTools.Hosting.Protocol;
|
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
|
using Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.SqlProjects
|
|
{
|
|
/// <summary>
|
|
/// Main class for SqlProjects service
|
|
/// </summary>
|
|
class SqlProjectsService
|
|
{
|
|
private static readonly Lazy<SqlProjectsService> instance = new Lazy<SqlProjectsService>(() => new SqlProjectsService());
|
|
|
|
/// <summary>
|
|
/// Gets the singleton instance object
|
|
/// </summary>
|
|
public static SqlProjectsService Instance => instance.Value;
|
|
|
|
private Lazy<ConcurrentDictionary<string, SqlProject>> projects = new Lazy<ConcurrentDictionary<string, SqlProject>>(() => new ConcurrentDictionary<string, SqlProject>(StringComparer.OrdinalIgnoreCase));
|
|
|
|
/// <summary>
|
|
/// <see cref="ConcurrentDictionary{String, TSqlModel}"/> that maps Project URI to Project
|
|
/// </summary>
|
|
public ConcurrentDictionary<string, SqlProject> Projects => projects.Value;
|
|
|
|
/// <summary>
|
|
/// Initializes the service instance
|
|
/// </summary>
|
|
/// <param name="serviceHost"></param>
|
|
public void InitializeService(ServiceHost serviceHost)
|
|
{
|
|
// Project-level functions
|
|
serviceHost.SetRequestHandler(OpenSqlProjectRequest.Type, HandleOpenSqlProjectRequest, isParallelProcessingSupported: true);
|
|
serviceHost.SetRequestHandler(CloseSqlProjectRequest.Type, HandleCloseSqlProjectRequest, isParallelProcessingSupported: true);
|
|
serviceHost.SetRequestHandler(NewSqlProjectRequest.Type, HandleNewSqlProjectRequest, isParallelProcessingSupported: true);
|
|
|
|
// SQL object script calls
|
|
serviceHost.SetRequestHandler(AddSqlObjectScriptRequest.Type, HandleAddSqlObjectScriptRequest, isParallelProcessingSupported: false);
|
|
serviceHost.SetRequestHandler(DeleteSqlObjectScriptRequest.Type, HandleDeleteSqlObjectScriptRequest, isParallelProcessingSupported: false);
|
|
serviceHost.SetRequestHandler(ExcludeSqlObjectScriptRequest.Type, HandleExcludeSqlObjectScriptRequest, isParallelProcessingSupported: false);
|
|
}
|
|
|
|
#region Handlers
|
|
|
|
#region Project-level functions
|
|
|
|
internal async Task HandleOpenSqlProjectRequest(SqlProjectParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri), requestContext);
|
|
}
|
|
|
|
internal async Task HandleCloseSqlProjectRequest(SqlProjectParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(() => Projects.TryRemove(requestParams.ProjectUri, out _), requestContext);
|
|
}
|
|
|
|
internal async Task HandleNewSqlProjectRequest(NewSqlProjectParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(async () =>
|
|
{
|
|
await SqlProject.CreateProjectAsync(requestParams.ProjectUri, requestParams.SqlProjectType, requestParams.DatabaseSchemaProvider);
|
|
GetProject(requestParams.ProjectUri); // load into the cache
|
|
|
|
}, requestContext);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Sql object script calls
|
|
|
|
internal async Task HandleAddSqlObjectScriptRequest(SqlProjectScriptParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).SqlObjectScripts.Add(new SqlObjectScript(requestParams.Path)), requestContext);
|
|
}
|
|
|
|
internal async Task HandleDeleteSqlObjectScriptRequest(SqlProjectScriptParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).SqlObjectScripts.Delete(requestParams.Path), requestContext);
|
|
}
|
|
|
|
internal async Task HandleExcludeSqlObjectScriptRequest(SqlProjectScriptParams requestParams, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).SqlObjectScripts.Exclude(requestParams.Path), requestContext);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Helper methods
|
|
|
|
private async Task RunWithErrorHandling(Action action, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
await RunWithErrorHandling(async () => await Task.Run(action), requestContext);
|
|
}
|
|
|
|
private async Task RunWithErrorHandling(Func<Task> action, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
try
|
|
{
|
|
await action();
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = true,
|
|
ErrorMessage = null
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = false,
|
|
ErrorMessage = ex.Message
|
|
});
|
|
}
|
|
}
|
|
|
|
private SqlProject GetProject(string projectUri)
|
|
{
|
|
if (!Projects.ContainsKey(projectUri))
|
|
{
|
|
Projects[projectUri] = new SqlProject(projectUri);
|
|
}
|
|
|
|
return Projects[projectUri];
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|