mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
Added new Kusto ServiceLayer (#1009)
* Copy smoModel some rename * Copy entire service layer * Building copy * Fixing some references * Launch profile * Resolve namespace issues * Compiling tests. Correct manifest. * Fixing localization resources * ReliableKustoClient * Some trimming of extra code and Kusto code * Kusto client creation in bindingContent * Removing Smo and new Kusto classes * More trimming * Kusto schema hookup * Solidying DataSource abstraction * Solidifying further * Latest refatoring * More refactoring * Building and launching Kusto service layer * Working model which enumerates databases * Refactoring to pass IDataSource to all tree nodes * Removing some dependencies on the context * Working with tables and schema * Comment checkin * Refactoring to give out select script * Query created and sent back to ADS * Fix query generation * Fix listing of databases * Tunneling the query through. * Successful query execution * Return only results table * Deleting Cms * Delete DacFx * Delete SchemaCompare and TaskServices * Change build definition to not stop at launch * Fix error after merge * Save Kusto results in different formats (#935) * save results as csv etc * some fixes Co-authored-by: Monica Gupta <mogupt@microsoft.com> * 2407 Added OrderBy clause in KustoDataSource > GetDatabaseMetaData and GetColumnMetadata (#959) * 2405 Defaulted Options when setting ServerInfo in ConnectionService > GetConnectionCompleteParams (#965) * 2747 Fixed IsUnknownType error for Kusto (#989) * 2747 Removed unused directives in Kusto > DbColumnWrapper. Refactored IsUnknownType to handle null DataTypeName * 2747 Reverted IsUnknownType change in DbColumnWrapper. Changed DataTypeName to get calue from ColumnType. Refactored SafeGetValue to type check before hard casting to reduce case exceptions. * Added EmbeddedResourceUseDependentUponConvention to Microsoft.Kusto.ServiceLayer.csproj. Also renamed DACfx to match Microsoft.SqlTools.ServiceLayer. Added to compile Exclude="**/obj/**/*.cs" * Srahman cleanup sql code (#992) * Removed Management and Security Service Code. * Remove FileBrowser service * Comment why we are using SqlServer library * Remove SQL specific type definitions * clean up formatter service (#996) Co-authored-by: Monica Gupta <mogupt@microsoft.com> * Code clean up and Kusto intellisense (#994) * Code clean up and Kusto intellisense * Addressed few comments * Addressed few comments * addressed comments Co-authored-by: Monica Gupta <mogupt@microsoft.com> * Return multiple tables for Kusto * Changes required for Kusto manage dashboard (#1039) * Changes required for manage dashboard * Addressed comments Co-authored-by: Monica Gupta <mogupt@microsoft.com> * 2728 Kusto function support (#1038) * loc update (#914) * loc update * loc updates * 2728 moved ColumnInfo and KustoResultsReader to separate files. Added Folder and Function to TreeNode.cs * 2728 Added FunctionInfo. Added Folder to ColumnInfo. Removed partial class from KustoResultsReader. Set Function.IsAlwaysLeaf=true in TreeNode.cs. In KustoDataSource changed tableMetadata type to TableMetaData. Added folder and function dictionaries. Refactored GetSchema function. Renamed GenerateColumnMetadataKey to GenerateMetadataKey * 2728 Added FunctionInfo. Added Folder to ColumnInfo. Removed partial class from KustoResultsReader. Set Function.IsAlwaysLeaf=true in TreeNode.cs. In KustoDataSource changed tableMetadata type to TableMetaData. Added folder and function dictionaries. Refactored GetSchema function. Renamed GenerateColumnMetadataKey to GenerateMetadataKey * 2728 Created new SqlConnection within using block. Refactored KustoDataSource > columnmetadata to sort on get instead of insert. * 2728 Added GetFunctionInfo function to KustoDataSource. * 2728 Reverted change to Microsoft.Kusto.ServiceLayer.csproj from merge * 2728 Reverted change to SqlTools.ServiceLayer\Localization\transXliff * 2728 Reverted change to sr.de.xlf and sr.zh-hans.xlf * 2728 Refactored KustoDataSource Function folders to support subfolders * 2728 Refactored KustoDataSource to use urn for folders, functions, and tables instead of name. * Merge remote-tracking branch 'origin/main' into feature-ADE # Conflicts: # Packages.props * 2728 Moved metadata files into Metadata subdirectory. Added GenerateAlterFunction to IDataSource and DataSourceBase. * 2728 Added summary information to SafeAdd in SystemExtensions. Renamed local variable in SetTableMetadata * 2728 Moved SafeAdd from SystemExtensions to KustoQueryUtils. Added check when getting database schema to return existing records before querying again. Added AddRange function to KustoQueryUtils. Created SetFolderMetadataForFunctions method. * 2728 Added DatabaseKeyPrefix to only return tables to a database for the dashboard. Added logic to store all database tables within the tableMetadata dictionary for the dashboard. * 2728 Created TableInfo and moved info objects into Models directory. Refactored KustoDataSource to lazy load columns for tables. Refactored logic to load tables using cslschema instead of schema. * 2728 Renamed LoadColumnSchema to GetTableSchema to be consistent. Co-authored-by: khoiph1 <khoiph@microsoft.com> * Addressed comments Co-authored-by: Shafiq Rahman <srahman@microsoft.com> Co-authored-by: Monica Gupta <mogupt@microsoft.com> Co-authored-by: Justin M <63619224+JustinMDotNet@users.noreply.github.com> Co-authored-by: rkselfhost <rkselfhost@outlook.com> Co-authored-by: khoiph1 <khoiph@microsoft.com>
This commit is contained in:
23
.vscode/launch.json
vendored
23
.vscode/launch.json
vendored
@@ -18,6 +18,20 @@
|
||||
"stopAtEntry": false,
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
},
|
||||
{
|
||||
"name": "Kusto service Launch (console)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/src/Microsoft.Kusto.ServiceLayer/bin/Debug/netcoreapp3.1/MicrosoftKustoServiceLayer.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/src/Microsoft.Kusto.ServiceLayer",
|
||||
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
|
||||
"console": "externalTerminal",
|
||||
"stopAtEntry": false,
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
@@ -26,6 +40,15 @@
|
||||
"requireExactSource": false,
|
||||
"justMyCode": false,
|
||||
"enableStepFiltering": false
|
||||
},
|
||||
{
|
||||
"name": "Kusto Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}",
|
||||
"requireExactSource": false,
|
||||
"justMyCode": false,
|
||||
"enableStepFiltering": false
|
||||
}
|
||||
,]
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
<PackageReference Update="Microsoft.Data.SqlClient" Version="2.0.0"/>
|
||||
<PackageReference Update="Microsoft.SqlServer.SqlManagementObjects" Version="160.2004021.0" />
|
||||
<PackageReference Update="Microsoft.SqlServer.DACFx" Version="150.4870.3-preview" GeneratePathProperty="true" />
|
||||
<PackageReference Update="Microsoft.Azure.Kusto.Data" Version="8.0.2" />
|
||||
<PackageReference Update="Microsoft.Azure.Kusto.Language" Version="8.1.2"/>
|
||||
|
||||
<PackageReference Update="Moq" Version="4.8.2" />
|
||||
<PackageReference Update="NUnit" Version="3.12.0" />
|
||||
|
||||
@@ -104,6 +104,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlTools.ManagedB
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlTools.Test.CompletionExtension", "test\Microsoft.SqlTools.Test.CompletionExtension\Microsoft.SqlTools.Test.CompletionExtension.csproj", "{0EC2B30C-0652-49AE-9594-85B3C3E9CA21}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Kusto.ServiceLayer", "src\Microsoft.Kusto.ServiceLayer\Microsoft.Kusto.ServiceLayer.csproj", "{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure-pipelines", "azure-pipelines", "{48D5C134-4091-438D-9D35-6EB8CF0D1DCC}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
azure-pipelines\build.yml = azure-pipelines\build.yml
|
||||
@@ -249,6 +251,12 @@ Global
|
||||
{0EC2B30C-0652-49AE-9594-85B3C3E9CA21}.Integration|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0EC2B30C-0652-49AE-9594-85B3C3E9CA21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0EC2B30C-0652-49AE-9594-85B3C3E9CA21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Integration|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Integration|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -278,6 +286,7 @@ Global
|
||||
{3F82F298-700A-48DF-8A69-D048DFBA782C} = {2BBD7364-054F-4693-97CD-1C395E3E84A9}
|
||||
{D3696EFA-FB1E-4848-A726-FF7B168AFB96} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4}
|
||||
{0EC2B30C-0652-49AE-9594-85B3C3E9CA21} = {AB9CA2B8-6F70-431C-8A1D-67479D8A7BE4}
|
||||
{E0C941C8-91F2-4BE1-8B79-AC88EDB78729} = {2BBD7364-054F-4693-97CD-1C395E3E84A9}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B31CDF4B-2851-45E5-8C5F-BE97125D9DD8}
|
||||
|
||||
136
src/Microsoft.Kusto.ServiceLayer/Admin/AdminService.cs
Normal file
136
src/Microsoft.Kusto.ServiceLayer/Admin/AdminService.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// 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.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.Kusto.ServiceLayer.Admin.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
||||
using Microsoft.Kusto.ServiceLayer.Hosting;
|
||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Admin
|
||||
{
|
||||
/// <summary>
|
||||
/// Admin task service class
|
||||
/// </summary>
|
||||
public class AdminService
|
||||
{
|
||||
private static readonly Lazy<AdminService> instance = new Lazy<AdminService>(() => new AdminService());
|
||||
|
||||
private static ConnectionService connectionService = null;
|
||||
|
||||
/// <summary>
|
||||
/// Default, parameterless constructor.
|
||||
/// </summary>
|
||||
internal AdminService()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal for testing purposes only
|
||||
/// </summary>
|
||||
internal static ConnectionService ConnectionServiceInstance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (AdminService.connectionService == null)
|
||||
{
|
||||
AdminService.connectionService = ConnectionService.Instance;
|
||||
}
|
||||
return AdminService.connectionService;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
AdminService.connectionService = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton instance object
|
||||
/// </summary>
|
||||
public static AdminService Instance
|
||||
{
|
||||
get { return instance.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the service instance
|
||||
/// </summary>
|
||||
public void InitializeService(ServiceHost serviceHost)
|
||||
{
|
||||
serviceHost.SetRequestHandler(GetDatabaseInfoRequest.Type, HandleGetDatabaseInfoRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle get database info request
|
||||
/// </summary>
|
||||
internal static async Task HandleGetDatabaseInfoRequest(
|
||||
GetDatabaseInfoParams databaseParams,
|
||||
RequestContext<GetDatabaseInfoResponse> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
Func<Task> requestHandler = async () =>
|
||||
{
|
||||
ConnectionInfo connInfo;
|
||||
AdminService.ConnectionServiceInstance.TryFindConnection(
|
||||
databaseParams.OwnerUri,
|
||||
out connInfo);
|
||||
DatabaseInfo info = null;
|
||||
|
||||
if (connInfo != null)
|
||||
{
|
||||
info = GetDatabaseInfo(connInfo);
|
||||
}
|
||||
|
||||
await requestContext.SendResult(new GetDatabaseInfoResponse()
|
||||
{
|
||||
DatabaseInfo = info
|
||||
});
|
||||
};
|
||||
|
||||
Task task = Task.Run(async () => await requestHandler()).ContinueWithOnFaulted(async t =>
|
||||
{
|
||||
await requestContext.SendError(t.Exception.ToString());
|
||||
});
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await requestContext.SendError(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return database info for a specific database
|
||||
/// </summary>
|
||||
/// <param name="connInfo"></param>
|
||||
/// <returns></returns>
|
||||
internal static DatabaseInfo GetDatabaseInfo(ConnectionInfo connInfo)
|
||||
{
|
||||
if(!string.IsNullOrEmpty(connInfo.ConnectionDetails.DatabaseName)){
|
||||
ReliableDataSourceConnection connection;
|
||||
connInfo.TryGetConnection("Default", out connection);
|
||||
IDataSource dataSource = connection.GetUnderlyingConnection();
|
||||
DataSourceObjectMetadata objectMetadata = DataSourceFactory.CreateClusterMetadata(connInfo.ConnectionDetails.ServerName);
|
||||
|
||||
List<DataSourceObjectMetadata> metadata = dataSource.GetChildObjects(objectMetadata, true).ToList();
|
||||
var databaseMetadata = metadata.Where(o => o.Name == connInfo.ConnectionDetails.DatabaseName);
|
||||
|
||||
List<DatabaseInfo> databaseInfo = DataSourceFactory.ConvertToDatabaseInfo(databaseMetadata);
|
||||
|
||||
return databaseInfo.ElementAtOrDefault(0);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Admin.Contracts
|
||||
{
|
||||
public class DatabaseInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the options
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Options { get; set; }
|
||||
|
||||
public DatabaseInfo()
|
||||
{
|
||||
Options = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Admin.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Params for a get database info request
|
||||
/// </summar>
|
||||
public class GetDatabaseInfoParams
|
||||
{
|
||||
/// <summary>
|
||||
/// Uri identifier for the connection to get the database info for
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Response object for get database info
|
||||
/// </summary>
|
||||
public class GetDatabaseInfoResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The object containing the database info
|
||||
/// </summary>
|
||||
public DatabaseInfo DatabaseInfo { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get database info request mapping
|
||||
/// </summary>
|
||||
public class GetDatabaseInfoRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<GetDatabaseInfoParams, GetDatabaseInfoResponse> Type =
|
||||
RequestType<GetDatabaseInfoParams, GetDatabaseInfoResponse>.Create("admin/getdatabaseinfo");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to uniquely identify a CancellationTokenSource associated with both
|
||||
/// a string URI and a string connection type.
|
||||
/// </summary>
|
||||
public class CancelTokenKey : CancelConnectParams, IEquatable<CancelTokenKey>
|
||||
{
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
CancelTokenKey other = obj as CancelTokenKey;
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return other.OwnerUri == OwnerUri && other.Type == Type;
|
||||
}
|
||||
|
||||
public bool Equals(CancelTokenKey obj)
|
||||
{
|
||||
return obj.OwnerUri == OwnerUri && obj.Type == Type;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return OwnerUri.GetHashCode() ^ Type.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
src/Microsoft.Kusto.ServiceLayer/Connection/ConnectionInfo.cs
Normal file
162
src/Microsoft.Kusto.ServiceLayer/Connection/ConnectionInfo.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Information pertaining to a unique connection instance.
|
||||
/// </summary>
|
||||
public class ConnectionInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ConnectionInfo(IDataSourceConnectionFactory factory, string ownerUri, ConnectionDetails details)
|
||||
{
|
||||
Factory = factory;
|
||||
OwnerUri = ownerUri;
|
||||
ConnectionDetails = details;
|
||||
ConnectionId = Guid.NewGuid();
|
||||
IntellisenseMetrics = new InteractionMetrics<double>(new int[] {50, 100, 200, 500, 1000, 2000});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unique Id, helpful to identify a connection info object
|
||||
/// </summary>
|
||||
public Guid ConnectionId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// URI identifying the owner/user of the connection. Could be a file, service, resource, etc.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Factory used for creating the SQL connection associated with the connection info.
|
||||
/// </summary>
|
||||
public IDataSourceConnectionFactory Factory { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Properties used for creating/opening the SQL connection.
|
||||
/// </summary>
|
||||
public ConnectionDetails ConnectionDetails { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map containing all connections to the database that are associated with
|
||||
/// this ConnectionInfo's OwnerUri.
|
||||
/// This is internal for testing access only
|
||||
/// </summary>
|
||||
internal readonly ConcurrentDictionary<string, ReliableDataSourceConnection> ConnectionTypeToConnectionMap =
|
||||
new ConcurrentDictionary<string, ReliableDataSourceConnection>();
|
||||
|
||||
/// <summary>
|
||||
/// Intellisense Metrics
|
||||
/// </summary>
|
||||
public InteractionMetrics<double> IntellisenseMetrics { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the db connection is to any cloud instance
|
||||
/// </summary>
|
||||
public bool IsCloud { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the major version number of the db we are connected to
|
||||
/// </summary>
|
||||
public int MajorVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All DbConnection instances held by this ConnectionInfo
|
||||
/// </summary>
|
||||
public ICollection<ReliableDataSourceConnection> AllConnections
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConnectionTypeToConnectionMap.Values;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All connection type strings held by this ConnectionInfo
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<string> AllConnectionTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConnectionTypeToConnectionMap.Keys;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasConnectionType(string connectionType)
|
||||
{
|
||||
connectionType = connectionType ?? ConnectionType.Default;
|
||||
return ConnectionTypeToConnectionMap.ContainsKey(connectionType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The count of DbConnectioninstances held by this ConnectionInfo
|
||||
/// </summary>
|
||||
public int CountConnections
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConnectionTypeToConnectionMap.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the DbConnection associated with the given connection type string.
|
||||
/// </summary>
|
||||
/// <returns>true if a connection with type connectionType was located and out connection was set,
|
||||
/// false otherwise </returns>
|
||||
/// <exception cref="ArgumentException">Thrown when connectionType is null or empty</exception>
|
||||
public bool TryGetConnection(string connectionType, out ReliableDataSourceConnection connection)
|
||||
{
|
||||
Validate.IsNotNullOrEmptyString("Connection Type", connectionType);
|
||||
return ConnectionTypeToConnectionMap.TryGetValue(connectionType, out connection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a DbConnection to this object and associates it with the given
|
||||
/// connection type string. If a connection already exists with an identical
|
||||
/// connection type string, it is not overwritten. Ignores calls where connectionType = null
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">Thrown when connectionType is null or empty</exception>
|
||||
public void AddConnection(string connectionType, ReliableDataSourceConnection connection)
|
||||
{
|
||||
Validate.IsNotNullOrEmptyString("Connection Type", connectionType);
|
||||
ConnectionTypeToConnectionMap.TryAdd(connectionType, connection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the single DbConnection instance associated with string connectionType
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">Thrown when connectionType is null or empty</exception>
|
||||
public void RemoveConnection(string connectionType)
|
||||
{
|
||||
Validate.IsNotNullOrEmptyString("Connection Type", connectionType);
|
||||
ReliableDataSourceConnection connection;
|
||||
ConnectionTypeToConnectionMap.TryRemove(connectionType, out connection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all DbConnection instances held by this object
|
||||
/// </summary>
|
||||
public void RemoveAllConnections()
|
||||
{
|
||||
foreach (var type in AllConnectionTypes)
|
||||
{
|
||||
ReliableDataSourceConnection connection;
|
||||
ConnectionTypeToConnectionMap.TryRemove(type, out connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
//
|
||||
// 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.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class for providing metadata about connection options
|
||||
/// </summary>
|
||||
internal class ConnectionProviderOptionsHelper
|
||||
{
|
||||
internal static ConnectionProviderOptions BuildConnectionProviderOptions()
|
||||
{
|
||||
return new ConnectionProviderOptions
|
||||
{
|
||||
Options = new ConnectionOption[]
|
||||
{
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "server",
|
||||
DisplayName = "Server name",
|
||||
Description = "Name of the SQL Server instance",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
SpecialValueType = ConnectionOption.SpecialValueServerName,
|
||||
IsIdentity = true,
|
||||
IsRequired = true,
|
||||
GroupName = "Source"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "database",
|
||||
DisplayName = "Database name",
|
||||
Description = "The name of the initial catalog or database int the data source",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
SpecialValueType = ConnectionOption.SpecialValueDatabaseName,
|
||||
IsIdentity = true,
|
||||
IsRequired = false,
|
||||
GroupName = "Source"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "authenticationType",
|
||||
DisplayName = "Authentication type",
|
||||
Description = "Specifies the method of authenticating with SQL Server",
|
||||
ValueType = ConnectionOption.ValueTypeCategory,
|
||||
SpecialValueType = ConnectionOption.SpecialValueAuthType,
|
||||
CategoryValues = new CategoryValue[]
|
||||
{ new CategoryValue { DisplayName = "SQL Login", Name = "SqlLogin" },
|
||||
new CategoryValue { DisplayName = "Windows Authentication", Name = "Integrated" },
|
||||
new CategoryValue { DisplayName = "Azure Active Directory - Universal with MFA support", Name = "AzureMFA" }
|
||||
},
|
||||
IsIdentity = true,
|
||||
IsRequired = true,
|
||||
GroupName = "Security"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "user",
|
||||
DisplayName = "User name",
|
||||
Description = "Indicates the user ID to be used when connecting to the data source",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
SpecialValueType = ConnectionOption.SpecialValueUserName,
|
||||
IsIdentity = true,
|
||||
IsRequired = true,
|
||||
GroupName = "Security"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "password",
|
||||
DisplayName = "Password",
|
||||
Description = "Indicates the password to be used when connecting to the data source",
|
||||
ValueType = ConnectionOption.ValueTypePassword,
|
||||
SpecialValueType = ConnectionOption.SpecialValuePasswordName,
|
||||
IsIdentity = true,
|
||||
IsRequired = true,
|
||||
GroupName = "Security"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "applicationIntent",
|
||||
DisplayName = "Application intent",
|
||||
Description = "Declares the application workload type when connecting to a server",
|
||||
ValueType = ConnectionOption.ValueTypeCategory,
|
||||
CategoryValues = new CategoryValue[] {
|
||||
new CategoryValue { Name = "ReadWrite", DisplayName = "ReadWrite" },
|
||||
new CategoryValue {Name = "ReadOnly", DisplayName = "ReadOnly" }
|
||||
},
|
||||
GroupName = "Initialization"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "asynchronousProcessing",
|
||||
DisplayName = "Asynchronous processing enabled",
|
||||
Description = "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean,
|
||||
GroupName = "Initialization"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "connectTimeout",
|
||||
DisplayName = "Connect timeout",
|
||||
Description =
|
||||
"The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
DefaultValue = "15",
|
||||
GroupName = "Initialization"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "currentLanguage",
|
||||
DisplayName = "Current language",
|
||||
Description = "The SQL Server language record name",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = "Initialization"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "columnEncryptionSetting",
|
||||
DisplayName = "Column encryption setting",
|
||||
Description = "Default column encryption setting for all the commands on the connection",
|
||||
ValueType = ConnectionOption.ValueTypeCategory,
|
||||
GroupName = "Security",
|
||||
CategoryValues = new CategoryValue[] {
|
||||
new CategoryValue { Name = "Disabled" },
|
||||
new CategoryValue {Name = "Enabled" }
|
||||
}
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "encrypt",
|
||||
DisplayName = "Encrypt",
|
||||
Description =
|
||||
"When true, SQL Server uses SSL encryption for all data sent between the client and server if the servers has a certificate installed",
|
||||
GroupName = "Security",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "persistSecurityInfo",
|
||||
DisplayName = "Persist security info",
|
||||
Description = "When false, security-sensitive information, such as the password, is not returned as part of the connection",
|
||||
GroupName = "Security",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "trustServerCertificate",
|
||||
DisplayName = "Trust server certificate",
|
||||
Description = "When true (and encrypt=true), SQL Server uses SSL encryption for all data sent between the client and server without validating the server certificate",
|
||||
GroupName = "Security",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "attachedDBFileName",
|
||||
DisplayName = "Attached DB file name",
|
||||
Description = "The name of the primary file, including the full path name, of an attachable database",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = "Source"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "contextConnection",
|
||||
DisplayName = "Context connection",
|
||||
Description = "When true, indicates the connection should be from the SQL server context. Available only when running in the SQL Server process",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean,
|
||||
GroupName = "Source"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "port",
|
||||
DisplayName = "Port",
|
||||
ValueType = ConnectionOption.ValueTypeNumber
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "connectRetryCount",
|
||||
DisplayName = "Connect retry count",
|
||||
Description = "Number of attempts to restore connection",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
DefaultValue = "1",
|
||||
GroupName = "Connection Resiliency"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "connectRetryInterval",
|
||||
DisplayName = "Connect retry interval",
|
||||
Description = "Delay between attempts to restore connection",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
DefaultValue = "10",
|
||||
GroupName = "Connection Resiliency"
|
||||
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "applicationName",
|
||||
DisplayName = "Application name",
|
||||
Description = "The name of the application",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = "Context",
|
||||
SpecialValueType = ConnectionOption.SpecialValueAppName
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "workstationId",
|
||||
DisplayName = "Workstation Id",
|
||||
Description = "The name of the workstation connecting to SQL Server",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = "Context"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "pooling",
|
||||
DisplayName = "Pooling",
|
||||
Description = "When true, the connection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean,
|
||||
GroupName = "Pooling"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "maxPoolSize",
|
||||
DisplayName = "Max pool size",
|
||||
Description = "The maximum number of connections allowed in the pool",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
GroupName = "Pooling"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "minPoolSize",
|
||||
DisplayName = "Min pool size",
|
||||
Description = "The minimum number of connections allowed in the pool",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
GroupName = "Pooling"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "loadBalanceTimeout",
|
||||
DisplayName = "Load balance timeout",
|
||||
Description = "The minimum amount of time (in seconds) for this connection to live in the pool before being destroyed",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
GroupName = "Pooling"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "replication",
|
||||
DisplayName = "Replication",
|
||||
Description = "Used by SQL Server in Replication",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean,
|
||||
GroupName = "Replication"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "attachDbFilename",
|
||||
DisplayName = "Attach DB filename",
|
||||
ValueType = ConnectionOption.ValueTypeString
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "failoverPartner",
|
||||
DisplayName = "Failover partner",
|
||||
Description = "the name or network address of the instance of SQL Server that acts as a failover partner",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = " Source"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "multiSubnetFailover",
|
||||
DisplayName = "Multi subnet failover",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "multipleActiveResultSets",
|
||||
DisplayName = "Multiple active result sets",
|
||||
Description = "When true, multiple result sets can be returned and read from one connection",
|
||||
ValueType = ConnectionOption.ValueTypeBoolean,
|
||||
GroupName = "Advanced"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "packetSize",
|
||||
DisplayName = "Packet size",
|
||||
Description = "Size in bytes of the network packets used to communicate with an instance of SQL Server",
|
||||
ValueType = ConnectionOption.ValueTypeNumber,
|
||||
GroupName = "Advanced"
|
||||
},
|
||||
new ConnectionOption
|
||||
{
|
||||
Name = "typeSystemVersion",
|
||||
DisplayName = "Type system version",
|
||||
Description = "Indicates which server type system then provider will expose through the DataReader",
|
||||
ValueType = ConnectionOption.ValueTypeString,
|
||||
GroupName = "Advanced"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
1513
src/Microsoft.Kusto.ServiceLayer/Connection/ConnectionService.cs
Normal file
1513
src/Microsoft.Kusto.ServiceLayer/Connection/ConnectionService.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// String constants that represent connection types.
|
||||
///
|
||||
/// Default: Connection used by the editor. Opened by the editor upon the initial connection.
|
||||
/// Query: Connection used for executing queries. Opened when the first query is executed.
|
||||
/// </summary>
|
||||
public static class ConnectionType
|
||||
{
|
||||
public const string Default = "Default";
|
||||
public const string Query = "Query";
|
||||
public const string Edit = "Edit";
|
||||
public const string ObjectExplorer = "ObjectExplorer";
|
||||
public const string Dashboard = "Dashboard";
|
||||
public const string GeneralConnection = "GeneralConnection";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialize Connection String request
|
||||
/// </summary>
|
||||
public class BuildConnectionInfoRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<string, ConnectionDetails> Type =
|
||||
RequestType<string, ConnectionDetails>.Create("connection/buildconnectioninfo");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the Cancel Connect Request.
|
||||
/// </summary>
|
||||
public class CancelConnectParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the owner of the connection. This will most commonly be a file in the workspace
|
||||
/// or a virtual file representing an object in a database.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of connection we are trying to cancel
|
||||
/// </summary>
|
||||
public string Type { get; set; } = ConnectionType.Default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Cancel connect request mapping entry
|
||||
/// </summary>
|
||||
public class CancelConnectRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<CancelConnectParams, bool> Type =
|
||||
RequestType<CancelConnectParams, bool>.Create("connection/cancelconnect");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the List Databases Request.
|
||||
/// </summary>
|
||||
public class ChangeDatabaseParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI of the owner of the connection requesting the list of databases.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The database to change to
|
||||
/// </summary>
|
||||
public string NewDatabase { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// List databases request mapping entry
|
||||
/// </summary>
|
||||
public class ChangeDatabaseRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ChangeDatabaseParams, bool> Type =
|
||||
RequestType<ChangeDatabaseParams, bool>.Create("connection/changedatabase");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the Connect Request.
|
||||
/// </summary>
|
||||
public class ConnectParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the owner of the connection. This will most commonly be a file in the workspace
|
||||
/// or a virtual file representing an object in a database.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the required parameters to initialize a connection to a database.
|
||||
/// A connection will identified by its server name, database name and user name.
|
||||
/// This may be changed in the future to support multiple connections with different
|
||||
/// connection properties to the same database.
|
||||
/// </summary>
|
||||
public ConnectionDetails Connection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of this connection. By default, this is set to ConnectionType.Default.
|
||||
/// </summary>
|
||||
public string Type { get; set; } = ConnectionType.Default;
|
||||
|
||||
/// <summary>
|
||||
/// The porpose of the connection to keep track of open connections
|
||||
/// </summary>
|
||||
public string Purpose { get; set; } = ConnectionType.GeneralConnection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to ConnectParams
|
||||
/// </summary>
|
||||
public static class ConnectParamsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Check that the fields in ConnectParams are all valid
|
||||
/// </summary>
|
||||
public static bool IsValid(this ConnectParams parameters, out string errorMessage)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
if (string.IsNullOrEmpty(parameters.OwnerUri))
|
||||
{
|
||||
errorMessage = SR.ConnectionParamsValidateNullOwnerUri;
|
||||
}
|
||||
else if (parameters.Connection == null)
|
||||
{
|
||||
errorMessage = SR.ConnectionParamsValidateNullConnection;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(parameters.Connection.ConnectionString))
|
||||
{
|
||||
// Do not check other connection parameters if a connection string is present
|
||||
return string.IsNullOrEmpty(errorMessage);
|
||||
}
|
||||
else if (string.IsNullOrEmpty(parameters.Connection.ServerName))
|
||||
{
|
||||
errorMessage = SR.ConnectionParamsValidateNullServerName;
|
||||
}
|
||||
else if (string.IsNullOrEmpty(parameters.Connection.AuthenticationType) || parameters.Connection.AuthenticationType == "SqlLogin")
|
||||
{
|
||||
// For SqlLogin, username cannot be empty
|
||||
if (string.IsNullOrEmpty(parameters.Connection.UserName))
|
||||
{
|
||||
errorMessage = SR.ConnectionParamsValidateNullSqlAuth("UserName");
|
||||
}
|
||||
}
|
||||
|
||||
return string.IsNullOrEmpty(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// ConnectionChanged notification mapping entry
|
||||
/// </summary>
|
||||
public class ConnectionChangedNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<ConnectionChangedParams> Type =
|
||||
EventType<ConnectionChangedParams>.Create("connection/connectionchanged");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the ConnectionChanged Notification.
|
||||
/// </summary>
|
||||
public class ConnectionChangedParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the owner of the connection. This will most commonly be a file in the workspace
|
||||
/// or a virtual file representing an object in a database.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
/// <summary>
|
||||
/// Contains the high-level properties about the connection, for display to the user.
|
||||
/// </summary>
|
||||
public ConnectionSummary Connection { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters to be sent back with a connection complete event
|
||||
/// </summary>
|
||||
public class ConnectionCompleteParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the owner of the connection. This will most commonly be a file in the workspace
|
||||
/// or a virtual file representing an object in a database.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A GUID representing a unique connection ID
|
||||
/// </summary>
|
||||
public string ConnectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets any detailed connection error messages.
|
||||
/// </summary>
|
||||
public string Messages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Error message returned from the engine for a connection failure reason, if any.
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Error number returned from the engine for connection failure reason, if any.
|
||||
/// </summary>
|
||||
public int ErrorNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Information about the connected server.
|
||||
/// </summary>
|
||||
public ServerInfo ServerInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the actual Connection established, including Database Name
|
||||
/// </summary>
|
||||
public ConnectionSummary ConnectionSummary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of connection that this notification is for
|
||||
/// </summary>
|
||||
public string Type { get; set; } = ConnectionType.Default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ConnectionComplete notification mapping entry
|
||||
/// </summary>
|
||||
public class ConnectionCompleteNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<ConnectionCompleteParams> Type =
|
||||
EventType<ConnectionCompleteParams>.Create("connection/complete");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,540 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Message format for the initial connection request
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If this contract is ever changed, be sure to update ConnectionDetailsExtensions methods.
|
||||
/// </remarks>
|
||||
public class ConnectionDetails : GeneralRequestDetails, IConnectionSummary
|
||||
{
|
||||
public ConnectionDetails() : base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection password
|
||||
/// </summary>
|
||||
public string Password
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("password");
|
||||
}
|
||||
set
|
||||
{
|
||||
SetOptionValue("password", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection server name
|
||||
/// </summary>
|
||||
public string ServerName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("server");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("server", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection database name
|
||||
/// </summary>
|
||||
public string DatabaseName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("database");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("database", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection user name
|
||||
/// </summary>
|
||||
public string UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("user");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("user", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authentication to use.
|
||||
/// </summary>
|
||||
public string AuthenticationType
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("authenticationType");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("authenticationType", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed.
|
||||
/// </summary>
|
||||
public bool? Encrypt
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("encrypt");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("encrypt", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates whether the channel will be encrypted while bypassing walking the certificate chain to validate trust.
|
||||
/// </summary>
|
||||
public bool? TrustServerCertificate
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("trustServerCertificate");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("trustServerCertificate", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.
|
||||
/// </summary>
|
||||
public bool? PersistSecurityInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("persistSecurityInfo");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("persistSecurityInfo", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.
|
||||
/// </summary>
|
||||
public int? ConnectTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("connectTimeout");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("connectTimeout", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of reconnections attempted after identifying that there was an idle connection failure.
|
||||
/// </summary>
|
||||
public int? ConnectRetryCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("connectRetryCount");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("connectRetryCount", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure.
|
||||
/// </summary>
|
||||
public int? ConnectRetryInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("connectRetryInterval");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("connectRetryInterval", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the application associated with the connection string.
|
||||
/// </summary>
|
||||
public string ApplicationName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("applicationName");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("applicationName", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the workstation connecting to SQL Server.
|
||||
/// </summary>
|
||||
public string WorkstationId
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("workstationId");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("workstationId", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Declares the application workload type when connecting to a database in an SQL Server Availability Group.
|
||||
/// </summary>
|
||||
public string ApplicationIntent
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("applicationIntent");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("applicationIntent", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SQL Server Language record name.
|
||||
/// </summary>
|
||||
public string CurrentLanguage
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("currentLanguage");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("currentLanguage", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a Boolean value that indicates whether the connection will be pooled or explicitly opened every time that the connection is requested.
|
||||
/// </summary>
|
||||
public bool? Pooling
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("pooling");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("pooling", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of connections allowed in the connection pool for this specific connection string.
|
||||
/// </summary>
|
||||
public int? MaxPoolSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("maxPoolSize");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("maxPoolSize", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum number of connections allowed in the connection pool for this specific connection string.
|
||||
/// </summary>
|
||||
public int? MinPoolSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("minPoolSize");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("minPoolSize", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum time, in seconds, for the connection to live in the connection pool before being destroyed.
|
||||
/// </summary>
|
||||
public int? LoadBalanceTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("loadBalanceTimeout");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("loadBalanceTimeout", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a Boolean value that indicates whether replication is supported using the connection.
|
||||
/// </summary>
|
||||
public bool? Replication
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("replication");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("replication", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a string that contains the name of the primary data file. This includes the full path name of an attachable database.
|
||||
/// </summary>
|
||||
public string AttachDbFilename
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("attachDbFilename");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("attachDbFilename", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name or address of the partner server to connect to if the primary server is down.
|
||||
/// </summary>
|
||||
public string FailoverPartner
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("failoverPartner");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("failoverPartner", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If your application is connecting to an AlwaysOn availability group (AG) on different subnets, setting MultiSubnetFailover=true provides faster detection of and connection to the (currently) active server.
|
||||
/// </summary>
|
||||
public bool? MultiSubnetFailover
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("multiSubnetFailover");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("multiSubnetFailover", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When true, an application can maintain multiple active result sets (MARS).
|
||||
/// </summary>
|
||||
public bool? MultipleActiveResultSets
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<bool?>("multipleActiveResultSets");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("multipleActiveResultSets", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size in bytes of the network packets used to communicate with an instance of SQL Server.
|
||||
/// </summary>
|
||||
public int? PacketSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("packetSize");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("packetSize", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port to use for the TCP/IP connection
|
||||
/// </summary>
|
||||
public int? Port
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<int?>("port");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("port", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a string value that indicates the type system the application expects.
|
||||
/// </summary>
|
||||
public string TypeSystemVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("typeSystemVersion");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("typeSystemVersion", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a string value to be used as the connection string. If given, all other options will be ignored.
|
||||
/// </summary>
|
||||
public string ConnectionString
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("connectionString");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetOptionValue("connectionString", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the group ID
|
||||
/// </summary>
|
||||
public string GroupId
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("groupId");
|
||||
}
|
||||
set
|
||||
{
|
||||
SetOptionValue("groupId", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database display name
|
||||
/// </summary>
|
||||
public string DatabaseDisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("databaseDisplayName");
|
||||
}
|
||||
set
|
||||
{
|
||||
SetOptionValue("databaseDisplayName", value);
|
||||
}
|
||||
}
|
||||
|
||||
public string AzureAccountToken
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("azureAccountToken");
|
||||
}
|
||||
set
|
||||
{
|
||||
SetOptionValue("azureAccountToken", value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsComparableTo(ConnectionDetails other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ServerName != other.ServerName
|
||||
|| AuthenticationType != other.AuthenticationType
|
||||
|| UserName != other.UserName
|
||||
|| AzureAccountToken != other.AzureAccountToken)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// For database name, only compare if neither is empty. This is important
|
||||
// Since it allows for handling of connections to the default database, but is
|
||||
// not a 100% accurate heuristic.
|
||||
if (!string.IsNullOrEmpty(DatabaseName)
|
||||
&& !string.IsNullOrEmpty(other.DatabaseName)
|
||||
&& DatabaseName != other.DatabaseName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for the ConnectionDetails contract class
|
||||
/// </summary>
|
||||
public static class ConnectionDetailsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a copy of a connection details object.
|
||||
/// </summary>
|
||||
public static ConnectionDetails Clone(this ConnectionDetails details)
|
||||
{
|
||||
return new ConnectionDetails()
|
||||
{
|
||||
ServerName = details.ServerName,
|
||||
DatabaseName = details.DatabaseName,
|
||||
UserName = details.UserName,
|
||||
Password = details.Password,
|
||||
AuthenticationType = details.AuthenticationType,
|
||||
Encrypt = details.Encrypt,
|
||||
TrustServerCertificate = details.TrustServerCertificate,
|
||||
PersistSecurityInfo = details.PersistSecurityInfo,
|
||||
ConnectTimeout = details.ConnectTimeout,
|
||||
ConnectRetryCount = details.ConnectRetryCount,
|
||||
ConnectRetryInterval = details.ConnectRetryInterval,
|
||||
ApplicationName = details.ApplicationName,
|
||||
WorkstationId = details.WorkstationId,
|
||||
ApplicationIntent = details.ApplicationIntent,
|
||||
CurrentLanguage = details.CurrentLanguage,
|
||||
Pooling = details.Pooling,
|
||||
MaxPoolSize = details.MaxPoolSize,
|
||||
MinPoolSize = details.MinPoolSize,
|
||||
LoadBalanceTimeout = details.LoadBalanceTimeout,
|
||||
Replication = details.Replication,
|
||||
AttachDbFilename = details.AttachDbFilename,
|
||||
FailoverPartner = details.FailoverPartner,
|
||||
MultiSubnetFailover = details.MultiSubnetFailover,
|
||||
MultipleActiveResultSets = details.MultipleActiveResultSets,
|
||||
PacketSize = details.PacketSize,
|
||||
TypeSystemVersion = details.TypeSystemVersion,
|
||||
ConnectionString = details.ConnectionString,
|
||||
Port = details.Port,
|
||||
AzureAccountToken = details.AzureAccountToken
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Connect request mapping entry
|
||||
/// </summary>
|
||||
public class ConnectionRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ConnectParams, bool> Type =
|
||||
RequestType<ConnectParams, bool>.Create("connection/connect");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
|
||||
public interface IConnectionSummary
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the connection server name
|
||||
/// </summary>
|
||||
string ServerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection database name
|
||||
/// </summary>
|
||||
string DatabaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection user name
|
||||
/// </summary>
|
||||
string UserName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides high level information about a connection.
|
||||
/// </summary>
|
||||
public class ConnectionSummary : IConnectionSummary
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the connection server name
|
||||
/// </summary>
|
||||
public virtual string ServerName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection database name
|
||||
/// </summary>
|
||||
public virtual string DatabaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection user name
|
||||
/// </summary>
|
||||
public virtual string UserName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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.Generic;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Treats connections as the same if their server, db and usernames all match
|
||||
/// </summary>
|
||||
public class ConnectionSummaryComparer : IEqualityComparer<ConnectionSummary>
|
||||
{
|
||||
public bool Equals(ConnectionSummary x, ConnectionSummary y)
|
||||
{
|
||||
if(x == y) { return true; }
|
||||
else if(x != null)
|
||||
{
|
||||
if(y == null) { return false; }
|
||||
|
||||
// Compare server, db, username. Note: server is case-insensitive in the driver
|
||||
return string.Compare(x.ServerName, y.ServerName, StringComparison.OrdinalIgnoreCase) == 0
|
||||
&& string.Compare(x.DatabaseName, y.DatabaseName, StringComparison.Ordinal) == 0
|
||||
&& string.Compare(x.UserName, y.UserName, StringComparison.Ordinal) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetHashCode(ConnectionSummary obj)
|
||||
{
|
||||
int hashcode = 31;
|
||||
if(obj != null)
|
||||
{
|
||||
if(obj.ServerName != null)
|
||||
{
|
||||
hashcode ^= obj.ServerName.GetHashCode();
|
||||
}
|
||||
if (obj.DatabaseName != null)
|
||||
{
|
||||
hashcode ^= obj.DatabaseName.GetHashCode();
|
||||
}
|
||||
if (obj.UserName != null)
|
||||
{
|
||||
hashcode ^= obj.UserName.GetHashCode();
|
||||
}
|
||||
}
|
||||
return hashcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to ConnectionSummary
|
||||
/// </summary>
|
||||
public static class ConnectionSummaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a copy of a ConnectionSummary object
|
||||
/// </summary>
|
||||
public static ConnectionSummary Clone(this IConnectionSummary summary)
|
||||
{
|
||||
return new ConnectionSummary()
|
||||
{
|
||||
ServerName = summary.ServerName,
|
||||
DatabaseName = summary.DatabaseName,
|
||||
UserName = summary.UserName
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the Disconnect Request.
|
||||
/// </summary>
|
||||
public class DisconnectParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the owner of the connection. This will most commonly be a file in the workspace
|
||||
/// or a virtual file representing an object in a database.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of connection we are disconnecting. If null, we will disconnect all connections.
|
||||
/// connections.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Disconnect request mapping entry
|
||||
/// </summary>
|
||||
public class DisconnectRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<DisconnectParams, bool> Type =
|
||||
RequestType<DisconnectParams, bool>.Create("connection/disconnect");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the Get Connection String Request.
|
||||
/// </summary>
|
||||
public class GetConnectionStringParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI of the owner of the connection
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the password should be return in the connection string
|
||||
/// </summary>
|
||||
public bool IncludePassword { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Get Connection String request
|
||||
/// </summary>
|
||||
public class GetConnectionStringRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<GetConnectionStringParams, string> Type =
|
||||
RequestType<GetConnectionStringParams, string>.Create("connection/getconnectionstring");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Parameters for the Language Flavor Change notification.
|
||||
/// </summary>
|
||||
public class LanguageFlavorChangeParams
|
||||
{
|
||||
/// <summary>
|
||||
/// A URI identifying the affected resource
|
||||
/// </summary>
|
||||
public string Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The primary language
|
||||
/// </summary>
|
||||
public string Language { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The specific language flavor that is being set
|
||||
/// </summary>
|
||||
public string Flavor { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an event that is sent from the client to notify that
|
||||
/// the client is exiting and the server should as well.
|
||||
/// </summary>
|
||||
public class LanguageFlavorChangeNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<LanguageFlavorChangeParams> Type =
|
||||
EventType<LanguageFlavorChangeParams>.Create("connection/languageflavorchanged");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for the List Databases Request.
|
||||
/// </summary>
|
||||
public class ListDatabasesParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI of the owner of the connection requesting the list of databases.
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// whether to include the details of the databases. Called by manage dashboard
|
||||
/// </summary>
|
||||
public bool? IncludeDetails { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// List databases request mapping entry
|
||||
/// </summary>
|
||||
public class ListDatabasesRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ListDatabasesParams, ListDatabasesResponse> Type =
|
||||
RequestType<ListDatabasesParams, ListDatabasesResponse>.Create("connection/listdatabases");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
using Microsoft.Kusto.ServiceLayer.Admin.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Message format for the list databases response
|
||||
/// </summary>
|
||||
public class ListDatabasesResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the list of database names.
|
||||
/// </summary>
|
||||
public string[] DatabaseNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the databases details.
|
||||
/// </summary>
|
||||
public DatabaseInfo[] Databases { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Contract for information on the connected SQL Server instance.
|
||||
/// </summary>
|
||||
public class ServerInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The major version of the SQL Server instance.
|
||||
/// </summary>
|
||||
public int ServerMajorVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minor version of the SQL Server instance.
|
||||
/// </summary>
|
||||
public int ServerMinorVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The build of the SQL Server instance.
|
||||
/// </summary>
|
||||
public int ServerReleaseVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the engine edition of the SQL Server instance.
|
||||
/// </summary>
|
||||
public int EngineEditionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// String containing the full server version text.
|
||||
/// </summary>
|
||||
public string ServerVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// String describing the product level of the server.
|
||||
/// </summary>
|
||||
public string ServerLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The edition of the SQL Server instance.
|
||||
/// </summary>
|
||||
public string ServerEdition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the SQL Server instance is running in the cloud (Azure) or not.
|
||||
/// </summary>
|
||||
public bool IsCloud { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The version of Azure that the SQL Server instance is running on, if applicable.
|
||||
/// </summary>
|
||||
public int AzureVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operating System version string of the machine running the SQL Server instance.
|
||||
/// </summary>
|
||||
public string OsVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Operating System version string of the machine running the SQL Server instance.
|
||||
/// </summary>
|
||||
public string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Server options
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Options { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Data.Common;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory class to create SqlClientConnections
|
||||
/// The purpose of the factory is to make it easier to mock out the database
|
||||
/// in 'offline' unit test scenarios.
|
||||
/// </summary>
|
||||
public class DataSourceConnectionFactory : IDataSourceConnectionFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new SqlConnection object
|
||||
/// </summary>
|
||||
public ReliableDataSourceConnection CreateDataSourceConnection(string connectionString, string azureAccountToken)
|
||||
{
|
||||
RetryPolicy connectionRetryPolicy = RetryPolicyFactory.CreateDefaultConnectionRetryPolicy();
|
||||
RetryPolicy commandRetryPolicy = RetryPolicyFactory.CreateDefaultConnectionRetryPolicy();
|
||||
return new ReliableDataSourceConnection(connectionString, connectionRetryPolicy, commandRetryPolicy, azureAccountToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
public class DatabaseFullAccessException: Exception
|
||||
{
|
||||
public DatabaseFullAccessException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public DatabaseFullAccessException(string message, Exception exception)
|
||||
: base(message, exception)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public DatabaseFullAccessException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
public class DatabaseLocksManager: IDisposable
|
||||
{
|
||||
internal DatabaseLocksManager(int waitToGetFullAccess)
|
||||
{
|
||||
this.waitToGetFullAccess = waitToGetFullAccess;
|
||||
}
|
||||
|
||||
private static DatabaseLocksManager instance = new DatabaseLocksManager(DefaultWaitToGetFullAccess);
|
||||
|
||||
public static DatabaseLocksManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectionService ConnectionService { get; set; }
|
||||
|
||||
private Dictionary<string, ManualResetEvent> databaseAccessEvents = new Dictionary<string, ManualResetEvent>();
|
||||
private object databaseAccessLock = new object();
|
||||
public const int DefaultWaitToGetFullAccess = 10000;
|
||||
public int waitToGetFullAccess = DefaultWaitToGetFullAccess;
|
||||
|
||||
private ManualResetEvent GetResetEvent(string serverName, string databaseName)
|
||||
{
|
||||
string key = GenerateKey(serverName, databaseName);
|
||||
ManualResetEvent resetEvent = null;
|
||||
lock (databaseAccessLock)
|
||||
{
|
||||
if (!databaseAccessEvents.TryGetValue(key, out resetEvent))
|
||||
{
|
||||
resetEvent = new ManualResetEvent(true);
|
||||
databaseAccessEvents.Add(key, resetEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return resetEvent;
|
||||
}
|
||||
|
||||
public bool GainFullAccessToDatabase(string serverName, string databaseName)
|
||||
{
|
||||
/*
|
||||
* TODO: add the lock so not two process can get full access at the same time
|
||||
ManualResetEvent resetEvent = GetResetEvent(serverName, databaseName);
|
||||
if (resetEvent.WaitOne(this.waitToGetFullAccess))
|
||||
{
|
||||
resetEvent.Reset();
|
||||
|
||||
foreach (IConnectedBindingQueue item in ConnectionService.ConnectedQueues)
|
||||
{
|
||||
item.CloseConnections(serverName, databaseName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DatabaseFullAccessException($"Waited more than {waitToGetFullAccess} milli seconds for others to release the lock");
|
||||
}
|
||||
*/
|
||||
foreach (IConnectedBindingQueue item in ConnectionService.ConnectedQueues)
|
||||
{
|
||||
item.CloseConnections(serverName, databaseName, DefaultWaitToGetFullAccess);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public bool ReleaseAccess(string serverName, string databaseName)
|
||||
{
|
||||
/*
|
||||
ManualResetEvent resetEvent = GetResetEvent(serverName, databaseName);
|
||||
|
||||
foreach (IConnectedBindingQueue item in ConnectionService.ConnectedQueues)
|
||||
{
|
||||
item.OpenConnections(serverName, databaseName);
|
||||
}
|
||||
|
||||
resetEvent.Set();
|
||||
*/
|
||||
foreach (IConnectedBindingQueue item in ConnectionService.ConnectedQueues)
|
||||
{
|
||||
item.OpenConnections(serverName, databaseName, DefaultWaitToGetFullAccess);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private string GenerateKey(string serverName, string databaseName)
|
||||
{
|
||||
return $"{serverName.ToLowerInvariant()}-{databaseName.ToLowerInvariant()}";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var resetEvent in databaseAccessEvents)
|
||||
{
|
||||
resetEvent.Value.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Any operation that needs full access to databas should implement this interface.
|
||||
/// Make sure to call GainAccessToDatabase before the operation and ReleaseAccessToDatabase after
|
||||
/// </summary>
|
||||
public interface IFeatureWithFullDbAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// Database Lock Manager
|
||||
/// </summary>
|
||||
DatabaseLocksManager LockedDatabaseManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure the feature has fill access to the database
|
||||
/// </summary>
|
||||
bool GainAccessToDatabase();
|
||||
|
||||
/// <summary>
|
||||
/// Release the access to db
|
||||
/// </summary>
|
||||
bool ReleaseAccessToDatabase();
|
||||
|
||||
/// <summary>
|
||||
/// Server name
|
||||
/// </summary>
|
||||
string ServerName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Database name
|
||||
/// </summary>
|
||||
string DatabaseName { get; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for the SQL Connection factory
|
||||
/// </summary>
|
||||
public interface IDataSourceConnectionFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new SQL Connection object
|
||||
/// </summary>
|
||||
ReliableDataSourceConnection CreateDataSourceConnection(string connectionString, string azureAccountToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
// This code is copied from the source described in the comment below.
|
||||
|
||||
// =======================================================================================
|
||||
// Microsoft Windows Server AppFabric Customer Advisory Team (CAT) Best Practices Series
|
||||
//
|
||||
// This sample is supplemental to the technical guidance published on the community
|
||||
// blog at http://blogs.msdn.com/appfabriccat/ and copied from
|
||||
// sqlmain ./sql/manageability/mfx/common/
|
||||
//
|
||||
// =======================================================================================
|
||||
// Copyright © 2012 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
// EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. YOU BEAR THE RISK OF USING IT.
|
||||
// =======================================================================================
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection.ReliableConnection
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a arguments for event handler which will be invoked whenever a retry condition is encountered.
|
||||
/// </summary>
|
||||
internal sealed class RetryCallbackEventArgs : EventArgs
|
||||
{
|
||||
private readonly int _retryCount;
|
||||
private readonly Exception _exception;
|
||||
private readonly TimeSpan _delay;
|
||||
|
||||
public RetryCallbackEventArgs(int retryCount, Exception exception, TimeSpan delay)
|
||||
{
|
||||
_retryCount = retryCount;
|
||||
_exception = exception;
|
||||
_delay = delay;
|
||||
}
|
||||
|
||||
public TimeSpan Delay
|
||||
{
|
||||
get { return _delay; }
|
||||
}
|
||||
|
||||
public Exception Exception
|
||||
{
|
||||
get { return _exception; }
|
||||
}
|
||||
|
||||
public int RetryCount
|
||||
{
|
||||
get { return _retryCount; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// <copyright file="KustoQueryUtils.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft. All Rights Reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
using System.Data;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
class DataReaderWrapper:IDataReader
|
||||
{
|
||||
private readonly IDataReader _inner ;
|
||||
public DataReaderWrapper(IDataReader inner)
|
||||
{
|
||||
_inner = inner;
|
||||
}
|
||||
|
||||
public object this[int i] => _inner[i];
|
||||
|
||||
public object this[string name] => _inner[name];
|
||||
|
||||
public int Depth => _inner.Depth;
|
||||
|
||||
public bool IsClosed => _inner.IsClosed;
|
||||
|
||||
public int RecordsAffected => _inner.RecordsAffected;
|
||||
|
||||
public int FieldCount => _inner.FieldCount;
|
||||
|
||||
public void Close() => _inner.Close();
|
||||
public void Dispose() => _inner.Dispose();
|
||||
public bool GetBoolean(int i) => _inner.GetBoolean(i);
|
||||
public byte GetByte(int i) => _inner.GetByte(i);
|
||||
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) => _inner.GetBytes(i, fieldOffset, buffer, bufferoffset, length);
|
||||
public char GetChar(int i) => _inner.GetChar(i);
|
||||
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) => _inner.GetChars(i, fieldoffset, buffer, bufferoffset, length);
|
||||
public IDataReader GetData(int i) => _inner.GetData(i);
|
||||
public string GetDataTypeName(int i) => _inner.GetDataTypeName(i);
|
||||
public DateTime GetDateTime(int i) => _inner.GetDateTime(i);
|
||||
public decimal GetDecimal(int i) => _inner.GetDecimal(i);
|
||||
public double GetDouble(int i) => _inner.GetDouble(i);
|
||||
public Type GetFieldType(int i) => _inner.GetFieldType(i);
|
||||
public float GetFloat(int i) => _inner.GetFloat(i);
|
||||
public Guid GetGuid(int i) => _inner.GetGuid(i);
|
||||
public short GetInt16(int i) => _inner.GetInt16(i);
|
||||
public int GetInt32(int i) => _inner.GetInt32(i);
|
||||
public long GetInt64(int i) => _inner.GetInt64(i);
|
||||
public string GetName(int i) => _inner.GetName(i);
|
||||
public int GetOrdinal(string name) => _inner.GetOrdinal(name);
|
||||
public DataTable GetSchemaTable() => _inner.GetSchemaTable();
|
||||
public string GetString(int i) => _inner.GetString(i);
|
||||
public object GetValue(int i) => _inner.GetValue(i);
|
||||
public int GetValues(object[] values) => _inner.GetValues(values);
|
||||
public bool IsDBNull(int i) => _inner.IsDBNull(i);
|
||||
public virtual bool NextResult() => _inner.NextResult();
|
||||
public bool Read() => _inner.Read();
|
||||
}
|
||||
}
|
||||
132
src/Microsoft.Kusto.ServiceLayer/DataSource/DataSourceBase.cs
Normal file
132
src/Microsoft.Kusto.ServiceLayer/DataSource/DataSourceBase.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
// <copyright file="DataSourceUtils.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft. All Rights Reserved.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Completion;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
/// <inheritdoc cref="IDataSource"/>
|
||||
public abstract class DataSourceBase : IDataSource
|
||||
{
|
||||
protected Object dataSourceLock = new Object();
|
||||
|
||||
private string _database;
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DataSourceBase"/> class.
|
||||
/// </summary>
|
||||
~DataSourceBase()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if disposing; false if finalizing.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDataSource
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract Task<IDataReader> ExecuteQueryAsync(string query, CancellationToken cancellationToken, string databaseName = null);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<T> ExecuteScalarQueryAsync<T>(string query, CancellationToken cancellationToken, string databaseName = null)
|
||||
{
|
||||
ValidationUtils.IsArgumentNotNullOrWhiteSpace(query, nameof(query));
|
||||
|
||||
using (var records = await ExecuteQueryAsync(query, cancellationToken, databaseName))
|
||||
{
|
||||
return records.ToScalar<T>();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Task<IEnumerable<T>> ExecuteControlCommandAsync<T>(string command, bool throwOnError, CancellationToken cancellationToken);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract DiagnosticsInfo GetDiagnostics(DataSourceObjectMetadata parentMetadata);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract IEnumerable<DataSourceObjectMetadata> GetChildObjects(DataSourceObjectMetadata parentMetadata, bool includeSizeDetails = false);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void Refresh();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void Refresh(DataSourceObjectMetadata objectMetadata);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void UpdateDatabase(string databaseName);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract CompletionItem[] GetAutoCompleteSuggestions(ScriptDocumentInfo queryText, Position index, bool throwOnError = false);
|
||||
/// <inheritdoc/>
|
||||
public abstract Hover GetHoverHelp(ScriptDocumentInfo scriptDocumentInfo, Position textPosition, bool throwOnError = false);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract DefinitionResult GetDefinition(string queryText, int index, int startLine, int startColumn, bool throwOnError = false);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract ScriptFileMarker[] GetSemanticMarkers(ScriptParseInfo parseInfo, ScriptFile scriptFile, string queryText);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract Task<bool> Exists();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract bool Exists(DataSourceObjectMetadata objectMetadata);
|
||||
|
||||
public abstract string GenerateAlterFunctionScript(string functionName);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DataSourceType DataSourceType { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ClusterName { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string DatabaseName {
|
||||
get
|
||||
{
|
||||
return _database;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
lock(dataSourceLock)
|
||||
{
|
||||
_database = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
159
src/Microsoft.Kusto.ServiceLayer/DataSource/DataSourceFactory.cs
Normal file
159
src/Microsoft.Kusto.ServiceLayer/DataSource/DataSourceFactory.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||
using Microsoft.Kusto.ServiceLayer.Admin.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.Kusto.ServiceLayer.Metadata.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Completion;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Data source factory.
|
||||
/// </summary>
|
||||
public static class DataSourceFactory
|
||||
{
|
||||
public static IDataSource Create(DataSourceType dataSourceType, string connectionString, string azureAccountToken)
|
||||
{
|
||||
ValidationUtils.IsArgumentNotNullOrWhiteSpace(connectionString, nameof(connectionString));
|
||||
ValidationUtils.IsArgumentNotNullOrWhiteSpace(azureAccountToken, nameof(azureAccountToken));
|
||||
|
||||
switch (dataSourceType)
|
||||
{
|
||||
case DataSourceType.Kusto:
|
||||
{
|
||||
return new KustoDataSource(connectionString, azureAccountToken);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported data source type \"{dataSourceType}\"", nameof(dataSourceType));
|
||||
}
|
||||
}
|
||||
|
||||
public static DataSourceObjectMetadata CreateClusterMetadata(string clusterName)
|
||||
{
|
||||
ValidationUtils.IsArgumentNotNullOrWhiteSpace(clusterName, nameof(clusterName));
|
||||
|
||||
return new DataSourceObjectMetadata{
|
||||
MetadataType = DataSourceMetadataType.Cluster,
|
||||
MetadataTypeName = DataSourceMetadataType.Cluster.ToString(),
|
||||
Name = clusterName,
|
||||
PrettyName = clusterName,
|
||||
Urn = $"{clusterName}"
|
||||
};
|
||||
}
|
||||
|
||||
public static DataSourceObjectMetadata CreateDatabaseMetadata(DataSourceObjectMetadata clusterMetadata, string databaseName)
|
||||
{
|
||||
ValidationUtils.IsTrue<ArgumentException>(clusterMetadata.MetadataType == DataSourceMetadataType.Cluster, nameof(clusterMetadata));
|
||||
ValidationUtils.IsArgumentNotNullOrWhiteSpace(databaseName, nameof(databaseName));
|
||||
|
||||
return new DatabaseMetadata{
|
||||
ClusterName = clusterMetadata.Name,
|
||||
MetadataType = DataSourceMetadataType.Database,
|
||||
MetadataTypeName = DataSourceMetadataType.Database.ToString(),
|
||||
Name = databaseName,
|
||||
PrettyName = databaseName,
|
||||
Urn = $"{clusterMetadata.Urn}.{databaseName}"
|
||||
};
|
||||
}
|
||||
|
||||
public static FolderMetadata CreateFolderMetadata(DataSourceObjectMetadata parentMetadata, string path, string name)
|
||||
{
|
||||
ValidationUtils.IsNotNull(parentMetadata, nameof(parentMetadata));
|
||||
|
||||
return new FolderMetadata{
|
||||
MetadataType = DataSourceMetadataType.Folder,
|
||||
MetadataTypeName = DataSourceMetadataType.Folder.ToString(),
|
||||
Name = name,
|
||||
PrettyName = name,
|
||||
ParentMetadata = parentMetadata,
|
||||
Urn = $"{path}.{name}"
|
||||
};
|
||||
}
|
||||
|
||||
// Gets default keywords for intellisense when there is no connection.
|
||||
public static CompletionItem[] GetDefaultAutoComplete(DataSourceType dataSourceType, ScriptDocumentInfo scriptDocumentInfo, Position textDocumentPosition){
|
||||
switch (dataSourceType)
|
||||
{
|
||||
case DataSourceType.Kusto:
|
||||
{
|
||||
return KustoIntellisenseHelper.GetDefaultKeywords(scriptDocumentInfo, textDocumentPosition);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported data source type \"{dataSourceType}\"", nameof(dataSourceType));
|
||||
}
|
||||
}
|
||||
|
||||
// Gets default keywords errors related to intellisense when there is no connection.
|
||||
public static ScriptFileMarker[] GetDefaultSemanticMarkers(DataSourceType dataSourceType, ScriptParseInfo parseInfo, ScriptFile scriptFile, string queryText){
|
||||
switch (dataSourceType)
|
||||
{
|
||||
case DataSourceType.Kusto:
|
||||
{
|
||||
return KustoIntellisenseHelper.GetDefaultDiagnostics(parseInfo, scriptFile, queryText);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported data source type \"{dataSourceType}\"", nameof(dataSourceType));
|
||||
}
|
||||
}
|
||||
|
||||
// Converts database details shown on cluster manage dashboard to DatabaseInfo type. Add DataSourceType as param if required to show different properties
|
||||
public static List<DatabaseInfo> ConvertToDatabaseInfo(IEnumerable<DataSourceObjectMetadata> clusterDBDetails)
|
||||
{
|
||||
var databaseDetails = new List<DatabaseInfo>();
|
||||
|
||||
if(typeof(DatabaseMetadata) == clusterDBDetails.FirstOrDefault().GetType()){
|
||||
foreach(var dbDetail in clusterDBDetails)
|
||||
{
|
||||
DatabaseInfo databaseInfo = new DatabaseInfo();
|
||||
Int64.TryParse(dbDetail.SizeInMB.ToString(), out long sum_OriginalSize);
|
||||
databaseInfo.Options["name"] = dbDetail.Name;
|
||||
databaseInfo.Options["sizeInMB"] = (sum_OriginalSize /(1024 * 1024)).ToString();
|
||||
databaseDetails.Add(databaseInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return databaseDetails;
|
||||
}
|
||||
|
||||
// Converts tables details shown on database manage dashboard to ObjectMetadata type. Add DataSourceType as param if required to show different properties
|
||||
public static List<ObjectMetadata> ConvertToObjectMetadata(IEnumerable<DataSourceObjectMetadata> dbChildDetails)
|
||||
{
|
||||
var databaseChildDetails = new List<ObjectMetadata>();
|
||||
|
||||
foreach(var childDetail in dbChildDetails)
|
||||
{
|
||||
ObjectMetadata dbChildInfo = new ObjectMetadata();
|
||||
dbChildInfo.Name = childDetail.PrettyName;
|
||||
dbChildInfo.MetadataTypeName = childDetail.MetadataTypeName;
|
||||
dbChildInfo.MetadataType = MetadataType.Table; // Add mapping here.
|
||||
databaseChildDetails.Add(dbChildInfo);
|
||||
}
|
||||
return databaseChildDetails;
|
||||
}
|
||||
|
||||
public static ReliableConnectionHelper.ServerInfo ConvertToServerinfoFormat(DataSourceType dataSourceType, DiagnosticsInfo clusterDiagnostics)
|
||||
{
|
||||
switch (dataSourceType)
|
||||
{
|
||||
case DataSourceType.Kusto:
|
||||
{
|
||||
ReliableConnectionHelper.ServerInfo serverInfo = new ReliableConnectionHelper.ServerInfo();
|
||||
serverInfo.Options = new Dictionary<string, object>(clusterDiagnostics.Options);
|
||||
return serverInfo;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported data source type \"{dataSourceType}\"", nameof(dataSourceType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
//
|
||||
// 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.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Kusto.Language;
|
||||
using Kusto.Language.Editor;
|
||||
using Kusto.Language.Syntax;
|
||||
using Kusto.Language.Symbols;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Completion;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense
|
||||
{
|
||||
/// <summary>
|
||||
/// Kusto specific class for intellisense helper functions.
|
||||
/// </summary>
|
||||
public static class KustoIntellisenseHelper
|
||||
{
|
||||
|
||||
public class ShowDatabasesResult
|
||||
{
|
||||
public string DatabaseName;
|
||||
public string PersistentStorage;
|
||||
public string Version;
|
||||
public bool IsCurrent;
|
||||
public string DatabaseAccessMode;
|
||||
public string PrettyName;
|
||||
public bool CurrentUserIsUnrestrictedViewer;
|
||||
public string DatabaseId;
|
||||
}
|
||||
|
||||
public class ShowDatabaseSchemaResult
|
||||
{
|
||||
public string DatabaseName;
|
||||
public string TableName;
|
||||
public string ColumnName;
|
||||
public string ColumnType;
|
||||
public bool IsDefaultTable;
|
||||
public bool IsDefaultColumn;
|
||||
public string PrettyName;
|
||||
public string Version;
|
||||
public string Folder;
|
||||
public string DocName;
|
||||
}
|
||||
|
||||
public class ShowFunctionsResult
|
||||
{
|
||||
public string Name;
|
||||
public string Parameters;
|
||||
public string Body;
|
||||
public string Folder;
|
||||
public string DocString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert CLR type name into a Kusto scalar type.
|
||||
/// </summary>
|
||||
private static ScalarSymbol GetKustoType(string clrTypeName)
|
||||
{
|
||||
switch (clrTypeName)
|
||||
{
|
||||
case "System.Byte":
|
||||
case "Byte":
|
||||
case "byte":
|
||||
case "System.SByte":
|
||||
case "SByte":
|
||||
case "sbyte":
|
||||
case "System.Int16":
|
||||
case "Int16":
|
||||
case "short":
|
||||
case "System.UInt16":
|
||||
case "UInt16":
|
||||
case "ushort":
|
||||
case "System.Int32":
|
||||
case "System.Single":
|
||||
case "Int32":
|
||||
case "int":
|
||||
return ScalarTypes.Int;
|
||||
case "System.UInt32": // unsigned ints don't fit into int, use long
|
||||
case "UInt32":
|
||||
case "uint":
|
||||
case "System.Int64":
|
||||
case "Int64":
|
||||
case "long":
|
||||
return ScalarTypes.Long;
|
||||
case "System.Double":
|
||||
case "Double":
|
||||
case "double":
|
||||
case "float":
|
||||
return ScalarTypes.Real;
|
||||
case "System.UInt64": // unsigned longs do not fit into long, use decimal
|
||||
case "UInt64":
|
||||
case "ulong":
|
||||
case "System.Decimal":
|
||||
case "Decimal":
|
||||
case "decimal":
|
||||
case "System.Data.SqlTypes.SqlDecimal":
|
||||
case "SqlDecimal":
|
||||
return ScalarTypes.Decimal;
|
||||
case "System.Guid":
|
||||
case "Guid":
|
||||
return ScalarTypes.Guid;
|
||||
case "System.DateTime":
|
||||
case "DateTime":
|
||||
return ScalarTypes.DateTime;
|
||||
case "System.TimeSpan":
|
||||
case "TimeSpan":
|
||||
return ScalarTypes.TimeSpan;
|
||||
case "System.String":
|
||||
case "String":
|
||||
case "string":
|
||||
return ScalarTypes.String;
|
||||
case "System.Boolean":
|
||||
case "Boolean":
|
||||
case "bool":
|
||||
return ScalarTypes.Bool;
|
||||
case "System.Object":
|
||||
case "Object":
|
||||
case "object":
|
||||
return ScalarTypes.Dynamic;
|
||||
case "System.Type":
|
||||
case "Type":
|
||||
return ScalarTypes.Type;
|
||||
default:
|
||||
throw new InvalidOperationException($"Unhandled clr type: {clrTypeName}");
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyList<Parameter> NoParameters = new Parameter[0];
|
||||
|
||||
/// <summary>
|
||||
/// Translate Kusto parameter list declaration into into list of <see cref="Parameter"/> instances.
|
||||
/// </summary>
|
||||
private static IReadOnlyList<Parameter> TranslateParameters(string parameters)
|
||||
{
|
||||
parameters = parameters.Trim();
|
||||
|
||||
if (string.IsNullOrEmpty(parameters) || parameters == "()")
|
||||
return NoParameters;
|
||||
|
||||
if (parameters[0] != '(')
|
||||
parameters = "(" + parameters;
|
||||
if (parameters[parameters.Length - 1] != ')')
|
||||
parameters = parameters + ")";
|
||||
|
||||
var query = "let fn = " + parameters + " { };";
|
||||
var code = KustoCode.ParseAndAnalyze(query);
|
||||
var let = code.Syntax.GetFirstDescendant<LetStatement>();
|
||||
var variable = let.Name.ReferencedSymbol as VariableSymbol;
|
||||
var function = variable.Type as FunctionSymbol;
|
||||
return function.Signatures[0].Parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the schema for the specified databasea into a a <see cref="DatabaseSymbol"/>.
|
||||
/// </summary>
|
||||
public static async Task<DatabaseSymbol> LoadDatabaseAsync(IDataSource dataSource, string databaseName, bool throwOnError = false)
|
||||
{
|
||||
var members = new List<Symbol>();
|
||||
CancellationTokenSource source = new CancellationTokenSource();
|
||||
CancellationToken cancellationToken = source.Token;
|
||||
|
||||
var tableSchemas = await dataSource.ExecuteControlCommandAsync<ShowDatabaseSchemaResult>($".show database {databaseName} schema", throwOnError, cancellationToken).ConfigureAwait(false);
|
||||
if (tableSchemas == null)
|
||||
return null;
|
||||
|
||||
tableSchemas = tableSchemas
|
||||
.Where(r => !string.IsNullOrEmpty(r.TableName) && !string.IsNullOrEmpty(r.ColumnName))
|
||||
.ToArray();
|
||||
|
||||
foreach (var table in tableSchemas.GroupBy(s => s.TableName))
|
||||
{
|
||||
var columns = table.Select(s => new ColumnSymbol(s.ColumnName, GetKustoType(s.ColumnType))).ToList();
|
||||
var tableSymbol = new TableSymbol(table.Key, columns);
|
||||
members.Add(tableSymbol);
|
||||
}
|
||||
|
||||
var functionSchemas = await dataSource.ExecuteControlCommandAsync<ShowFunctionsResult>(".show functions", throwOnError, cancellationToken).ConfigureAwait(false);
|
||||
if (functionSchemas == null)
|
||||
return null;
|
||||
|
||||
foreach (var fun in functionSchemas)
|
||||
{
|
||||
var parameters = TranslateParameters(fun.Parameters);
|
||||
var functionSymbol = new FunctionSymbol(fun.Name, fun.Body, parameters);
|
||||
members.Add(functionSymbol);
|
||||
}
|
||||
|
||||
var databaseSymbol = new DatabaseSymbol(databaseName, members);
|
||||
return databaseSymbol;
|
||||
}
|
||||
|
||||
public static CompletionItemKind CreateCompletionItemKind(CompletionKind kustoKind)
|
||||
{
|
||||
CompletionItemKind kind = CompletionItemKind.Variable;
|
||||
switch (kustoKind)
|
||||
{
|
||||
case CompletionKind.Syntax:
|
||||
kind = CompletionItemKind.Module;
|
||||
break;
|
||||
case CompletionKind.Column:
|
||||
kind = CompletionItemKind.Field;
|
||||
break;
|
||||
case CompletionKind.Variable:
|
||||
kind = CompletionItemKind.Variable;
|
||||
break;
|
||||
case CompletionKind.Table:
|
||||
kind = CompletionItemKind.File;
|
||||
break;
|
||||
case CompletionKind.Database:
|
||||
kind = CompletionItemKind.Method;
|
||||
break;
|
||||
case CompletionKind.LocalFunction:
|
||||
case CompletionKind.DatabaseFunction:
|
||||
case CompletionKind.BuiltInFunction:
|
||||
case CompletionKind.AggregateFunction:
|
||||
kind = CompletionItemKind.Function;
|
||||
break;
|
||||
default:
|
||||
kind = CompletionItemKind.Keyword;
|
||||
break;
|
||||
}
|
||||
|
||||
return kind;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets default keyword when user if not connected to any Kusto cluster.
|
||||
/// </summary>
|
||||
public static LanguageServices.Contracts.CompletionItem[] GetDefaultKeywords(ScriptDocumentInfo scriptDocumentInfo, Position textDocumentPosition){
|
||||
var kustoCodeService = new KustoCodeService(scriptDocumentInfo.Contents, GlobalState.Default);
|
||||
var script = CodeScript.From(scriptDocumentInfo.Contents, GlobalState.Default);
|
||||
script.TryGetTextPosition(textDocumentPosition.Line + 1, textDocumentPosition.Character, out int position); // Gets the actual offset based on line and local offset
|
||||
var completion = kustoCodeService.GetCompletionItems(position);
|
||||
|
||||
List<LanguageServices.Contracts.CompletionItem> completions = new List<LanguageServices.Contracts.CompletionItem>();
|
||||
foreach (var autoCompleteItem in completion.Items)
|
||||
{
|
||||
var label = autoCompleteItem.DisplayText;
|
||||
// convert the completion item candidates into vscode format CompletionItems
|
||||
completions.Add(AutoCompleteHelper.CreateCompletionItem(label, label + " keyword", label, CompletionItemKind.Keyword, scriptDocumentInfo.StartLine, scriptDocumentInfo.StartColumn, textDocumentPosition.Character));
|
||||
}
|
||||
|
||||
return completions.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets default diagnostics when user if not connected to any Kusto cluster.
|
||||
/// </summary>
|
||||
public static ScriptFileMarker[] GetDefaultDiagnostics(ScriptParseInfo parseInfo, ScriptFile scriptFile, string queryText){
|
||||
var kustoCodeService = new KustoCodeService(queryText, GlobalState.Default);
|
||||
var script = CodeScript.From(queryText, GlobalState.Default);
|
||||
var parseResult = kustoCodeService.GetDiagnostics();
|
||||
|
||||
parseInfo.ParseResult = parseResult;
|
||||
|
||||
// build a list of Kusto script file markers from the errors.
|
||||
List<ScriptFileMarker> markers = new List<ScriptFileMarker>();
|
||||
if (parseResult != null && parseResult.Count() > 0)
|
||||
{
|
||||
foreach (var error in parseResult)
|
||||
{
|
||||
script.TryGetLineAndOffset(error.Start, out var startLine, out var startOffset);
|
||||
script.TryGetLineAndOffset(error.End, out var endLine, out var endOffset);
|
||||
|
||||
// vscode specific format for error markers.
|
||||
markers.Add(new ScriptFileMarker()
|
||||
{
|
||||
Message = error.Message,
|
||||
Level = ScriptFileMarkerLevel.Error,
|
||||
ScriptRegion = new ScriptRegion()
|
||||
{
|
||||
File = scriptFile.FilePath,
|
||||
StartLineNumber = startLine,
|
||||
StartColumnNumber = startOffset,
|
||||
StartOffset = 0,
|
||||
EndLineNumber = endLine,
|
||||
EndColumnNumber = endOffset,
|
||||
EndOffset = 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return markers.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the schema for the specified database and returns a new <see cref="GlobalState"/> with the database added or updated.
|
||||
/// </summary>
|
||||
public static async Task<GlobalState> AddOrUpdateDatabaseAsync(IDataSource dataSource, GlobalState globals, string databaseName, string clusterName, bool throwOnError)
|
||||
{ // try and show error from here.
|
||||
DatabaseSymbol databaseSymbol = null;
|
||||
|
||||
if(databaseName != null){
|
||||
databaseSymbol = await LoadDatabaseAsync(dataSource, databaseName, throwOnError).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if(databaseSymbol == null){
|
||||
return globals;
|
||||
}
|
||||
|
||||
var cluster = globals.GetCluster(clusterName);
|
||||
if (cluster == null)
|
||||
{
|
||||
cluster = new ClusterSymbol(clusterName, new[] { databaseSymbol }, isOpen: true);
|
||||
globals = globals.AddOrUpdateCluster(cluster);
|
||||
}
|
||||
else
|
||||
{
|
||||
cluster = cluster.AddOrUpdateDatabase(databaseSymbol);
|
||||
globals = globals.AddOrUpdateCluster(cluster);
|
||||
}
|
||||
|
||||
globals = globals.WithCluster(cluster).WithDatabase(databaseSymbol);
|
||||
|
||||
return globals;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Kusto.Language;
|
||||
using Kusto.Language.Editor;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense
|
||||
{
|
||||
/// <summary>
|
||||
/// Data Source specific class for storing cached metadata regarding a parsed KQL file.
|
||||
/// </summary>
|
||||
public class ScriptParseInfo
|
||||
{
|
||||
private object buildingMetadataLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Event which tells if MetadataProvider is built fully or not
|
||||
/// </summary>
|
||||
public object BuildingMetadataLock
|
||||
{
|
||||
get { return this.buildingMetadataLock; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a flag determining is the LanguageService is connected
|
||||
/// </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding queue connection context key
|
||||
/// </summary>
|
||||
public string ConnectionKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the previous Kusto diagnostics result. TODOKusto: Check exact usage.
|
||||
/// </summary>
|
||||
public IReadOnlyList<Diagnostic> ParseResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current autocomplete suggestion list retrieved from the Kusto language library.
|
||||
/// So that other details like documentation can be later retrieved in ResolveCompletionItem.
|
||||
/// </summary>
|
||||
public IEnumerable<CompletionItem > CurrentSuggestions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the type of a data source.
|
||||
/// </summary>
|
||||
public enum DataSourceType
|
||||
{
|
||||
/// <summary>
|
||||
/// Unknown.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// A Kusto cluster.
|
||||
/// </summary>
|
||||
Kusto,
|
||||
|
||||
/// <summary>
|
||||
/// An Application Insights subscription.
|
||||
/// </summary>
|
||||
ApplicationInsights,
|
||||
|
||||
/// <summary>
|
||||
/// An Operations Management Suite (OMS) Log Analytics workspace.
|
||||
/// </summary>
|
||||
OmsLogAnalytics
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
public class DiagnosticsInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the options
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Options { get; set; }
|
||||
|
||||
public DiagnosticsInfo()
|
||||
{
|
||||
Options = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
}
|
||||
132
src/Microsoft.Kusto.ServiceLayer/DataSource/IDataSource.cs
Normal file
132
src/Microsoft.Kusto.ServiceLayer/DataSource/IDataSource.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Completion;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents data source utilities.
|
||||
/// </summary>
|
||||
public interface IDataSource : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The data source type.
|
||||
/// </summary>
|
||||
DataSourceType DataSourceType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The cluster/server name.
|
||||
/// </summary>
|
||||
string ClusterName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The current database name, if there is one.
|
||||
/// </summary>
|
||||
string DatabaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Executes a query.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The results.</returns>
|
||||
Task<IDataReader> ExecuteQueryAsync(string query, CancellationToken cancellationToken, string databaseName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a Kusto query that returns a scalar value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The result.</returns>
|
||||
Task<T> ExecuteScalarQueryAsync<T>(string query, CancellationToken cancellationToken, string databaseName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a Kusto query that returns a scalar value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the result.</typeparam>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>The result.</returns>
|
||||
Task<IEnumerable<T>> ExecuteControlCommandAsync<T>(string command, bool throwOnError, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Get children of the given parent
|
||||
/// </summary>
|
||||
/// <param name="parentMetadata">Parent object metadata.</param>
|
||||
/// <returns>Metadata for all children.</returns>
|
||||
DiagnosticsInfo GetDiagnostics(DataSourceObjectMetadata parentMetadata);
|
||||
|
||||
/// <summary>
|
||||
/// Get children of the given parent
|
||||
/// </summary>
|
||||
/// <param name="parentMetadata">Parent object metadata.</param>
|
||||
/// <param name="includeSizeDetails"></param>
|
||||
/// <returns>Metadata for all children.</returns>
|
||||
IEnumerable<DataSourceObjectMetadata> GetChildObjects(DataSourceObjectMetadata parentMetadata, bool includeSizeDetails = false);
|
||||
|
||||
/// <summary>
|
||||
/// Refresh object list for entire cluster.
|
||||
/// </summary>
|
||||
void Refresh();
|
||||
|
||||
/// <summary>
|
||||
/// Refresh object list for given object.
|
||||
/// </summary>
|
||||
/// <param name="objectMetadata">Object metadata.</param>
|
||||
void Refresh(DataSourceObjectMetadata objectMetadata);
|
||||
|
||||
/// <summary>
|
||||
/// Updates database and affected variables like GlobalState for given object.
|
||||
/// </summary>
|
||||
/// <param name="updateDatabase">Object metadata.</param>
|
||||
void UpdateDatabase(string databaseName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets autocomplete suggestions at given position.
|
||||
/// </summary>
|
||||
/// <param name="GetAutoCompleteSuggestions">Object metadata.</param>
|
||||
CompletionItem[] GetAutoCompleteSuggestions(ScriptDocumentInfo queryText, Position index, bool throwOnError = false);
|
||||
/// <summary>
|
||||
/// Gets quick info hover tooltips for the current position.
|
||||
/// </summary>
|
||||
/// <param name="GetHoverHelp">Object metadata.</param>
|
||||
Hover GetHoverHelp(ScriptDocumentInfo scriptDocumentInfo, Position textPosition, bool throwOnError = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets definition for a selected query text.
|
||||
/// </summary>
|
||||
/// <param name="GetDefinition">Object metadata.</param>
|
||||
DefinitionResult GetDefinition(string queryText, int index, int startLine, int startColumn, bool throwOnError = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of semantic diagnostic marks for the provided script file
|
||||
/// </summary>
|
||||
/// <param name="GetSemanticMarkers">Object metadata.</param>
|
||||
ScriptFileMarker[] GetSemanticMarkers(ScriptParseInfo parseInfo, ScriptFile scriptFile, string queryText);
|
||||
|
||||
/// <summary>
|
||||
/// Tells whether the data source exists.
|
||||
/// </summary>
|
||||
/// <returns>true if it exists; false otherwise.</returns>
|
||||
Task<bool> Exists();
|
||||
|
||||
/// <summary>
|
||||
/// Tells whether the object exists.
|
||||
/// </summary>
|
||||
/// <returns>true if it exists; false otherwise.</returns>
|
||||
bool Exists(DataSourceObjectMetadata objectMetadata);
|
||||
|
||||
/// <summary>
|
||||
/// Gets FunctionInfo object for a function
|
||||
/// </summary>
|
||||
/// <param name="functionName"></param>
|
||||
/// <returns></returns>
|
||||
string GenerateAlterFunctionScript(string functionName);
|
||||
}
|
||||
}
|
||||
1045
src/Microsoft.Kusto.ServiceLayer/DataSource/KustoDataSource.cs
Normal file
1045
src/Microsoft.Kusto.ServiceLayer/DataSource/KustoDataSource.cs
Normal file
File diff suppressed because it is too large
Load Diff
115
src/Microsoft.Kusto.ServiceLayer/DataSource/KustoQueryUtils.cs
Normal file
115
src/Microsoft.Kusto.ServiceLayer/DataSource/KustoQueryUtils.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
// <copyright file="KustoQueryUtils.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft. All Rights Reserved.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
public static class KustoQueryUtils
|
||||
{
|
||||
public const string StatementSeparator = "\n | "; // Start each statement on a new line. Not required by Kusto, but doing this for readability of scripts generated from here.
|
||||
|
||||
/// <summary>
|
||||
/// Escape table/column/database names for a Kusto query.
|
||||
/// </summary>
|
||||
/// <param name="name">The name to be escaped</param>
|
||||
/// <param name="alwaysEscape">Always escape if this flag is set</param>
|
||||
/// <returns>The escaped string</returns>
|
||||
public static string EscapeName(string name, bool alwaysEscape = false)
|
||||
{
|
||||
if (name.StartsWith("[@") || name == "*") // Field already escaped. No escaping required for '*' operand
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
string result = name;
|
||||
Regex rx = new Regex("[^_a-zA-Z0-9]");
|
||||
string [] kustoKeywordList = {"and", "anomalychart", "areachart", "asc", "barchart", "between", "bool", "boolean", "by",
|
||||
"columnchart", "consume", "contains", "containscs", "count", "date", "datetime", "default", "desc", "distinct",
|
||||
"double", "dynamic", "endswith", "evaluate", "extend", "false", "filter", "find", "first", "flags", "float",
|
||||
"getschema", "has", "hasprefix", "hassuffix", "in", "int", "join", "journal", "kind", "ladderchart", "last",
|
||||
"like", "limit", "linechart", "long", "materialize", "mvexpand", "notcontains", "notlike", "of", "or", "order",
|
||||
"parse", "piechart", "pivotchart", "print", "project", "queries", "real", "regex", "sample", "scatterchart",
|
||||
"search", "set", "sort", "stacked", "stacked100", "stackedareachart", "startswith", "string", "summarize",
|
||||
"take", "time", "timechart", "timeline", "timepivot", "timespan", "to", "top", "toscalar", "true", "union",
|
||||
"unstacked", "viewers", "where", "withsource"}; // add more keywords here
|
||||
|
||||
var escapeName = rx.IsMatch(name) || kustoKeywordList.Any(name.Contains) || alwaysEscape;
|
||||
if (escapeName)
|
||||
{
|
||||
if (name.IndexOf('"') > -1)
|
||||
{
|
||||
result = "[@'" + name + "']";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "[@\"" + name + "\"]";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsClusterLevelQuery(string query)
|
||||
{
|
||||
string [] clusterLevelQueryPrefixes = {
|
||||
".show databases",
|
||||
".show schema"
|
||||
};
|
||||
|
||||
return clusterLevelQueryPrefixes.Any(query.StartsWith);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an object of type DataSourceObjectMetadata to a dictionary<string, Dictionary<string, T>>. If the key exists then the item is added
|
||||
/// to the list. If not then the key is created and then added.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The dictionary of the dictionary that the list should be added to.</param>
|
||||
/// <param name="key">The key to be added.</param>
|
||||
/// <param name="metadata">The metadata to be added to the list.</param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void SafeAdd<T>(this Dictionary<string, Dictionary<string, T>> dictionary, string key,
|
||||
T metadata) where T : DataSourceObjectMetadata
|
||||
{
|
||||
if (dictionary.ContainsKey(key))
|
||||
{
|
||||
if (dictionary[key].ContainsKey(metadata.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dictionary[key].Add(metadata.Name, metadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary[key] = new Dictionary<string, T> {{metadata.Name, metadata}};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a range to a dictionary of ConcurrentDictionary. Adds range to existing IEnumerable within dictionary
|
||||
/// at the same key.
|
||||
/// </summary>
|
||||
/// <param name="dictionary"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="metadatas"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void AddRange<T>(this ConcurrentDictionary<string, IEnumerable<T>> dictionary, string key,
|
||||
List<T> metadatas) where T : DataSourceObjectMetadata
|
||||
{
|
||||
if (dictionary.ContainsKey(key))
|
||||
{
|
||||
metadatas.AddRange(dictionary[key]);
|
||||
}
|
||||
|
||||
dictionary[key] = metadatas.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Data;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||
{
|
||||
internal class KustoResultsReader : DataReaderWrapper
|
||||
{
|
||||
public KustoResultsReader(IDataReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kusto returns 3 results tables - QueryResults, QueryProperties, QueryStatus. When returning query results
|
||||
/// we want the caller to only read the first table. We override the NextResult function here to only return one table
|
||||
/// from the IDataReader.
|
||||
/// </summary>
|
||||
/*public override bool NextResult()
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Column metadata information
|
||||
/// </summary>
|
||||
public class ColumnMetadata : TableMetadata
|
||||
{
|
||||
public string TableName { get; set; }
|
||||
public string DataType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Metadata type enumeration
|
||||
/// </summary>
|
||||
public enum DataSourceMetadataType
|
||||
{
|
||||
Cluster = 0,
|
||||
Database = 1,
|
||||
Table = 2,
|
||||
Column = 3,
|
||||
Function = 4,
|
||||
Folder = 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Object metadata information
|
||||
/// </summary>
|
||||
public class DataSourceObjectMetadata
|
||||
{
|
||||
public DataSourceMetadataType MetadataType { get; set; }
|
||||
|
||||
public string MetadataTypeName { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string PrettyName { get; set; }
|
||||
|
||||
public string Urn { get; set; }
|
||||
|
||||
public string SizeInMB { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Database metadata information
|
||||
/// </summary>
|
||||
public class DatabaseMetadata : DataSourceObjectMetadata
|
||||
{
|
||||
public string ClusterName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Folder metadata information
|
||||
/// </summary>
|
||||
public class FolderMetadata : DataSourceObjectMetadata
|
||||
{
|
||||
public DataSourceObjectMetadata ParentMetadata { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
public class FunctionMetadata : DatabaseMetadata
|
||||
{
|
||||
public string DatabaseName { get; set; }
|
||||
|
||||
public string Parameters { get; set; }
|
||||
|
||||
public string Body { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Metadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Database metadata information
|
||||
/// </summary>
|
||||
public class TableMetadata : DatabaseMetadata
|
||||
{
|
||||
public string DatabaseName { get; set; }
|
||||
public string Folder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Models
|
||||
{
|
||||
public class ColumnInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The table name.
|
||||
/// </summary>
|
||||
public string Table { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The column name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The data type.
|
||||
/// </summary>
|
||||
public string DataType { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The folder name.
|
||||
/// </summary>
|
||||
public string Folder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Models
|
||||
{
|
||||
public class FunctionInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Parameters { get; set; }
|
||||
public string Body { get; set; }
|
||||
public string Folder { get; set; }
|
||||
public string DocString { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Models
|
||||
{
|
||||
public class TableInfo
|
||||
{
|
||||
public string TableName { get; set; }
|
||||
public string Folder { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
// This code is copied from the source described in the comment below.
|
||||
|
||||
// =======================================================================================
|
||||
// Microsoft Windows Server AppFabric Customer Advisory Team (CAT) Best Practices Series
|
||||
//
|
||||
// This sample is supplemental to the technical guidance published on the community
|
||||
// blog at http://blogs.msdn.com/appfabriccat/ and copied from
|
||||
// sqlmain ./sql/manageability/mfx/common/
|
||||
//
|
||||
// =======================================================================================
|
||||
// Copyright © 2012 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
// EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. YOU BEAR THE RISK OF USING IT.
|
||||
// =======================================================================================
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Collections;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a reliable way of opening connections to and executing commands
|
||||
/// taking into account potential network unreliability and a requirement for connection retry.
|
||||
/// </summary>
|
||||
public sealed partial class ReliableDataSourceConnection : IDisposable
|
||||
{
|
||||
private IDataSource _dataSource;
|
||||
private readonly RetryPolicy _connectionRetryPolicy;
|
||||
private RetryPolicy _commandRetryPolicy;
|
||||
private Guid _azureSessionId = Guid.NewGuid();
|
||||
|
||||
private string _connectionString;
|
||||
private string _azureAccountToken;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ReliableKustoClient class with a given connection string
|
||||
/// and a policy defining whether to retry a request if the connection fails to be opened or a command
|
||||
/// fails to be successfully executed.
|
||||
/// </summary>
|
||||
/// <param name="connectionString">The connection string used to open the SQL Azure database.</param>
|
||||
/// <param name="connectionRetryPolicy">The retry policy defining whether to retry a request if a connection fails to be established.</param>
|
||||
/// <param name="commandRetryPolicy">The retry policy defining whether to retry a request if a command fails to be executed.</param>
|
||||
public ReliableDataSourceConnection(string connectionString, RetryPolicy connectionRetryPolicy, RetryPolicy commandRetryPolicy, string azureAccountToken)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
_azureAccountToken = azureAccountToken;
|
||||
_dataSource = DataSourceFactory.Create(DataSourceType.Kusto, connectionString, azureAccountToken);
|
||||
|
||||
_connectionRetryPolicy = connectionRetryPolicy ?? RetryPolicyFactory.CreateNoRetryPolicy();
|
||||
_commandRetryPolicy = commandRetryPolicy ?? RetryPolicyFactory.CreateNoRetryPolicy();
|
||||
|
||||
_connectionRetryPolicy.RetryOccurred += RetryConnectionCallback;
|
||||
_commandRetryPolicy.RetryOccurred += RetryCommandCallback;
|
||||
}
|
||||
|
||||
private void RetryCommandCallback(RetryState retryState)
|
||||
{
|
||||
RetryPolicyUtils.RaiseSchemaAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.CommandRetry, _azureSessionId);
|
||||
}
|
||||
|
||||
private void RetryConnectionCallback(RetryState retryState)
|
||||
{
|
||||
RetryPolicyUtils.RaiseSchemaAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.ConnectionRetry, _azureSessionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or
|
||||
/// resetting managed and unmanaged resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">A flag indicating that managed resources must be released.</param>
|
||||
public void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_connectionRetryPolicy != null)
|
||||
{
|
||||
_connectionRetryPolicy.RetryOccurred -= RetryConnectionCallback;
|
||||
}
|
||||
|
||||
if (_commandRetryPolicy != null)
|
||||
{
|
||||
_commandRetryPolicy.RetryOccurred -= RetryCommandCallback;
|
||||
}
|
||||
|
||||
_dataSource.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection string for opening a connection to the SQL Azure database.
|
||||
/// </summary>
|
||||
public string ConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the policy which decides whether to retry a connection request, based on how many
|
||||
/// times the request has been made and the reason for the last failure.
|
||||
/// </summary>
|
||||
public RetryPolicy ConnectionRetryPolicy
|
||||
{
|
||||
get { return _connectionRetryPolicy; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the policy which decides whether to retry a command, based on how many
|
||||
/// times the request has been made and the reason for the last failure.
|
||||
/// </summary>
|
||||
public RetryPolicy CommandRetryPolicy
|
||||
{
|
||||
get { return _commandRetryPolicy; }
|
||||
set
|
||||
{
|
||||
Validate.IsNotNull(nameof(value), value);
|
||||
|
||||
if (_commandRetryPolicy != null)
|
||||
{
|
||||
_commandRetryPolicy.RetryOccurred -= RetryCommandCallback;
|
||||
}
|
||||
|
||||
_commandRetryPolicy = value;
|
||||
_commandRetryPolicy.RetryOccurred += RetryCommandCallback;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the server name from the underlying connection.
|
||||
/// </summary>
|
||||
public string ClusterName
|
||||
{
|
||||
get { return _dataSource.ClusterName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the underlying SqlConnection absolutely has to be accessed, for instance
|
||||
/// to pass to external APIs that require this type of connection, then this
|
||||
/// can be used.
|
||||
/// </summary>
|
||||
/// <returns><see cref="SqlConnection"/></returns>
|
||||
public IDataSource GetUnderlyingConnection()
|
||||
{
|
||||
return _dataSource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current database for an open Connection object.
|
||||
/// </summary>
|
||||
/// <param name="databaseName">The name of the database to use in place of the current database.</param>
|
||||
public void ChangeDatabase(string databaseName)
|
||||
{
|
||||
_dataSource.UpdateDatabase(databaseName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a database connection with the settings specified by the ConnectionString
|
||||
/// property of the provider-specific Connection object.
|
||||
/// </summary>
|
||||
public void Open()
|
||||
{
|
||||
// TODOKusto: Should we initialize in the constructor or here. Set a breapoint and check.
|
||||
// Check if retry policy was specified, if not, disable retries by executing the Open method using RetryPolicy.NoRetry.
|
||||
if(_dataSource == null)
|
||||
{
|
||||
_connectionRetryPolicy.ExecuteAction(() =>
|
||||
{
|
||||
_dataSource = DataSourceFactory.Create(DataSourceType.Kusto, _connectionString, _azureAccountToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a database connection with the settings specified by the ConnectionString
|
||||
/// property of the provider-specific Connection object.
|
||||
/// </summary>
|
||||
public Task OpenAsync(CancellationToken token)
|
||||
{
|
||||
// Make sure that the token isn't cancelled before we try
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
return Task.FromCanceled(token);
|
||||
}
|
||||
|
||||
// Check if retry policy was specified, if not, disable retries by executing the Open method using RetryPolicy.NoRetry.
|
||||
try
|
||||
{
|
||||
return _connectionRetryPolicy.ExecuteAction(async () =>
|
||||
{
|
||||
await Task.Run(() => Open());
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Task.FromException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the connection to the database.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time to wait while trying to establish a connection before terminating
|
||||
/// the attempt and generating an error.
|
||||
/// </summary>
|
||||
public int ConnectionTimeout
|
||||
{
|
||||
get { return 30; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the current database or the database to be used after a
|
||||
/// connection is opened.
|
||||
/// </summary>
|
||||
public string Database
|
||||
{
|
||||
get { return _dataSource.DatabaseName; }
|
||||
}
|
||||
|
||||
private void VerifyConnectionOpen(ReliableDataSourceConnection conn)
|
||||
{
|
||||
if(conn.GetUnderlyingConnection() == null)
|
||||
{
|
||||
conn.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Formatter.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// A formatting request to process an entire document
|
||||
/// </summary>
|
||||
public class DocumentFormattingRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<DocumentFormattingParams, TextEdit[]> Type =
|
||||
RequestType<DocumentFormattingParams, TextEdit[]>.Create("textDocument/formatting");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A formatting request to process a specific range inside a document
|
||||
/// </summary>
|
||||
public class DocumentRangeFormattingRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<DocumentRangeFormattingParams, TextEdit[]> Type =
|
||||
RequestType<DocumentRangeFormattingParams, TextEdit[]>.Create("textDocument/rangeFormatting");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A formatting request to handle a user typing, giving a chance to update the text based on this
|
||||
/// </summary>
|
||||
public class DocumentOnTypeFormattingRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<DocumentOnTypeFormattingParams, TextEdit[]> Type =
|
||||
RequestType<DocumentOnTypeFormattingParams, TextEdit[]>.Create("textDocument/onTypeFormatting");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Params for the <see cref="DocumentFormattingRequest"/>
|
||||
/// </summary>
|
||||
public class DocumentFormattingParams
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The document to format.
|
||||
/// </summary>
|
||||
public TextDocumentIdentifier TextDocument { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The formatting options
|
||||
/// </summary>
|
||||
public FormattingOptions Options { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Params for the <see cref="DocumentRangeFormattingRequest"/>
|
||||
/// </summary>
|
||||
public class DocumentRangeFormattingParams : DocumentFormattingParams
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The range to format
|
||||
/// </summary>
|
||||
public Range Range { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Params for the <see cref="DocumentOnTypeFormattingRequest"/>
|
||||
/// </summary>
|
||||
public class DocumentOnTypeFormattingParams : DocumentFormattingParams
|
||||
{
|
||||
/// <summary>
|
||||
/// The position at which this request was sent.
|
||||
|
||||
/// </summary>
|
||||
Position Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The character that has been typed.
|
||||
|
||||
/// </summary>
|
||||
string Ch { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value-object describing what options formatting should use.
|
||||
/// </summary>
|
||||
public class FormattingOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of a tab in spaces
|
||||
/// </summary>
|
||||
public int TabSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prefer spaces over tabs.
|
||||
/// </summary>
|
||||
public bool InsertSpaces { get; set; }
|
||||
|
||||
// TODO there may be other options passed by VSCode - format is
|
||||
// [key: string]: boolean | number | string;
|
||||
// Determine how these might be passed and add them here
|
||||
}
|
||||
|
||||
}
|
||||
171
src/Microsoft.Kusto.ServiceLayer/Formatter/Impl/FormatOptions.cs
Normal file
171
src/Microsoft.Kusto.ServiceLayer/Formatter/Impl/FormatOptions.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
//
|
||||
// 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.ComponentModel;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Formatter
|
||||
{
|
||||
|
||||
public enum CasingOptions { None, Uppercase, Lowercase };
|
||||
|
||||
/// <summary>
|
||||
/// The supported options to use when formatting text
|
||||
/// </summary>
|
||||
public class FormatOptions : INotifyPropertyChanged
|
||||
{
|
||||
|
||||
private int spacesPerIndent;
|
||||
private bool useTabs = false;
|
||||
private bool encloseIdentifiersInSquareBrackets;
|
||||
private bool placeCommasBeforeNextStatement;
|
||||
private bool placeEachReferenceOnNewLineInQueryStatements;
|
||||
private CasingOptions keywordCasing;
|
||||
private CasingOptions datatypeCasing;
|
||||
private bool alignColumnDefinitionsInColumns;
|
||||
|
||||
internal FormatOptions()
|
||||
{
|
||||
SpacesPerIndent = 4;
|
||||
UseTabs = false;
|
||||
PlaceCommasBeforeNextStatement = false;
|
||||
EncloseIdentifiersInSquareBrackets = false;
|
||||
PlaceEachReferenceOnNewLineInQueryStatements = false;
|
||||
}
|
||||
|
||||
public int SpacesPerIndent
|
||||
{
|
||||
get { return spacesPerIndent; }
|
||||
set { spacesPerIndent = value;
|
||||
RaisePropertyChanged("SpacesPerIndent"); }
|
||||
}
|
||||
|
||||
public bool UseTabs
|
||||
{
|
||||
get { return useTabs; }
|
||||
set
|
||||
{
|
||||
useTabs = value;
|
||||
// raise UseTabs & UseSpaces property changed events
|
||||
RaisePropertyChanged("UseTabs");
|
||||
RaisePropertyChanged("UseSpaces");
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseSpaces
|
||||
{
|
||||
get { return !UseTabs; }
|
||||
set { UseTabs = !value; }
|
||||
}
|
||||
|
||||
public bool EncloseIdentifiersInSquareBrackets
|
||||
{
|
||||
get { return encloseIdentifiersInSquareBrackets; }
|
||||
set
|
||||
{
|
||||
encloseIdentifiersInSquareBrackets = value;
|
||||
RaisePropertyChanged("EncloseIdentifiersInSquareBrackets");
|
||||
}
|
||||
}
|
||||
|
||||
public bool PlaceCommasBeforeNextStatement
|
||||
{
|
||||
get { return placeCommasBeforeNextStatement; }
|
||||
set
|
||||
{
|
||||
placeCommasBeforeNextStatement = value;
|
||||
RaisePropertyChanged("PlaceCommasBeforeNextStatement");
|
||||
}
|
||||
}
|
||||
|
||||
public bool PlaceEachReferenceOnNewLineInQueryStatements
|
||||
{
|
||||
get { return placeEachReferenceOnNewLineInQueryStatements; }
|
||||
set
|
||||
{
|
||||
placeEachReferenceOnNewLineInQueryStatements = value;
|
||||
RaisePropertyChanged("PlaceEachReferenceOnNewLineInQueryStatements");
|
||||
}
|
||||
}
|
||||
|
||||
public CasingOptions KeywordCasing
|
||||
{
|
||||
get { return keywordCasing; }
|
||||
set
|
||||
{
|
||||
keywordCasing = value;
|
||||
RaisePropertyChanged("KeywordCasing");
|
||||
}
|
||||
}
|
||||
|
||||
public bool UppercaseKeywords
|
||||
{
|
||||
get { return KeywordCasing == CasingOptions.Uppercase; }
|
||||
}
|
||||
public bool LowercaseKeywords
|
||||
{
|
||||
get { return KeywordCasing == CasingOptions.Lowercase; }
|
||||
}
|
||||
|
||||
public bool DoNotFormatKeywords
|
||||
{
|
||||
get { return KeywordCasing == CasingOptions.None; }
|
||||
}
|
||||
|
||||
public CasingOptions DatatypeCasing
|
||||
{
|
||||
get { return datatypeCasing; }
|
||||
set
|
||||
{
|
||||
datatypeCasing = value;
|
||||
RaisePropertyChanged("DatatypeCasing");
|
||||
}
|
||||
}
|
||||
|
||||
public bool UppercaseDataTypes
|
||||
{
|
||||
get { return DatatypeCasing == CasingOptions.Uppercase; }
|
||||
}
|
||||
public bool LowercaseDataTypes
|
||||
{
|
||||
get { return DatatypeCasing == CasingOptions.Lowercase; }
|
||||
}
|
||||
public bool DoNotFormatDataTypes
|
||||
{
|
||||
get { return DatatypeCasing == CasingOptions.None; }
|
||||
}
|
||||
|
||||
public bool AlignColumnDefinitionsInColumns
|
||||
{
|
||||
get { return alignColumnDefinitionsInColumns; }
|
||||
set
|
||||
{
|
||||
alignColumnDefinitionsInColumns = value;
|
||||
RaisePropertyChanged("AlignColumnDefinitionsInColumns");
|
||||
}
|
||||
}
|
||||
|
||||
private void RaisePropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public static void Copy(FormatOptions target, FormatOptions source)
|
||||
{
|
||||
target.AlignColumnDefinitionsInColumns = source.AlignColumnDefinitionsInColumns;
|
||||
target.DatatypeCasing = source.DatatypeCasing;
|
||||
target.EncloseIdentifiersInSquareBrackets = source.EncloseIdentifiersInSquareBrackets;
|
||||
target.KeywordCasing = source.KeywordCasing;
|
||||
target.PlaceCommasBeforeNextStatement = source.PlaceCommasBeforeNextStatement;
|
||||
target.PlaceEachReferenceOnNewLineInQueryStatements = source.PlaceEachReferenceOnNewLineInQueryStatements;
|
||||
target.SpacesPerIndent = source.SpacesPerIndent;
|
||||
target.UseSpaces = source.UseSpaces;
|
||||
target.UseTabs = source.UseTabs;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
//
|
||||
// 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.Generic;
|
||||
using System.Composition;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
//using Kusto.Language;
|
||||
//using Kusto.Language.Editor;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.Hosting;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.Kusto.ServiceLayer.Formatter.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.SqlContext;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Range = Microsoft.Kusto.ServiceLayer.Workspace.Contracts.Range;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.Formatter
|
||||
{
|
||||
|
||||
[Export(typeof(IHostedService))]
|
||||
public class TSqlFormatterService : HostedService<TSqlFormatterService>, IComposableService
|
||||
{
|
||||
private FormatterSettings settings;
|
||||
/// <summary>
|
||||
/// The default constructor is required for MEF-based composable services
|
||||
/// </summary>
|
||||
public TSqlFormatterService()
|
||||
{
|
||||
settings = new FormatterSettings();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void InitializeService(IProtocolEndpoint serviceHost)
|
||||
{
|
||||
Logger.Write(TraceEventType.Verbose, "TSqlFormatter initialized");
|
||||
serviceHost.SetRequestHandler(DocumentFormattingRequest.Type, HandleDocFormatRequest);
|
||||
serviceHost.SetRequestHandler(DocumentRangeFormattingRequest.Type, HandleDocRangeFormatRequest);
|
||||
WorkspaceService?.RegisterConfigChangeCallback(HandleDidChangeConfigurationNotification);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the workspace service. Note: should handle case where this is null in cases where unit tests do not set this up
|
||||
/// </summary>
|
||||
private WorkspaceService<SqlToolsSettings> WorkspaceService
|
||||
{
|
||||
get { return ServiceProvider.GetService<WorkspaceService<SqlToolsSettings>>(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the language service. Note: should handle case where this is null in cases where unit tests do not set this up
|
||||
/// </summary>
|
||||
private LanguageService LanguageService
|
||||
{
|
||||
get { return ServiceProvider.GetService<LanguageService>(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure formatter settings are always up to date
|
||||
/// </summary>
|
||||
public Task HandleDidChangeConfigurationNotification(
|
||||
SqlToolsSettings newSettings,
|
||||
SqlToolsSettings oldSettings,
|
||||
EventContext eventContext)
|
||||
{
|
||||
// update the current settings to reflect any changes (assuming formatter settings exist)
|
||||
settings = newSettings?.SqlTools?.Format ?? settings;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public async Task HandleDocFormatRequest(DocumentFormattingParams docFormatParams, RequestContext<TextEdit[]> requestContext)
|
||||
{
|
||||
Func<Task<TextEdit[]>> requestHandler = () =>
|
||||
{
|
||||
return FormatAndReturnEdits(docFormatParams);
|
||||
};
|
||||
await HandleRequest(requestHandler, requestContext, "HandleDocFormatRequest");
|
||||
|
||||
DocumentStatusHelper.SendTelemetryEvent(requestContext, CreateTelemetryProps(isDocFormat: true));
|
||||
}
|
||||
|
||||
public async Task HandleDocRangeFormatRequest(DocumentRangeFormattingParams docRangeFormatParams, RequestContext<TextEdit[]> requestContext)
|
||||
{
|
||||
Func<Task<TextEdit[]>> requestHandler = () =>
|
||||
{
|
||||
return FormatRangeAndReturnEdits(docRangeFormatParams);
|
||||
};
|
||||
await HandleRequest(requestHandler, requestContext, "HandleDocRangeFormatRequest");
|
||||
|
||||
DocumentStatusHelper.SendTelemetryEvent(requestContext, CreateTelemetryProps(isDocFormat: false));
|
||||
}
|
||||
private static TelemetryProperties CreateTelemetryProps(bool isDocFormat)
|
||||
{
|
||||
return new TelemetryProperties
|
||||
{
|
||||
Properties = new Dictionary<string, string>
|
||||
{
|
||||
{ TelemetryPropertyNames.FormatType,
|
||||
isDocFormat ? TelemetryPropertyNames.DocumentFormatType : TelemetryPropertyNames.RangeFormatType }
|
||||
},
|
||||
EventName = TelemetryEventNames.FormatCode
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<TextEdit[]> FormatRangeAndReturnEdits(DocumentRangeFormattingParams docFormatParams)
|
||||
{
|
||||
return await Task.Factory.StartNew(() =>
|
||||
{
|
||||
if (ShouldSkipFormatting(docFormatParams))
|
||||
{
|
||||
return Array.Empty<TextEdit>();
|
||||
}
|
||||
|
||||
var range = docFormatParams.Range;
|
||||
ScriptFile scriptFile = GetFile(docFormatParams);
|
||||
if (scriptFile == null)
|
||||
{
|
||||
return new TextEdit[0];
|
||||
}
|
||||
TextEdit textEdit = new TextEdit { Range = range };
|
||||
string text = scriptFile.GetTextInRange(range.ToBufferRange());
|
||||
return DoFormat(docFormatParams, textEdit, text);
|
||||
});
|
||||
}
|
||||
|
||||
private bool ShouldSkipFormatting(DocumentFormattingParams docFormatParams)
|
||||
{
|
||||
if (docFormatParams == null
|
||||
|| docFormatParams.TextDocument == null
|
||||
|| docFormatParams.TextDocument.Uri == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return (LanguageService != null && LanguageService.ShouldSkipNonMssqlFile(docFormatParams.TextDocument.Uri));
|
||||
}
|
||||
|
||||
private async Task<TextEdit[]> FormatAndReturnEdits(DocumentFormattingParams docFormatParams)
|
||||
{
|
||||
return await Task.Factory.StartNew(() =>
|
||||
{
|
||||
if (ShouldSkipFormatting(docFormatParams))
|
||||
{
|
||||
return Array.Empty<TextEdit>();
|
||||
}
|
||||
|
||||
var scriptFile = GetFile(docFormatParams);
|
||||
if (scriptFile == null
|
||||
|| scriptFile.FileLines.Count == 0)
|
||||
{
|
||||
return new TextEdit[0];
|
||||
}
|
||||
TextEdit textEdit = PrepareEdit(scriptFile);
|
||||
string text = scriptFile.Contents;
|
||||
return DoFormat(docFormatParams, textEdit, text);
|
||||
});
|
||||
}
|
||||
|
||||
private TextEdit[] DoFormat(DocumentFormattingParams docFormatParams, TextEdit edit, string text)
|
||||
{
|
||||
Validate.IsNotNull(nameof(docFormatParams), docFormatParams);
|
||||
|
||||
FormatOptions options = GetOptions(docFormatParams);
|
||||
List<TextEdit> edits = new List<TextEdit>();
|
||||
edit.NewText = Format(text, options, false);
|
||||
// TODO do not add if no formatting needed?
|
||||
edits.Add(edit);
|
||||
return edits.ToArray();
|
||||
}
|
||||
|
||||
private FormatOptions GetOptions(DocumentFormattingParams docFormatParams)
|
||||
{
|
||||
return MergeFormatOptions(docFormatParams.Options, settings);
|
||||
}
|
||||
|
||||
internal static FormatOptions MergeFormatOptions(FormattingOptions formatRequestOptions, FormatterSettings settings)
|
||||
|
||||
{
|
||||
FormatOptions options = new FormatOptions();
|
||||
if (formatRequestOptions != null)
|
||||
{
|
||||
options.UseSpaces = formatRequestOptions.InsertSpaces;
|
||||
options.SpacesPerIndent = formatRequestOptions.TabSize;
|
||||
}
|
||||
UpdateFormatOptionsFromSettings(options, settings);
|
||||
return options;
|
||||
}
|
||||
|
||||
internal static void UpdateFormatOptionsFromSettings(FormatOptions options, FormatterSettings settings)
|
||||
{
|
||||
Validate.IsNotNull(nameof(options), options);
|
||||
if (settings != null)
|
||||
{
|
||||
if (settings.AlignColumnDefinitionsInColumns.HasValue) { options.AlignColumnDefinitionsInColumns = settings.AlignColumnDefinitionsInColumns.Value; }
|
||||
|
||||
if (settings.PlaceCommasBeforeNextStatement.HasValue) { options.PlaceCommasBeforeNextStatement = settings.PlaceCommasBeforeNextStatement.Value; }
|
||||
|
||||
if (settings.PlaceSelectStatementReferencesOnNewLine.HasValue) { options.PlaceEachReferenceOnNewLineInQueryStatements = settings.PlaceSelectStatementReferencesOnNewLine.Value; }
|
||||
|
||||
if (settings.UseBracketForIdentifiers.HasValue) { options.EncloseIdentifiersInSquareBrackets = settings.UseBracketForIdentifiers.Value; }
|
||||
|
||||
options.DatatypeCasing = settings.DatatypeCasing;
|
||||
options.KeywordCasing = settings.KeywordCasing;
|
||||
}
|
||||
}
|
||||
|
||||
private ScriptFile GetFile(DocumentFormattingParams docFormatParams)
|
||||
{
|
||||
return WorkspaceService.Workspace.GetFile(docFormatParams.TextDocument.Uri);
|
||||
}
|
||||
|
||||
private static TextEdit PrepareEdit(ScriptFile scriptFile)
|
||||
{
|
||||
int fileLines = scriptFile.FileLines.Count;
|
||||
Position start = new Position { Line = 0, Character = 0 };
|
||||
int lastChar = scriptFile.FileLines[scriptFile.FileLines.Count - 1].Length;
|
||||
Position end = new Position { Line = scriptFile.FileLines.Count - 1, Character = lastChar };
|
||||
|
||||
TextEdit edit = new TextEdit
|
||||
{
|
||||
Range = new Range { Start = start, End = end }
|
||||
};
|
||||
return edit;
|
||||
}
|
||||
|
||||
private async Task HandleRequest<T>(Func<Task<T>> handler, RequestContext<T> requestContext, string requestType)
|
||||
{
|
||||
Logger.Write(TraceEventType.Verbose, requestType);
|
||||
|
||||
try
|
||||
{
|
||||
T result = await handler();
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await requestContext.SendError(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public string Format(TextReader input)
|
||||
{
|
||||
string originalSql = input.ReadToEnd();
|
||||
return Format(originalSql, new FormatOptions());
|
||||
}
|
||||
|
||||
public string Format(string input, FormatOptions options)
|
||||
{
|
||||
return Format(input, options, true);
|
||||
}
|
||||
|
||||
public string Format(string input, FormatOptions options, bool verifyOutput)
|
||||
{
|
||||
string result = null;
|
||||
//TODOKusto: Implement formatting for Kusto generically here.
|
||||
//var kustoCodeService = new KustoCodeService(input, GlobalState.Default);
|
||||
//var formattedText = kustoCodeService.GetFormattedText();
|
||||
//DoFormat(input, options, verifyOutput, visitor =>
|
||||
//{
|
||||
//result = formattedText.Text;
|
||||
//});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*public void Format(string input, FormatOptions options, bool verifyOutput, Replacement.OnReplace replace)
|
||||
{
|
||||
DoFormat(input, options, verifyOutput, visitor =>
|
||||
{
|
||||
foreach (Replacement r in visitor.Context.Replacements)
|
||||
{
|
||||
r.Apply(replace);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DoFormat(string input, FormatOptions options, bool verifyOutput, Action<FormatterVisitor> postFormatAction)
|
||||
{
|
||||
Validate.IsNotNull(nameof(input), input);
|
||||
Validate.IsNotNull(nameof(options), options);
|
||||
|
||||
ParseResult result = Parser.Parse(input);
|
||||
FormatContext context = new FormatContext(result.Script, options);
|
||||
|
||||
FormatterVisitor visitor = new FormatterVisitor(context, ServiceProvider);
|
||||
result.Script.Accept(visitor);
|
||||
if (verifyOutput)
|
||||
{
|
||||
visitor.VerifyFormat();
|
||||
}
|
||||
|
||||
postFormatAction?.Invoke(visitor);
|
||||
}*/
|
||||
}
|
||||
|
||||
internal static class RangeExtensions
|
||||
{
|
||||
public static BufferRange ToBufferRange(this Range range)
|
||||
{
|
||||
// It turns out that VSCode sends Range objects as 0-indexed lines, while
|
||||
// our BufferPosition and BufferRange logic assumes 1-indexed. Therefore
|
||||
// need to increment all ranges by 1 when copying internally and reduce
|
||||
// when returning to the caller
|
||||
return new BufferRange(
|
||||
new BufferPosition(range.Start.Line + 1, range.Start.Character + 1),
|
||||
new BufferPosition(range.End.Line + 1, range.End.Character + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
136
src/Microsoft.Kusto.ServiceLayer/HostLoader.cs
Normal file
136
src/Microsoft.Kusto.ServiceLayer/HostLoader.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// 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.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Credentials;
|
||||
using Microsoft.SqlTools.Extensibility;
|
||||
using Microsoft.SqlTools.Hosting;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.Kusto.ServiceLayer.Admin;
|
||||
using Microsoft.Kusto.ServiceLayer.Metadata;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.Kusto.ServiceLayer.Hosting;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices;
|
||||
using Microsoft.Kusto.ServiceLayer.QueryExecution;
|
||||
using Microsoft.Kusto.ServiceLayer.Scripting;
|
||||
using Microsoft.Kusto.ServiceLayer.SqlContext;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace;
|
||||
using SqlToolsContext = Microsoft.SqlTools.ServiceLayer.SqlContext.SqlToolsContext;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides support for starting up a service host. This is a common responsibility
|
||||
/// for both the main service program and test driver that interacts with it
|
||||
/// </summary>
|
||||
public static class HostLoader
|
||||
{
|
||||
private static object lockObject = new object();
|
||||
private static bool isLoaded;
|
||||
|
||||
private static readonly string[] inclusionList =
|
||||
{
|
||||
"microsofsqltoolscredentials.dll",
|
||||
"microsoft.sqltools.hosting.dll",
|
||||
"microsoftkustoservicelayer.dll"
|
||||
};
|
||||
|
||||
internal static ServiceHost CreateAndStartServiceHost(SqlToolsContext sqlToolsContext)
|
||||
{
|
||||
ServiceHost serviceHost = ServiceHost.Instance;
|
||||
lock (lockObject)
|
||||
{
|
||||
if (!isLoaded)
|
||||
{
|
||||
// Grab the instance of the service host
|
||||
serviceHost.Initialize();
|
||||
|
||||
InitializeRequestHandlersAndServices(serviceHost, sqlToolsContext);
|
||||
|
||||
// Start the service only after all request handlers are setup. This is vital
|
||||
// as otherwise the Initialize event can be lost - it's processed and discarded before the handler
|
||||
// is hooked up to receive the message
|
||||
serviceHost.Start().Wait();
|
||||
isLoaded = true;
|
||||
}
|
||||
}
|
||||
return serviceHost;
|
||||
}
|
||||
|
||||
private static void InitializeRequestHandlersAndServices(ServiceHost serviceHost, SqlToolsContext sqlToolsContext)
|
||||
{
|
||||
// Load extension provider, which currently finds all exports in current DLL. Can be changed to find based
|
||||
// on directory or assembly list quite easily in the future
|
||||
ExtensionServiceProvider serviceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider(inclusionList);
|
||||
serviceProvider.RegisterSingleService(sqlToolsContext);
|
||||
serviceProvider.RegisterSingleService(serviceHost);
|
||||
|
||||
// Initialize and register singleton services so they're accessible for any MEF service. In the future, these
|
||||
// could be updated to be IComposableServices, which would avoid the requirement to define a singleton instance
|
||||
// and instead have MEF handle discovery & loading
|
||||
WorkspaceService<SqlToolsSettings>.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(WorkspaceService<SqlToolsSettings>.Instance);
|
||||
|
||||
LanguageService.Instance.InitializeService(serviceHost, sqlToolsContext);
|
||||
serviceProvider.RegisterSingleService(LanguageService.Instance);
|
||||
|
||||
ConnectionService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(ConnectionService.Instance);
|
||||
|
||||
CredentialService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(CredentialService.Instance);
|
||||
|
||||
QueryExecutionService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(QueryExecutionService.Instance);
|
||||
|
||||
ScriptingService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(ScriptingService.Instance);
|
||||
|
||||
AdminService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(AdminService.Instance);
|
||||
|
||||
MetadataService.Instance.InitializeService(serviceHost);
|
||||
serviceProvider.RegisterSingleService(MetadataService.Instance);
|
||||
|
||||
InitializeHostedServices(serviceProvider, serviceHost);
|
||||
serviceHost.ServiceProvider = serviceProvider;
|
||||
|
||||
serviceHost.InitializeRequestHandlers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal to support testing. Initializes <see cref="IHostedService"/> instances in the service,
|
||||
/// and registers them for their preferred service type
|
||||
/// </summary>
|
||||
internal static void InitializeHostedServices(RegisteredServiceProvider provider, IProtocolEndpoint host)
|
||||
{
|
||||
// Pre-register all services before initializing. This ensures that if one service wishes to reference
|
||||
// another one during initialization, it will be able to safely do so
|
||||
foreach (IHostedService service in provider.GetServices<IHostedService>())
|
||||
{
|
||||
provider.RegisterSingleService(service.ServiceType, service);
|
||||
}
|
||||
|
||||
ServiceHost serviceHost = host as ServiceHost;
|
||||
foreach (IHostedService service in provider.GetServices<IHostedService>())
|
||||
{
|
||||
// Initialize all hosted services, and register them in the service provider for their requested
|
||||
// service type. This ensures that when searching for the ConnectionService you can get it without
|
||||
// searching for an IHostedService of type ConnectionService
|
||||
service.InitializeService(host);
|
||||
|
||||
IDisposable disposable = service as IDisposable;
|
||||
if (serviceHost != null && disposable != null)
|
||||
{
|
||||
serviceHost.RegisterShutdownTask(async (shutdownParams, shutdownRequestContext) =>
|
||||
{
|
||||
disposable.Dispose();
|
||||
await Task.FromResult(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
using Range = Microsoft.Kusto.ServiceLayer.Workspace.Contracts.Range;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// All the conversion of intellisense info to vscode format is done in this class.
|
||||
/// </summary>
|
||||
public static class AutoCompleteHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a completion item from the default item text since VS Code expects CompletionItems
|
||||
/// </summary>
|
||||
/// <param name="label"></param>
|
||||
/// <param name="detail"></param>
|
||||
/// <param name="insertText"></param>
|
||||
/// <param name="kind"></param>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="startColumn"></param>
|
||||
/// <param name="endColumn"></param>
|
||||
public static CompletionItem CreateCompletionItem(
|
||||
string label,
|
||||
string detail,
|
||||
string insertText,
|
||||
CompletionItemKind kind,
|
||||
int row,
|
||||
int startColumn,
|
||||
int endColumn)
|
||||
{
|
||||
CompletionItem item = new CompletionItem
|
||||
{
|
||||
Label = label,
|
||||
Kind = kind,
|
||||
Detail = detail,
|
||||
InsertText = insertText,
|
||||
TextEdit = new TextEdit
|
||||
{
|
||||
NewText = insertText,
|
||||
Range = new Range
|
||||
{
|
||||
Start = new Position
|
||||
{
|
||||
Line = row,
|
||||
Character = startColumn
|
||||
},
|
||||
End = new Position
|
||||
{
|
||||
Line = row,
|
||||
Character = endColumn
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts QuickInfo object into a VS Code Hover object
|
||||
/// </summary>
|
||||
/// <param name="quickInfo"></param>
|
||||
/// <param name="language"></param>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="startColumn"></param>
|
||||
/// <param name="endColumn"></param>
|
||||
public static Hover ConvertQuickInfoToHover(
|
||||
string quickInfoText,
|
||||
string language,
|
||||
int row,
|
||||
int startColumn,
|
||||
int endColumn)
|
||||
{
|
||||
// convert from the parser format to the VS Code wire format
|
||||
var markedStrings = new MarkedString[1];
|
||||
if (quickInfoText != null)
|
||||
{
|
||||
markedStrings[0] = new MarkedString()
|
||||
{
|
||||
Language = language,
|
||||
Value = quickInfoText
|
||||
};
|
||||
|
||||
return new Hover()
|
||||
{
|
||||
Contents = markedStrings,
|
||||
Range = new Range
|
||||
{
|
||||
Start = new Position
|
||||
{
|
||||
Line = row,
|
||||
Character = startColumn
|
||||
},
|
||||
End = new Position
|
||||
{
|
||||
Line = row,
|
||||
Character = endColumn
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
//
|
||||
// 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.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Main class for the Binding Queue
|
||||
/// </summary>
|
||||
public class BindingQueue<T> : IDisposable where T : IBindingContext, new()
|
||||
{
|
||||
internal const int QueueThreadStackSize = 5 * 1024 * 1024;
|
||||
|
||||
private CancellationTokenSource processQueueCancelToken = null;
|
||||
|
||||
private ManualResetEvent itemQueuedEvent = new ManualResetEvent(initialState: false);
|
||||
|
||||
private object bindingQueueLock = new object();
|
||||
|
||||
private LinkedList<QueueItem> bindingQueue = new LinkedList<QueueItem>();
|
||||
|
||||
private object bindingContextLock = new object();
|
||||
|
||||
private Task queueProcessorTask;
|
||||
|
||||
public delegate void UnhandledExceptionDelegate(string connectionKey, Exception ex);
|
||||
|
||||
public event UnhandledExceptionDelegate OnUnhandledException;
|
||||
|
||||
/// <summary>
|
||||
/// Map from context keys to binding context instances
|
||||
/// Internal for testing purposes only
|
||||
/// </summary>
|
||||
internal Dictionary<string, IBindingContext> BindingContextMap { get; set; }
|
||||
|
||||
internal Dictionary<IBindingContext, Task> BindingContextTasks { get; set; } = new Dictionary<IBindingContext, Task>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a binding queue instance
|
||||
/// </summary>
|
||||
public BindingQueue()
|
||||
{
|
||||
this.BindingContextMap = new Dictionary<string, IBindingContext>();
|
||||
this.StartQueueProcessor();
|
||||
}
|
||||
|
||||
public void StartQueueProcessor()
|
||||
{
|
||||
this.queueProcessorTask = StartQueueProcessorAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the binding queue by sending cancellation request
|
||||
/// </summary>
|
||||
/// <param name="timeout"></param>
|
||||
public bool StopQueueProcessor(int timeout)
|
||||
{
|
||||
this.processQueueCancelToken.Cancel();
|
||||
return this.queueProcessorTask.Wait(timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if cancellation is requested
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsCancelRequested
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.processQueueCancelToken.IsCancellationRequested;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queue a binding request item
|
||||
/// </summary>
|
||||
public virtual QueueItem QueueBindingOperation(
|
||||
string key,
|
||||
Func<IBindingContext, CancellationToken, object> bindOperation,
|
||||
Func<IBindingContext, object> timeoutOperation = null,
|
||||
Func<Exception, object> errorHandler = null,
|
||||
int? bindingTimeout = null,
|
||||
int? waitForLockTimeout = null)
|
||||
{
|
||||
// don't add null operations to the binding queue
|
||||
if (bindOperation == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
QueueItem queueItem = new QueueItem()
|
||||
{
|
||||
Key = key,
|
||||
BindOperation = bindOperation,
|
||||
TimeoutOperation = timeoutOperation,
|
||||
ErrorHandler = errorHandler,
|
||||
BindingTimeout = bindingTimeout,
|
||||
WaitForLockTimeout = waitForLockTimeout
|
||||
};
|
||||
|
||||
lock (this.bindingQueueLock)
|
||||
{
|
||||
this.bindingQueue.AddLast(queueItem);
|
||||
}
|
||||
|
||||
this.itemQueuedEvent.Set();
|
||||
|
||||
return queueItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a particular binding context is connected or not
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public bool IsBindingContextConnected(string key)
|
||||
{
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
IBindingContext context;
|
||||
if (this.BindingContextMap.TryGetValue(key, out context))
|
||||
{
|
||||
return context.IsConnected;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates a binding context for the provided context key
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
protected IBindingContext GetOrCreateBindingContext(string key)
|
||||
{
|
||||
// use a default binding context for disconnected requests
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
key = "disconnected_binding_context";
|
||||
}
|
||||
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
if (!this.BindingContextMap.ContainsKey(key))
|
||||
{
|
||||
var bindingContext = new T();
|
||||
this.BindingContextMap.Add(key, bindingContext);
|
||||
this.BindingContextTasks.Add(bindingContext, Task.Run(() => null));
|
||||
}
|
||||
|
||||
return this.BindingContextMap[key];
|
||||
}
|
||||
}
|
||||
|
||||
protected IEnumerable<IBindingContext> GetBindingContexts(string keyPrefix)
|
||||
{
|
||||
// use a default binding context for disconnected requests
|
||||
if (string.IsNullOrWhiteSpace(keyPrefix))
|
||||
{
|
||||
keyPrefix = "disconnected_binding_context";
|
||||
}
|
||||
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
return this.BindingContextMap.Where(x => x.Key.StartsWith(keyPrefix)).Select(v => v.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a binding context already exists for the provided context key
|
||||
/// </summary>
|
||||
protected bool BindingContextExists(string key)
|
||||
{
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
return this.BindingContextMap.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the binding queue entry
|
||||
/// </summary>
|
||||
protected void RemoveBindingContext(string key)
|
||||
{
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
if (this.BindingContextMap.ContainsKey(key))
|
||||
{
|
||||
// disconnect existing connection
|
||||
var bindingContext = this.BindingContextMap[key];
|
||||
if (bindingContext.ServerConnection != null && bindingContext.ServerConnection.IsOpen)
|
||||
{
|
||||
// Disconnecting can take some time so run it in a separate task so that it doesn't block removal
|
||||
Task.Run(() =>
|
||||
{
|
||||
bindingContext.ServerConnection.Cancel();
|
||||
bindingContext.ServerConnection.Disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
// remove key from the map
|
||||
this.BindingContextMap.Remove(key);
|
||||
this.BindingContextTasks.Remove(bindingContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasPendingQueueItems
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this.bindingQueueLock)
|
||||
{
|
||||
return this.bindingQueue.Count > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next pending queue item
|
||||
/// </summary>
|
||||
private QueueItem GetNextQueueItem()
|
||||
{
|
||||
lock (this.bindingQueueLock)
|
||||
{
|
||||
if (this.bindingQueue.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
QueueItem queueItem = this.bindingQueue.First.Value;
|
||||
this.bindingQueue.RemoveFirst();
|
||||
return queueItem;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the queue processing thread
|
||||
/// </summary>
|
||||
private Task StartQueueProcessorAsync()
|
||||
{
|
||||
if (this.processQueueCancelToken != null)
|
||||
{
|
||||
this.processQueueCancelToken.Dispose();
|
||||
}
|
||||
this.processQueueCancelToken = new CancellationTokenSource();
|
||||
|
||||
return Task.Factory.StartNew(
|
||||
ProcessQueue,
|
||||
this.processQueueCancelToken.Token,
|
||||
TaskCreationOptions.LongRunning,
|
||||
TaskScheduler.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The core queue processing method
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
private void ProcessQueue()
|
||||
{
|
||||
CancellationToken token = this.processQueueCancelToken.Token;
|
||||
WaitHandle[] waitHandles = new WaitHandle[2]
|
||||
{
|
||||
this.itemQueuedEvent,
|
||||
token.WaitHandle
|
||||
};
|
||||
|
||||
while (true)
|
||||
{
|
||||
// wait for with an item to be queued or the a cancellation request
|
||||
WaitHandle.WaitAny(waitHandles);
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// dispatch all pending queue items
|
||||
while (this.HasPendingQueueItems)
|
||||
{
|
||||
QueueItem queueItem = GetNextQueueItem();
|
||||
if (queueItem == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IBindingContext bindingContext = GetOrCreateBindingContext(queueItem.Key);
|
||||
if (bindingContext == null)
|
||||
{
|
||||
queueItem.ItemProcessed.Set();
|
||||
continue;
|
||||
}
|
||||
|
||||
var bindingContextTask = this.BindingContextTasks[bindingContext];
|
||||
|
||||
// Run in the binding context task in case this task has to wait for a previous binding operation
|
||||
this.BindingContextTasks[bindingContext] = bindingContextTask.ContinueWith((task) =>
|
||||
{
|
||||
bool lockTaken = false;
|
||||
try
|
||||
{
|
||||
// prefer the queue item binding item, otherwise use the context default timeout
|
||||
int bindTimeout = queueItem.BindingTimeout ?? bindingContext.BindingTimeout;
|
||||
|
||||
// handle the case a previous binding operation is still running
|
||||
if (!bindingContext.BindingLock.WaitOne(queueItem.WaitForLockTimeout ?? 0))
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Write(TraceEventType.Warning, "Binding queue operation timed out waiting for previous operation to finish");
|
||||
queueItem.Result = queueItem.TimeoutOperation != null
|
||||
? queueItem.TimeoutOperation(bindingContext)
|
||||
: null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(TraceEventType.Error, "Exception running binding queue lock timeout handler: " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
queueItem.ItemProcessed.Set();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bindingContext.BindingLock.Reset();
|
||||
|
||||
lockTaken = true;
|
||||
|
||||
// execute the binding operation
|
||||
object result = null;
|
||||
CancellationTokenSource cancelToken = new CancellationTokenSource();
|
||||
|
||||
// run the operation in a separate thread
|
||||
var bindTask = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
result = queueItem.BindOperation(
|
||||
bindingContext,
|
||||
cancelToken.Token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(TraceEventType.Error, "Unexpected exception on the binding queue: " + ex.ToString());
|
||||
if (queueItem.ErrorHandler != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = queueItem.ErrorHandler(ex);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Logger.Write(TraceEventType.Error, "Unexpected exception in binding queue error handler: " + ex2.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (IsExceptionOfType(ex, typeof(SqlException)) || IsExceptionOfType(ex, typeof(SocketException)))
|
||||
{
|
||||
if (this.OnUnhandledException != null)
|
||||
{
|
||||
this.OnUnhandledException(queueItem.Key, ex);
|
||||
}
|
||||
|
||||
RemoveBindingContext(queueItem.Key);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// check if the binding tasks completed within the binding timeout
|
||||
if (bindTask.Wait(bindTimeout))
|
||||
{
|
||||
queueItem.Result = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelToken.Cancel();
|
||||
|
||||
// if the task didn't complete then call the timeout callback
|
||||
if (queueItem.TimeoutOperation != null)
|
||||
{
|
||||
queueItem.Result = queueItem.TimeoutOperation(bindingContext);
|
||||
}
|
||||
|
||||
bindTask.ContinueWithOnFaulted(t => Logger.Write(TraceEventType.Error, "Binding queue threw exception " + t.Exception.ToString()));
|
||||
|
||||
// Give the task a chance to complete before moving on to the next operation
|
||||
bindTask.Wait();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(TraceEventType.Error, "Binding queue task completion threw exception " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
// set item processed to avoid deadlocks
|
||||
if (lockTaken)
|
||||
{
|
||||
bindingContext.BindingLock.Set();
|
||||
}
|
||||
queueItem.ItemProcessed.Set();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// catch and log any exceptions raised in the binding calls
|
||||
// set item processed to avoid deadlocks
|
||||
Logger.Write(TraceEventType.Error, "Binding queue threw exception " + ex.ToString());
|
||||
// set item processed to avoid deadlocks
|
||||
if (lockTaken)
|
||||
{
|
||||
bindingContext.BindingLock.Set();
|
||||
}
|
||||
queueItem.ItemProcessed.Set();
|
||||
}
|
||||
}, TaskContinuationOptions.None);
|
||||
|
||||
// if a queue processing cancellation was requested then exit the loop
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (this.bindingQueueLock)
|
||||
{
|
||||
// verify the binding queue is still empty
|
||||
if (this.bindingQueue.Count == 0)
|
||||
{
|
||||
// reset the item queued event since we've processed all the pending items
|
||||
this.itemQueuedEvent.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear queued items
|
||||
/// </summary>
|
||||
public void ClearQueuedItems()
|
||||
{
|
||||
lock (this.bindingQueueLock)
|
||||
{
|
||||
if (this.bindingQueue.Count > 0)
|
||||
{
|
||||
this.bindingQueue.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.processQueueCancelToken != null)
|
||||
{
|
||||
this.processQueueCancelToken.Dispose();
|
||||
}
|
||||
|
||||
if (itemQueuedEvent != null)
|
||||
{
|
||||
itemQueuedEvent.Dispose();
|
||||
}
|
||||
|
||||
if (this.BindingContextMap != null)
|
||||
{
|
||||
foreach (var item in this.BindingContextMap)
|
||||
{
|
||||
if (item.Value != null && item.Value.ServerConnection != null && item.Value.ServerConnection.SqlConnectionObject != null)
|
||||
{
|
||||
item.Value.ServerConnection.SqlConnectionObject.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsExceptionOfType(Exception ex, Type t)
|
||||
{
|
||||
return ex.GetType() == t || (ex.InnerException != null && ex.InnerException.GetType() == t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
//
|
||||
// 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.Threading;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Common;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||
using Kusto.Data.Net.Client;
|
||||
using Kusto.Data.Common;
|
||||
using Kusto.Data;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for the binding context for connected sessions
|
||||
/// </summary>
|
||||
public class ConnectedBindingContext : IBindingContext
|
||||
{
|
||||
private ParseOptions parseOptions;
|
||||
|
||||
private ManualResetEvent bindingLock;
|
||||
|
||||
private ServerConnection serverConnection;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDataSource DataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Connected binding context constructor
|
||||
/// </summary>
|
||||
public ConnectedBindingContext()
|
||||
{
|
||||
this.bindingLock = new ManualResetEvent(initialState: true);
|
||||
this.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
||||
this.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a flag indicating if the binder is connected
|
||||
/// </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding server connection
|
||||
/// </summary>
|
||||
public ServerConnection ServerConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.serverConnection;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.serverConnection = value;
|
||||
|
||||
// reset the parse options so the get recreated for the current connection
|
||||
this.parseOptions = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata display info provider
|
||||
/// </summary>
|
||||
public MetadataDisplayInfoProvider MetadataDisplayInfoProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SMO metadata provider
|
||||
/// </summary>
|
||||
public SmoMetadataProvider SmoMetadataProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binder
|
||||
/// </summary>
|
||||
public IBinder Binder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the binding lock object
|
||||
/// </summary>
|
||||
public ManualResetEvent BindingLock
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.bindingLock;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding operation timeout in milliseconds
|
||||
/// </summary>
|
||||
public int BindingTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Language Service ServerVersion
|
||||
/// </summary>
|
||||
public ServerVersion ServerVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ServerConnection != null
|
||||
? this.ServerConnection.ServerVersion
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current DataEngineType
|
||||
/// </summary>
|
||||
public DatabaseEngineType DatabaseEngineType
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ServerConnection != null
|
||||
? this.ServerConnection.DatabaseEngineType
|
||||
: DatabaseEngineType.Standalone;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current connections TransactSqlVersion
|
||||
/// </summary>
|
||||
public TransactSqlVersion TransactSqlVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsConnected
|
||||
? GetTransactSqlVersion(this.ServerVersion)
|
||||
: TransactSqlVersion.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current DatabaseCompatibilityLevel
|
||||
/// </summary>
|
||||
public DatabaseCompatibilityLevel DatabaseCompatibilityLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsConnected
|
||||
? GetDatabaseCompatibilityLevel(this.ServerVersion)
|
||||
: DatabaseCompatibilityLevel.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current ParseOptions
|
||||
/// </summary>
|
||||
public ParseOptions ParseOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.parseOptions == null)
|
||||
{
|
||||
this.parseOptions = new ParseOptions(
|
||||
batchSeparator: LanguageService.DefaultBatchSeperator,
|
||||
isQuotedIdentifierSet: true,
|
||||
compatibilityLevel: DatabaseCompatibilityLevel,
|
||||
transactSqlVersion: TransactSqlVersion);
|
||||
}
|
||||
return this.parseOptions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the database compatibility level from a server version
|
||||
/// </summary>
|
||||
/// <param name="serverVersion"></param>
|
||||
private static DatabaseCompatibilityLevel GetDatabaseCompatibilityLevel(ServerVersion serverVersion)
|
||||
{
|
||||
int versionMajor = Math.Max(serverVersion.Major, 8);
|
||||
|
||||
switch (versionMajor)
|
||||
{
|
||||
case 8:
|
||||
return DatabaseCompatibilityLevel.Version80;
|
||||
case 9:
|
||||
return DatabaseCompatibilityLevel.Version90;
|
||||
case 10:
|
||||
return DatabaseCompatibilityLevel.Version100;
|
||||
case 11:
|
||||
return DatabaseCompatibilityLevel.Version110;
|
||||
case 12:
|
||||
return DatabaseCompatibilityLevel.Version120;
|
||||
case 13:
|
||||
return DatabaseCompatibilityLevel.Version130;
|
||||
default:
|
||||
return DatabaseCompatibilityLevel.Current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transaction sql version from a server version
|
||||
/// </summary>
|
||||
/// <param name="serverVersion"></param>
|
||||
private static TransactSqlVersion GetTransactSqlVersion(ServerVersion serverVersion)
|
||||
{
|
||||
int versionMajor = Math.Max(serverVersion.Major, 9);
|
||||
|
||||
switch (versionMajor)
|
||||
{
|
||||
case 9:
|
||||
case 10:
|
||||
// In case of 10.0 we still use Version 10.5 as it is the closest available.
|
||||
return TransactSqlVersion.Version105;
|
||||
case 11:
|
||||
return TransactSqlVersion.Version110;
|
||||
case 12:
|
||||
return TransactSqlVersion.Version120;
|
||||
case 13:
|
||||
return TransactSqlVersion.Version130;
|
||||
default:
|
||||
return TransactSqlVersion.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
//
|
||||
// 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.Data.SqlClient;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection;
|
||||
using Microsoft.Kusto.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.SqlContext;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
public interface IConnectedBindingQueue
|
||||
{
|
||||
void CloseConnections(string serverName, string databaseName, int millisecondsTimeout);
|
||||
void OpenConnections(string serverName, string databaseName, int millisecondsTimeout);
|
||||
string AddConnectionContext(ConnectionInfo connInfo, string featureName = null, bool overwrite = false);
|
||||
void Dispose();
|
||||
QueueItem QueueBindingOperation(
|
||||
string key,
|
||||
Func<IBindingContext, CancellationToken, object> bindOperation,
|
||||
Func<IBindingContext, object> timeoutOperation = null,
|
||||
Func<Exception, object> errorHandler = null,
|
||||
int? bindingTimeout = null,
|
||||
int? waitForLockTimeout = null);
|
||||
}
|
||||
|
||||
public class SqlConnectionOpener
|
||||
{
|
||||
/// <summary>
|
||||
/// Virtual method used to support mocking and testing
|
||||
/// </summary>
|
||||
public virtual ServerConnection OpenServerConnection(ConnectionInfo connInfo, string featureName)
|
||||
{
|
||||
return ConnectionService.OpenServerConnection(connInfo, featureName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ConnectedBindingQueue class for processing online binding requests
|
||||
/// </summary>
|
||||
public class ConnectedBindingQueue : BindingQueue<ConnectedBindingContext>, IConnectedBindingQueue
|
||||
{
|
||||
internal const int DefaultBindingTimeout = 500;
|
||||
|
||||
internal const int DefaultMinimumConnectionTimeout = 30;
|
||||
|
||||
/// <summary>
|
||||
/// flag determing if the connection queue requires online metadata objects
|
||||
/// it's much cheaper to not construct these objects if not needed
|
||||
/// </summary>
|
||||
private bool needsMetadata;
|
||||
private SqlConnectionOpener connectionOpener;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current settings
|
||||
/// </summary>
|
||||
internal SqlToolsSettings CurrentSettings
|
||||
{
|
||||
get { return WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings; }
|
||||
}
|
||||
|
||||
public ConnectedBindingQueue()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
public ConnectedBindingQueue(bool needsMetadata)
|
||||
{
|
||||
this.needsMetadata = needsMetadata;
|
||||
this.connectionOpener = new SqlConnectionOpener();
|
||||
}
|
||||
|
||||
// For testing purposes only
|
||||
internal void SetConnectionOpener(SqlConnectionOpener opener)
|
||||
{
|
||||
this.connectionOpener = opener;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a unique key based on the ConnectionInfo object
|
||||
/// </summary>
|
||||
/// <param name="connInfo"></param>
|
||||
internal static string GetConnectionContextKey(ConnectionDetails details)
|
||||
{
|
||||
string key = string.Format("{0}_{1}_{2}_{3}",
|
||||
details.ServerName ?? "NULL",
|
||||
details.DatabaseName ?? "NULL",
|
||||
details.UserName ?? "NULL",
|
||||
details.AuthenticationType ?? "NULL"
|
||||
);
|
||||
|
||||
if (!string.IsNullOrEmpty(details.DatabaseDisplayName))
|
||||
{
|
||||
key += "_" + details.DatabaseDisplayName;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(details.GroupId))
|
||||
{
|
||||
key += "_" + details.GroupId;
|
||||
}
|
||||
|
||||
return Uri.EscapeUriString(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a unique key based on the ConnectionInfo object
|
||||
/// </summary>
|
||||
/// <param name="connInfo"></param>
|
||||
private string GetConnectionContextKey(string serverName, string databaseName)
|
||||
{
|
||||
return string.Format("{0}_{1}",
|
||||
serverName ?? "NULL",
|
||||
databaseName ?? "NULL");
|
||||
|
||||
}
|
||||
|
||||
public void CloseConnections(string serverName, string databaseName, int millisecondsTimeout)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(serverName, databaseName);
|
||||
var contexts = GetBindingContexts(connectionKey);
|
||||
foreach (var bindingContext in contexts)
|
||||
{
|
||||
if (bindingContext.BindingLock.WaitOne(millisecondsTimeout))
|
||||
{
|
||||
bindingContext.ServerConnection.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenConnections(string serverName, string databaseName, int millisecondsTimeout)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(serverName, databaseName);
|
||||
var contexts = GetBindingContexts(connectionKey);
|
||||
foreach (var bindingContext in contexts)
|
||||
{
|
||||
if (bindingContext.BindingLock.WaitOne(millisecondsTimeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
bindingContext.ServerConnection.Connect();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//TODO: remove the binding context?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveBindigContext(ConnectionInfo connInfo)
|
||||
{
|
||||
string connectionKey = GetConnectionContextKey(connInfo.ConnectionDetails);
|
||||
if (BindingContextExists(connectionKey))
|
||||
{
|
||||
RemoveBindingContext(connectionKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use a ConnectionInfo item to create a connected binding context
|
||||
/// </summary>
|
||||
/// <param name="connInfo">Connection info used to create binding context</param>
|
||||
/// <param name="overwrite">Overwrite existing context</param>
|
||||
public virtual string AddConnectionContext(ConnectionInfo connInfo, string featureName = null, bool overwrite = false)
|
||||
{
|
||||
if (connInfo == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// lookup the current binding contextna
|
||||
string connectionKey = GetConnectionContextKey(connInfo.ConnectionDetails);
|
||||
if (BindingContextExists(connectionKey))
|
||||
{
|
||||
if (overwrite)
|
||||
{
|
||||
RemoveBindingContext(connectionKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no need to populate the context again since the context already exists
|
||||
return connectionKey;
|
||||
}
|
||||
}
|
||||
IBindingContext bindingContext = this.GetOrCreateBindingContext(connectionKey);
|
||||
|
||||
if (bindingContext.BindingLock.WaitOne())
|
||||
{
|
||||
try
|
||||
{
|
||||
bindingContext.BindingLock.Reset();
|
||||
|
||||
// populate the binding context to work with the SMO metadata provider
|
||||
bindingContext.ServerConnection = connectionOpener.OpenServerConnection(connInfo, featureName);
|
||||
|
||||
string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
|
||||
bindingContext.DataSource = DataSourceFactory.Create(DataSourceType.Kusto, connectionString, connInfo.ConnectionDetails.AzureAccountToken);
|
||||
|
||||
if (this.needsMetadata)
|
||||
{
|
||||
bindingContext.SmoMetadataProvider = SmoMetadataProvider.CreateConnectedProvider(bindingContext.ServerConnection);
|
||||
bindingContext.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
||||
bindingContext.MetadataDisplayInfoProvider.BuiltInCasing =
|
||||
this.CurrentSettings.SqlTools.IntelliSense.LowerCaseSuggestions.Value
|
||||
? CasingStyle.Lowercase : CasingStyle.Uppercase;
|
||||
bindingContext.Binder = BinderProvider.CreateBinder(bindingContext.SmoMetadataProvider);
|
||||
}
|
||||
|
||||
bindingContext.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
||||
bindingContext.IsConnected = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
bindingContext.IsConnected = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
bindingContext.BindingLock.Set();
|
||||
}
|
||||
}
|
||||
|
||||
return connectionKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class CompletionRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<TextDocumentPosition, CompletionItem[]> Type =
|
||||
RequestType<TextDocumentPosition, CompletionItem[]>.Create("textDocument/completion");
|
||||
}
|
||||
|
||||
public class CompletionResolveRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<CompletionItem, CompletionItem> Type =
|
||||
RequestType<CompletionItem, CompletionItem>.Create("completionItem/resolve");
|
||||
}
|
||||
|
||||
public enum CompletionItemKind
|
||||
{
|
||||
Text = 1,
|
||||
Method = 2,
|
||||
Function = 3,
|
||||
Constructor = 4,
|
||||
Field = 5,
|
||||
Variable = 6,
|
||||
Class = 7,
|
||||
Interface = 8,
|
||||
Module = 9,
|
||||
Property = 10,
|
||||
Unit = 11,
|
||||
Value = 12,
|
||||
Enum = 13,
|
||||
Keyword = 14,
|
||||
Snippet = 15,
|
||||
Color = 16,
|
||||
File = 17,
|
||||
Reference = 18
|
||||
}
|
||||
|
||||
public class Command
|
||||
{
|
||||
/// <summary>
|
||||
/// Title of the command.
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The identifier of the actual command handler, like `vsintellicode.completionItemSelected`.
|
||||
/// </summary>
|
||||
public string command { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A tooltip for the command, when represented in the UI.
|
||||
/// </summary>
|
||||
public string Tooltip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Arguments that the command handler should be invoked with.
|
||||
/// </summary>
|
||||
public object[] Arguments { get; set; }
|
||||
}
|
||||
|
||||
[DebuggerDisplay("Kind = {Kind.ToString()}, Label = {Label}, Detail = {Detail}")]
|
||||
public class CompletionItem
|
||||
{
|
||||
public string Label { get; set; }
|
||||
|
||||
public CompletionItemKind? Kind { get; set; }
|
||||
|
||||
public string Detail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the documentation string for the completion item.
|
||||
/// </summary>
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public string SortText { get; set; }
|
||||
|
||||
public string FilterText { get; set; }
|
||||
|
||||
public string InsertText { get; set; }
|
||||
|
||||
public TextEdit TextEdit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a custom data field that allows the server to mark
|
||||
/// each completion item with an identifier that will help correlate
|
||||
/// the item to the previous completion request during a completion
|
||||
/// resolve request.
|
||||
/// </summary>
|
||||
public object Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exposing a command field for a completion item for passing telemetry
|
||||
/// </summary>
|
||||
public Command Command { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this completion item is preselected or not
|
||||
/// </summary>
|
||||
public bool? Preselect { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class DefinitionRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<TextDocumentPosition, Location[]> Type =
|
||||
RequestType<TextDocumentPosition, Location[]>.Create("textDocument/definition");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class PublishDiagnosticsNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<PublishDiagnosticsNotification> Type =
|
||||
EventType<PublishDiagnosticsNotification>.Create("textDocument/publishDiagnostics");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI for which diagnostic information is reported.
|
||||
/// </summary>
|
||||
public string Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the array of diagnostic information items.
|
||||
/// </summary>
|
||||
public Diagnostic[] Diagnostics { get; set; }
|
||||
}
|
||||
|
||||
public enum DiagnosticSeverity
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the diagnostic represents an error.
|
||||
/// </summary>
|
||||
Error = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the diagnostic represents a warning.
|
||||
/// </summary>
|
||||
Warning = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the diagnostic represents an informational message.
|
||||
/// </summary>
|
||||
Information = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the diagnostic represents a hint.
|
||||
/// </summary>
|
||||
Hint = 4
|
||||
}
|
||||
|
||||
public class Diagnostic
|
||||
{
|
||||
public Range Range { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the severity of the diagnostic. If omitted, the
|
||||
/// client should interpret the severity.
|
||||
/// </summary>
|
||||
public DiagnosticSeverity? Severity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the diagnostic's code (optional).
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the diagnostic message.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public enum DocumentHighlightKind
|
||||
{
|
||||
Text = 1,
|
||||
Read = 2,
|
||||
Write = 3
|
||||
}
|
||||
|
||||
public class DocumentHighlight
|
||||
{
|
||||
public Range Range { get; set; }
|
||||
|
||||
public DocumentHighlightKind Kind { get; set; }
|
||||
}
|
||||
|
||||
public class DocumentHighlightRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<TextDocumentPosition, DocumentHighlight[]> Type =
|
||||
RequestType<TextDocumentPosition, DocumentHighlight[]>.Create("textDocument/documentHighlight");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class ExpandAliasRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<string, string> Type =
|
||||
RequestType<string, string>.Create("SqlTools/expandAlias");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class FindModuleRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<List<PSModuleMessage>, object> Type =
|
||||
RequestType<List<PSModuleMessage>, object>.Create("SqlTools/findModule");
|
||||
}
|
||||
|
||||
|
||||
public class PSModuleMessage
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class MarkedString
|
||||
{
|
||||
public string Language { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
public class Hover
|
||||
{
|
||||
public MarkedString[] Contents { get; set; }
|
||||
|
||||
public Range? Range { get; set; }
|
||||
}
|
||||
|
||||
public class HoverRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<TextDocumentPosition, Hover> Type =
|
||||
RequestType<TextDocumentPosition, Hover>.Create("textDocument/hover");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
class InstallModuleRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<string, object> Type =
|
||||
RequestType<string, object>.Create("SqlTools/installModule");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters sent back with an IntelliSense ready event
|
||||
/// </summary>
|
||||
public class IntelliSenseReadyParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI identifying the text document
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event sent when the language service is finished updating after a connection
|
||||
/// </summary>
|
||||
public class IntelliSenseReadyNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<IntelliSenseReadyParams> Type =
|
||||
EventType<IntelliSenseReadyParams>.Create("textDocument/intelliSenseReady");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters to be sent back with a rebuild IntelliSense event
|
||||
/// </summary>
|
||||
public class RebuildIntelliSenseParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI identifying the file that should have its IntelliSense cache rebuilt
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RebuildIntelliSenseNotification notification mapping entry
|
||||
/// </summary>
|
||||
public class RebuildIntelliSenseNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<RebuildIntelliSenseParams> Type =
|
||||
EventType<RebuildIntelliSenseParams>.Create("textDocument/rebuildIntelliSense");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class ReferencesRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<ReferencesParams, Location[]> Type =
|
||||
RequestType<ReferencesParams, Location[]>.Create("textDocument/references");
|
||||
}
|
||||
|
||||
public class ReferencesParams : TextDocumentPosition
|
||||
{
|
||||
public ReferencesContext Context { get; set; }
|
||||
}
|
||||
|
||||
public class ReferencesContext
|
||||
{
|
||||
public bool IncludeDeclaration { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class ShowOnlineHelpRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<string, object> Type =
|
||||
RequestType<string, object>.Create("SqlTools/showOnlineHelp");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class SignatureHelpRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<TextDocumentPosition, SignatureHelp> Type =
|
||||
RequestType<TextDocumentPosition, SignatureHelp>.Create("textDocument/signatureHelp");
|
||||
}
|
||||
|
||||
public class ParameterInformation
|
||||
{
|
||||
public string Label { get; set; }
|
||||
|
||||
public string Documentation { get; set; }
|
||||
}
|
||||
|
||||
public class SignatureInformation
|
||||
{
|
||||
public string Label { get; set; }
|
||||
|
||||
public string Documentation { get; set; }
|
||||
|
||||
public ParameterInformation[] Parameters { get; set; }
|
||||
}
|
||||
|
||||
public class SignatureHelp
|
||||
{
|
||||
public SignatureInformation[] Signatures { get; set; }
|
||||
|
||||
public int? ActiveSignature { get; set; }
|
||||
|
||||
public int? ActiveParameter { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters sent back with an status change event
|
||||
/// </summary>
|
||||
public class StatusChangeParams
|
||||
{
|
||||
/// <summary>
|
||||
/// URI identifying the text document
|
||||
/// </summary>
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The new status for the document
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event sent for language service status change notification
|
||||
/// </summary>
|
||||
public class StatusChangedNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<StatusChangeParams> Type =
|
||||
EventType<StatusChangeParams>.Create("textDocument/statusChanged");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class SyntaxParseParams
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
public string Query { get; set; }
|
||||
}
|
||||
|
||||
public class SyntaxParseResult
|
||||
{
|
||||
public bool Parseable { get; set; }
|
||||
|
||||
public string[] Errors { get; set; }
|
||||
}
|
||||
|
||||
public class SyntaxParseRequest
|
||||
{
|
||||
public static readonly
|
||||
RequestType<SyntaxParseParams, SyntaxParseResult> Type =
|
||||
RequestType<SyntaxParseParams, SyntaxParseResult>.Create("query/syntaxparse");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
public class TelemetryProperties
|
||||
{
|
||||
public string EventName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Telemetry properties
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Telemetry measures
|
||||
/// </summary>
|
||||
public Dictionary<string, double> Measures { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameters sent back with an IntelliSense ready event
|
||||
/// </summary>
|
||||
public class TelemetryParams
|
||||
{
|
||||
public TelemetryProperties Params { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event sent when the language service needs to add a telemetry event
|
||||
/// </summary>
|
||||
public class TelemetryNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<TelemetryParams> Type =
|
||||
EventType<TelemetryParams>.Create("telemetry/sqlevent");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of telemetry events
|
||||
/// </summary>
|
||||
public static class TelemetryEventNames
|
||||
{
|
||||
/// <summary>
|
||||
/// telemetry event name for auto complete response time
|
||||
/// </summary>
|
||||
public const string IntellisenseQuantile = "IntellisenseQuantile";
|
||||
|
||||
/// <summary>
|
||||
/// telemetry event name for when definition is requested
|
||||
/// </summary>
|
||||
public const string PeekDefinitionRequested = "PeekDefinitionRequested";
|
||||
|
||||
/// <summary>
|
||||
/// telemetry event name for when definition is requested
|
||||
/// </summary>
|
||||
public const string FormatCode = "FormatCode";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of properties used in telemetry events
|
||||
/// </summary>
|
||||
public static class TelemetryPropertyNames
|
||||
{
|
||||
/// <summary>
|
||||
/// Is a connection to an Azure database or not
|
||||
/// </summary>
|
||||
public const string IsAzure = "IsAzure";
|
||||
|
||||
/// <summary>
|
||||
/// Did an event succeed or not
|
||||
/// </summary>
|
||||
public const string Succeeded = "Succeeded";
|
||||
|
||||
/// <summary>
|
||||
/// Was the action against a connected file or similar resource, or not
|
||||
/// </summary>
|
||||
public const string Connected = "Connected";
|
||||
|
||||
/// <summary>
|
||||
/// Format type property - should be one of <see cref="DocumentFormatType"/> or <see cref="RangeFormatType"/>
|
||||
/// </summary>
|
||||
public const string FormatType = "FormatType";
|
||||
|
||||
/// <summary>
|
||||
/// A full document format
|
||||
/// </summary>
|
||||
public const string DocumentFormatType = "Document";
|
||||
|
||||
/// <summary>
|
||||
/// A document range format
|
||||
/// </summary>
|
||||
public const string RangeFormatType = "Range";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts
|
||||
{
|
||||
|
||||
[DebuggerDisplay("NewText = {NewText}, Range = {Range.Start.Line}:{Range.Start.Character} - {Range.End.Line}:{Range.End.Character}")]
|
||||
public class TextEdit
|
||||
{
|
||||
public Range Range { get; set; }
|
||||
|
||||
public string NewText { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// 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.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Range = Microsoft.Kusto.ServiceLayer.Workspace.Contracts.Range;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Main class for Language Service functionality including anything that reqires knowledge of
|
||||
/// the language to perfom, such as definitions, intellisense, etc.
|
||||
/// </summary>
|
||||
public static class DiagnosticsHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Send the diagnostic results back to the host application
|
||||
/// </summary>
|
||||
/// <param name="scriptFile"></param>
|
||||
/// <param name="semanticMarkers"></param>
|
||||
/// <param name="eventContext"></param>
|
||||
internal static async Task PublishScriptDiagnostics(
|
||||
ScriptFile scriptFile,
|
||||
ScriptFileMarker[] semanticMarkers,
|
||||
EventContext eventContext)
|
||||
{
|
||||
var allMarkers = scriptFile.SyntaxMarkers != null
|
||||
? scriptFile.SyntaxMarkers.Concat(semanticMarkers)
|
||||
: semanticMarkers;
|
||||
|
||||
// Always send syntax and semantic errors. We want to
|
||||
// make sure no out-of-date markers are being displayed.
|
||||
await eventContext.SendEvent(
|
||||
PublishDiagnosticsNotification.Type,
|
||||
new PublishDiagnosticsNotification
|
||||
{
|
||||
Uri = scriptFile.ClientUri,
|
||||
Diagnostics =
|
||||
allMarkers
|
||||
.Select(GetDiagnosticFromMarker)
|
||||
.ToArray()
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send the diagnostic results back to the host application
|
||||
/// </summary>
|
||||
/// <param name="scriptFile"></param>
|
||||
/// <param name="semanticMarkers"></param>
|
||||
/// <param name="eventContext"></param>
|
||||
internal static async Task ClearScriptDiagnostics(
|
||||
string uri,
|
||||
EventContext eventContext)
|
||||
{
|
||||
Validate.IsNotNullOrEmptyString(nameof(uri), uri);
|
||||
Validate.IsNotNull(nameof(eventContext), eventContext);
|
||||
// Always send syntax and semantic errors. We want to
|
||||
// make sure no out-of-date markers are being displayed.
|
||||
await eventContext.SendEvent(
|
||||
PublishDiagnosticsNotification.Type,
|
||||
new PublishDiagnosticsNotification
|
||||
{
|
||||
Uri = uri,
|
||||
Diagnostics = Array.Empty<Diagnostic>()
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a ScriptFileMarker to a Diagnostic that is Language Service compatible
|
||||
/// </summary>
|
||||
/// <param name="scriptFileMarker"></param>
|
||||
/// <returns></returns>
|
||||
internal static Diagnostic GetDiagnosticFromMarker(ScriptFileMarker scriptFileMarker)
|
||||
{
|
||||
return new Diagnostic
|
||||
{
|
||||
Severity = MapDiagnosticSeverity(scriptFileMarker.Level),
|
||||
Message = scriptFileMarker.Message,
|
||||
Range = new Range
|
||||
{
|
||||
Start = new Position
|
||||
{
|
||||
Line = scriptFileMarker.ScriptRegion.StartLineNumber - 1,
|
||||
Character = scriptFileMarker.ScriptRegion.StartColumnNumber - 1
|
||||
},
|
||||
End = new Position
|
||||
{
|
||||
Line = scriptFileMarker.ScriptRegion.EndLineNumber - 1,
|
||||
Character = scriptFileMarker.ScriptRegion.EndColumnNumber - 1
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map ScriptFileMarker severity to Diagnostic severity
|
||||
/// </summary>
|
||||
/// <param name="markerLevel"></param>
|
||||
internal static DiagnosticSeverity MapDiagnosticSeverity(ScriptFileMarkerLevel markerLevel)
|
||||
{
|
||||
switch (markerLevel)
|
||||
{
|
||||
case ScriptFileMarkerLevel.Error:
|
||||
return DiagnosticSeverity.Error;
|
||||
|
||||
case ScriptFileMarkerLevel.Warning:
|
||||
return DiagnosticSeverity.Warning;
|
||||
|
||||
case ScriptFileMarkerLevel.Information:
|
||||
return DiagnosticSeverity.Information;
|
||||
|
||||
default:
|
||||
return DiagnosticSeverity.Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.Kusto.ServiceLayer.LanguageServices.Contracts;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to send events to the client
|
||||
/// </summary>
|
||||
public class DocumentStatusHelper
|
||||
{
|
||||
public const string DefinitionRequested = "DefinitionRequested";
|
||||
public const string DefinitionRequestCompleted = "DefinitionRequestCompleted";
|
||||
|
||||
/// <summary>
|
||||
/// Sends an event for specific document using the existing request context
|
||||
/// </summary>
|
||||
public static void SendStatusChange<T>(RequestContext<T> requestContext, TextDocumentPosition textDocumentPosition, string status)
|
||||
{
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
if (requestContext != null)
|
||||
{
|
||||
string ownerUri = textDocumentPosition != null && textDocumentPosition.TextDocument != null ? textDocumentPosition.TextDocument.Uri : "";
|
||||
await requestContext.SendEvent(StatusChangedNotification.Type, new StatusChangeParams()
|
||||
{
|
||||
OwnerUri = ownerUri,
|
||||
Status = status
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a telemetry event for specific document using the existing request context
|
||||
/// </summary>
|
||||
public static void SendTelemetryEvent<T>(RequestContext<T> requestContext, string telemetryEvent)
|
||||
{
|
||||
Validate.IsNotNull(nameof(requestContext), requestContext);
|
||||
Validate.IsNotNullOrWhitespaceString(nameof(telemetryEvent), telemetryEvent);
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
|
||||
{
|
||||
Params = new TelemetryProperties
|
||||
{
|
||||
EventName = telemetryEvent
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a telemetry event for specific document using the existing request context
|
||||
/// </summary>
|
||||
public static void SendTelemetryEvent<T>(RequestContext<T> requestContext, TelemetryProperties telemetryProps)
|
||||
{
|
||||
Validate.IsNotNull(nameof(requestContext), requestContext);
|
||||
Validate.IsNotNull(nameof(telemetryProps), telemetryProps);
|
||||
Validate.IsNotNullOrWhitespaceString("telemetryProps.EventName", telemetryProps.EventName);
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
|
||||
{
|
||||
Params = telemetryProps
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Threading;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Common;
|
||||
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
|
||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource;
|
||||
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// The context used for binding requests
|
||||
/// </summary>
|
||||
public interface IBindingContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a flag indicating if the context is connected
|
||||
/// </summary>
|
||||
bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding server connection
|
||||
/// </summary>
|
||||
ServerConnection ServerConnection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets data source interface
|
||||
/// </summary>
|
||||
IDataSource DataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata display info provider
|
||||
/// </summary>
|
||||
MetadataDisplayInfoProvider MetadataDisplayInfoProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SMO metadata provider
|
||||
/// </summary>
|
||||
SmoMetadataProvider SmoMetadataProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binder
|
||||
/// </summary>
|
||||
IBinder Binder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the binding lock object
|
||||
/// </summary>
|
||||
ManualResetEvent BindingLock { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding operation timeout in milliseconds
|
||||
/// </summary>
|
||||
int BindingTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current connection parse options
|
||||
/// </summary>
|
||||
ParseOptions ParseOptions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current connection server version
|
||||
/// </summary>
|
||||
ServerVersion ServerVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database engine type
|
||||
/// </summary>
|
||||
DatabaseEngineType DatabaseEngineType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the T-SQL version
|
||||
/// </summary>
|
||||
TransactSqlVersion TransactSqlVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database compatibility level
|
||||
/// </summary>
|
||||
DatabaseCompatibilityLevel DatabaseCompatibilityLevel { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to calculate the value for the metrics using the given bucket
|
||||
/// </summary>
|
||||
public class InteractionMetrics<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates new instance given a bucket of metrics
|
||||
/// </summary>
|
||||
public InteractionMetrics(int[] metrics)
|
||||
{
|
||||
Validate.IsNotNull("metrics", metrics);
|
||||
if(metrics.Length == 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("metrics");
|
||||
}
|
||||
|
||||
Counters = new ConcurrentDictionary<string, T>();
|
||||
if (!IsSorted(metrics))
|
||||
{
|
||||
Array.Sort(metrics);
|
||||
}
|
||||
Metrics = metrics;
|
||||
}
|
||||
|
||||
private ConcurrentDictionary<string, T> Counters { get; }
|
||||
|
||||
private object perfCountersLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// The metrics bucket
|
||||
/// </summary>
|
||||
public int[] Metrics { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the given list is sorted
|
||||
/// </summary>
|
||||
private bool IsSorted(int[] metrics)
|
||||
{
|
||||
if (metrics.Length > 1)
|
||||
{
|
||||
int previous = metrics[0];
|
||||
for (int i = 1; i < metrics.Length; i++)
|
||||
{
|
||||
if(metrics[i] < previous)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
previous = metrics[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update metric value given new number
|
||||
/// </summary>
|
||||
public void UpdateMetrics(double duration, T newValue, Func<string, T, T> updateValueFactory)
|
||||
{
|
||||
int metric = Metrics[Metrics.Length - 1];
|
||||
for (int i = 0; i < Metrics.Length; i++)
|
||||
{
|
||||
if (duration <= Metrics[i])
|
||||
{
|
||||
metric = Metrics[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
string key = metric.ToString();
|
||||
Counters.AddOrUpdate(key, newValue, updateValueFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the quantile
|
||||
/// </summary>
|
||||
public Dictionary<string, T> Quantile
|
||||
{
|
||||
get
|
||||
{
|
||||
return Counters.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1200
src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs
Normal file
1200
src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// /// Result object for PeekDefinition
|
||||
/// </summary>
|
||||
public class DefinitionResult
|
||||
{
|
||||
/// <summary>
|
||||
/// True, if definition error occured
|
||||
/// </summary>
|
||||
public bool IsErrorResult;
|
||||
|
||||
/// <summary>
|
||||
/// Error message, if any
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Location object representing the definition script file
|
||||
/// </summary>
|
||||
public Location[] Locations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// 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.Threading;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that stores the state of a binding queue request item
|
||||
/// </summary>
|
||||
public class QueueItem
|
||||
{
|
||||
/// <summary>
|
||||
/// QueueItem constructor
|
||||
/// </summary>
|
||||
public QueueItem()
|
||||
{
|
||||
this.ItemProcessed = new ManualResetEvent(initialState: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the queue item key
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bind operation callback method
|
||||
/// </summary>
|
||||
public Func<IBindingContext, CancellationToken, object> BindOperation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timeout operation to call if the bind operation doesn't finish within timeout period
|
||||
/// </summary>
|
||||
public Func<IBindingContext, object> TimeoutOperation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the operation to call if the bind operation encounters an unexpected exception.
|
||||
/// Supports returning an object in case of the exception occurring since in some cases we need to be
|
||||
/// tolerant of error cases and still return some value
|
||||
/// </summary>
|
||||
public Func<Exception, object> ErrorHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an event to signal when this queue item has been processed
|
||||
/// </summary>
|
||||
public virtual ManualResetEvent ItemProcessed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the result of the queued task
|
||||
/// </summary>
|
||||
public object Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding operation timeout in milliseconds
|
||||
/// </summary>
|
||||
public int? BindingTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timeout for how long to wait for the binding lock
|
||||
/// </summary>
|
||||
public int? WaitForLockTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts the result of the execution to type T
|
||||
/// </summary>
|
||||
public T GetResultAsT<T>() where T : class
|
||||
{
|
||||
//var task = this.ResultsTask;
|
||||
return (this.Result != null)
|
||||
? this.Result as T
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Microsoft.Kusto.ServiceLayer.DataSource.DataSourceIntellisense;
|
||||
using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.Kusto.ServiceLayer.LanguageServices.Completion
|
||||
{
|
||||
/// <summary>
|
||||
/// A class to calculate the numbers used by SQL parser using the text positions and content
|
||||
/// </summary>
|
||||
public class ScriptDocumentInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Create new instance
|
||||
/// </summary>
|
||||
public ScriptDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ScriptParseInfo scriptParseInfo)
|
||||
: this(textDocumentPosition, scriptFile)
|
||||
{
|
||||
Validate.IsNotNull(nameof(scriptParseInfo), scriptParseInfo);
|
||||
|
||||
ScriptParseInfo = scriptParseInfo;
|
||||
}
|
||||
|
||||
private ScriptDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile)
|
||||
{
|
||||
StartLine = textDocumentPosition.Position.Line;
|
||||
ParserLine = textDocumentPosition.Position.Line + 1;
|
||||
StartColumn = TextUtilities.PositionOfPrevDelimeter(
|
||||
scriptFile.Contents,
|
||||
textDocumentPosition.Position.Line,
|
||||
textDocumentPosition.Position.Character);
|
||||
EndColumn = TextUtilities.PositionOfNextDelimeter(
|
||||
scriptFile.Contents,
|
||||
textDocumentPosition.Position.Line,
|
||||
textDocumentPosition.Position.Character);
|
||||
ParserColumn = textDocumentPosition.Position.Character + 1;
|
||||
Contents = scriptFile.Contents;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ScriptDocumentInfo"/> with no backing <see cref="ScriptParseInfo"/> defined
|
||||
/// </summary>
|
||||
/// <param name="textDocumentPosition">A <see cref="TextDocumentPosition"/></param>
|
||||
/// <param name="scriptFile">A <see cref="ScriptFile"/> to process</param>
|
||||
/// <returns></returns>
|
||||
public static ScriptDocumentInfo CreateDefaultDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile)
|
||||
{
|
||||
return new ScriptDocumentInfo(textDocumentPosition, scriptFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string containing the full contents of the file.
|
||||
/// </summary>
|
||||
public string Contents { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Script Parse Info Instance
|
||||
/// </summary>
|
||||
public ScriptParseInfo ScriptParseInfo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start Line
|
||||
/// </summary>
|
||||
public int StartLine { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parser Line
|
||||
/// </summary>
|
||||
public int ParserLine { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start Column
|
||||
/// </summary>
|
||||
public int StartColumn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// end Column
|
||||
/// </summary>
|
||||
public int EndColumn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parser Column
|
||||
/// </summary>
|
||||
public int ParserColumn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The token text in the file content used for completion list
|
||||
/// </summary>
|
||||
public virtual string TokenText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Token != null ? Token.Text : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The token in the file content used for completion list
|
||||
/// </summary>
|
||||
public Token Token { get; private set; }
|
||||
}
|
||||
}
|
||||
4365
src/Microsoft.Kusto.ServiceLayer/Localization/sr.cs
Normal file
4365
src/Microsoft.Kusto.ServiceLayer/Localization/sr.cs
Normal file
File diff suppressed because it is too large
Load Diff
490
src/Microsoft.Kusto.ServiceLayer/Localization/sr.de.resx
Normal file
490
src/Microsoft.Kusto.ServiceLayer/Localization/sr.de.resx
Normal file
@@ -0,0 +1,490 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader><resheader name="version"><value>1.3</value></resheader><resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><data name="ConnectionServiceConnectErrorNullParams"><value>Verbindungsparameter dürfen nicht null sein.</value></data>
|
||||
<data name="ConnectionServiceListDbErrorNullOwnerUri"><value>OwnerUri darf nicht null oder leer sein.</value></data>
|
||||
<data name="ConnectionServiceListDbErrorNotConnected"><value>SpecifiedUri '{0}' hat keine gültige Verbindung</value></data>
|
||||
<data name="ConnectionServiceConnStringInvalidAuthType"><value>Ungültiger Wert '{0}' für AuthenticationType. Gültige Werte sind 'Integrated' und 'SqlLogin'.</value></data>
|
||||
<data name="ConnectionServiceConnStringInvalidIntent"><value>Ungültiger Wert '{0}' für ApplicationIntent. Gültige Werte sind 'ReadWrite' und 'ReadOnly'.</value></data>
|
||||
<data name="ConnectionServiceConnectionCanceled"><value>Verbindung wurde abgebrochen.</value></data>
|
||||
<data name="ConnectionParamsValidateNullOwnerUri"><value>OwnerUri darf nicht null oder leer sein.</value></data>
|
||||
<data name="ConnectionParamsValidateNullConnection"><value>Verbindungsdetails-Objekt darf nicht null sein.</value></data>
|
||||
<data name="ConnectionParamsValidateNullServerName"><value>ServerName darf nicht null oder leer sein.</value></data>
|
||||
<data name="ConnectionParamsValidateNullSqlAuth"><value>{0} darf bei Verwendung der SqlLogin-Authentifizierung nicht null oder leer sein</value></data>
|
||||
<data name="QueryServiceCancelAlreadyCompleted"><value>Die Abfrage wurde bereits abgeschlossen und kann nicht abgebrochen werden</value></data>
|
||||
<data name="QueryServiceCancelDisposeFailed"><value>Abfrage wurde erfolgreich abgebrochen, Fehler beim Abfrage verfügen. Benutzer-URI nicht gefunden.</value></data>
|
||||
<data name="QueryServiceQueryCancelled"><value>Die Abfrage wurde vom Benutzer abgebrochen.</value></data>
|
||||
<data name="QueryServiceSubsetBatchNotCompleted"><value>Die Stapelverarbeitung ist noch nicht abgeschlossen</value></data>
|
||||
<data name="QueryServiceSubsetBatchOutOfRange"><value>Batch-Index darf nicht kleiner als 0 oder größer als die Anzahl der Batches sein.</value></data>
|
||||
<data name="QueryServiceSubsetResultSetOutOfRange"><value>Der Index der Ergebnismenge darf nicht kleiner als 0 oder größer als die Anzahl der Ergebnismengen sein</value></data>
|
||||
<data name="QueryServiceDataReaderByteCountInvalid"><value>Die maximale Anzahl an Bytes die zurückgeben wird, muss größer als 0 sein.</value></data>
|
||||
<data name="QueryServiceDataReaderCharCountInvalid"><value>Die maximale Anzahl an Zeichen die zurückgeben werden, muss größer als 0 sein.</value></data>
|
||||
<data name="QueryServiceDataReaderXmlCountInvalid"><value>Die maximale Anzahl an XML Bytes die zurückgeben wird, muss größer als 0 sein.</value></data>
|
||||
<data name="QueryServiceFileWrapperWriteOnly"><value>Die Zugriffsmethode kann nicht write-only sein.</value></data>
|
||||
<data name="QueryServiceFileWrapperNotInitialized"><value>FileStreamWrapper muss initialisiert werden, bevor Operationen ausführt werden können</value></data>
|
||||
<data name="QueryServiceFileWrapperReadOnly"><value>Diese FileStreamWrapper kann nicht zum Schreiben verwendet werden</value></data>
|
||||
<data name="QueryServiceAffectedOneRow"><value>(1 Zeile betroffen)</value></data>
|
||||
<data name="QueryServiceAffectedRows"><value>({0} Zeilen betroffen)</value></data>
|
||||
<data name="QueryServiceCompletedSuccessfully"><value>Die Befehle wurden erfolgreich ausgeführt.</value></data>
|
||||
<data name="QueryServiceErrorFormat"><value>Zeile MSG {0} auf {1} Status {2}, {3} {4} {5}</value></data>
|
||||
<data name="QueryServiceQueryFailed"><value>Fehler bei Abfrage: {0}</value></data>
|
||||
<data name="QueryServiceColumnNull"><value>(Kein Spaltenname)</value></data>
|
||||
<data name="QueryServiceRequestsNoQuery"><value>Die angeforderte Abfrage ist nicht vorhanden.</value></data>
|
||||
<data name="QueryServiceQueryInvalidOwnerUri"><value>Dieser Editor ist nicht mit einer Datenbank verbunden.</value></data>
|
||||
<data name="QueryServiceQueryInProgress"><value>Eine Abfrage wird für diese Sitzung bereits ausgeführt. Brechen Sie diese Abfrage ab, oder warten Sie auf Beendigung.</value></data>
|
||||
<data name="QueryServiceMessageSenderNotSql"><value>Das sender Objekt für OnInfoMessage muss vom Typ SqlConnection sein</value></data>
|
||||
<data name="QueryServiceSaveAsResultSetNotComplete"><value>Das Ergebnis kann nicht gespeichert werden, solange die Abfrageausführung nicht abgeschlossen ist.</value></data>
|
||||
<data name="QueryServiceSaveAsMiscStartingError"><value>Beim Speichern ist ein interner Fehler aufgetreten</value></data>
|
||||
<data name="QueryServiceSaveAsInProgress"><value>Eine Speicheranforderung mit demselben Pfad wird bereits ausgeführt.</value></data>
|
||||
<data name="QueryServiceSaveAsFail"><value>Fehler beim Speichern von {0}: {1}</value></data>
|
||||
<data name="QueryServiceResultSetNotRead"><value>Der Teil kann nicht gelesen werden solange die Ergebnisse nicht vom Server gelesen wurden</value></data>
|
||||
<data name="QueryServiceResultSetStartRowOutOfRange"><value>Index der Startzeile kann nicht kleiner als 0 oder größer als die Anzahl der Zeilen der Ergebnismenge sein</value></data>
|
||||
<data name="QueryServiceResultSetRowCountOutOfRange"><value>Zeilenanzahl muss eine positive ganze Zahl sein.</value></data>
|
||||
<data name="QueryServiceResultSetNoColumnSchema"><value>Es konnten keine Schemainformationen der Spalte abgerufen werden</value></data>
|
||||
<data name="QueryServiceExecutionPlanNotFound"><value>Es konnten kein Ausführungsplan für die Ergebnismenge abgerufen werden</value></data>
|
||||
<data name="PeekDefinitionAzureError"><value>Diese Funktionalität wird derzeit nicht in Azure SQL DB ud Data Warehouse unterstützt: {0}</value></data>
|
||||
<data name="PeekDefinitionError"><value>Ein unerwarteter Fehler trat beim Einsehen der Definitionen auf: {0}</value></data>
|
||||
<data name="PeekDefinitionNoResultsError"><value>Es wurden keine Ergebnisse gefunden.</value></data>
|
||||
<data name="PeekDefinitionDatabaseError"><value>Es wurde kein Datenbankobjekt abgerufen</value></data>
|
||||
<data name="PeekDefinitionNotConnectedError"><value>Verbinden Sie Sich mit einem Server.</value></data>
|
||||
<data name="PeekDefinitionTimedoutError"><value>Zeitüberschreitung bei der Ausführung</value></data>
|
||||
<data name="PeekDefinitionTypeNotSupportedError"><value>Dieser Objekttyp wird aktuell von dieser Funktionalität nicht unterstützt</value></data>
|
||||
<data name="WorkspaceServicePositionLineOutOfRange"><value>Die Position befindet sich außerhalb der Zeile</value></data>
|
||||
<data name="WorkspaceServicePositionColumnOutOfRange"><value>Die Position befindet sich außerhalb der Spalte in Zeile {0}</value></data>
|
||||
<data name="WorkspaceServiceBufferPositionOutOfOrder"><value>Startposition ({0}, {1}) muss vor oder gleich der Endposition ({2}, {3}) sein</value></data>
|
||||
<data name="EE_BatchSqlMessageNoProcedureInfo"><value>Meldung {0}, Ebene {1}, Status {2}, Zeile {3}</value></data>
|
||||
<data name="EE_BatchSqlMessageWithProcedureInfo"><value>Meldung {0}, Ebene {1}, Status {2}, Prozedur {3}, Zeile {4}</value></data>
|
||||
<data name="EE_BatchSqlMessageNoLineInfo"><value>Meldung {0}, Ebene {1}, Status {2}</value></data>
|
||||
<data name="EE_BatchError_Exception"><value>Fehler beim Ausführen des Batches. Fehlermeldung: {0}</value></data>
|
||||
<data name="EE_BatchExecutionInfo_RowsAffected"><value>({0} Zeile(n) betroffen)</value></data>
|
||||
<data name="EE_ExecutionNotYetCompleteError"><value>Die vorherige Ausführung ist noch nicht abgeschlossen.</value></data>
|
||||
<data name="EE_ScriptError_Error"><value>Ein Skriptfehler ist aufgetreten.</value></data>
|
||||
<data name="EE_ScriptError_ParsingSyntax"><value>Ein Syntaxfehler ist aufgetreten der bei Analyse von {0}</value></data>
|
||||
<data name="EE_ScriptError_FatalError"><value>Ein schwerwiegender Fehler ist aufgetreten.</value></data>
|
||||
<data name="EE_ExecutionInfo_FinalizingLoop"><value>{0}-mal ausgeführt...</value></data>
|
||||
<data name="EE_ExecutionInfo_QueryCancelledbyUser"><value>Sie haben die Abfrage abgebrochen.</value></data>
|
||||
<data name="EE_BatchExecutionError_Halting"><value>Fehler während der Batchausführung.</value></data>
|
||||
<data name="EE_BatchExecutionError_Ignoring"><value>Fehler während der Batchausführung, aber des Fehlers wurde ignoriert.</value></data>
|
||||
<data name="EE_ExecutionInfo_InitializingLoop"><value>Beginning execution loop</value></data>
|
||||
<data name="EE_ExecutionError_CommandNotSupported"><value>Befehl {0} wird nicht unterstützt.</value></data>
|
||||
<data name="EE_ExecutionError_VariableNotFound"><value>Die Variable {0} konnte nicht gefunden werden.</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineError"><value>Fehler bei der SQL-Ausführung: {0}</value></data>
|
||||
<data name="BatchParserWrapperExecutionError"><value>Batch-Ausführung des Batchanalysewrappers: {0} in Zeile {1} gefunden...: {2} Beschreibung: {3}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchMessage"><value>Batch Parser Wrapper Execution Engine Meldung empfangen: Meldung: {0} Ausführliche Meldung: {1}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetProcessing"><value>Stapelverarbeitung Parser Wrapper Execution Engine Stapel ResultSet: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetFinished"><value>Batch-Parser Wrapper Execution Engine wurde beendet ResultSet.</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchCancelling"><value>Ausführung des Batchanalysewrappers Batch abgebrochen.</value></data>
|
||||
<data name="EE_ScriptError_Warning"><value>Scripting-Warnung.</value></data>
|
||||
<data name="TroubleshootingAssistanceMessage"><value>Weitere Informationen zu diesem Fehler finden Sie in den entsprechenden Abschnitten der Produktdokumentation.</value></data>
|
||||
<data name="BatchParser_CircularReference"><value>Die Datei '{0}' ist rekursiv eingeschlossen.</value></data>
|
||||
<data name="BatchParser_CommentNotTerminated"><value>Fehlender End Kommentarzeichen "* /".</value></data>
|
||||
<data name="BatchParser_StringNotTerminated"><value>Fehlendes schließendes Anführungszeichen nach der Zeichenfolge</value></data>
|
||||
<data name="BatchParser_IncorrectSyntax"><value>Syntaxfehler aufgetreten beim Analysieren von '{0}'.</value></data>
|
||||
<data name="BatchParser_VariableNotDefined"><value>Variable {0} ist nicht definiert.</value></data>
|
||||
<data name="TestLocalizationConstant"><value>Test</value></data>
|
||||
<data name="ErrorEmptyStringReplacement"><value>Ersatz einer leeren Zeichenfolge durch eine leere Zeichenfolge.</value></data>
|
||||
<data name="EditDataSessionNotFound"><value>Die Sitzung "{0}" ist nicht vorhanden.</value></data>
|
||||
<data name="EditDataQueryNotCompleted"><value>Die Abfrage wurde nicht abgeschlossen</value></data>
|
||||
<data name="EditDataQueryImproperResultSets"><value>Die Abfrage erzeugte mehr als eine Ergebnismenge</value></data>
|
||||
<data name="EditDataFailedAddRow"><value>Fehler beim Hinzufügen einer neuen Zeile zum Aktualisierungscache</value></data>
|
||||
<data name="EditDataRowOutOfRange"><value>Die angegebene Zeilen-ID ist außerhalb des Bereiches des Bearbeitungscaches</value></data>
|
||||
<data name="EditDataUpdatePending"><value>Für diese Zeile steht eine Aktualisierung an, die erst zurückgenommen werden muß</value></data>
|
||||
<data name="EditDataUpdateNotPending"><value>Die angegebene Zeilen-ID hat keine ausstehenden Aktualisierungen</value></data>
|
||||
<data name="EditDataObjectMetadataNotFound"><value>Tabellen oder Sicht Metadaten konnten nicht gefunden werden</value></data>
|
||||
<data name="EditDataInvalidFormatBinary"><value>Ungültiges Format für eine binäre Spalte</value></data>
|
||||
<data name="EditDataInvalidFormatBoolean"><value>Spalten vom Typ Boolean müssen entweder der Zahl 0 oder 1 oder der Zeichenkette true oder false entsprechen</value></data>
|
||||
<data name="EditDataCreateScriptMissingValue"><value>Ein Pflichtfeld hat keinen Wert.</value></data>
|
||||
<data name="EditDataDeleteSetCell"><value>Für diese Zeile steht ein Löschbefehl aus, die Aktualisierung von Feldern kann nicht durchgeführt werden.</value></data>
|
||||
<data name="EditDataColumnIdOutOfRange"><value>Die ID der Spalte muss innerhalb des Bereichs der Spalten der Abfrage sein</value></data>
|
||||
<data name="EditDataColumnCannotBeEdited"><value>Die Spalte kann nicht editiert werden</value></data>
|
||||
<data name="EditDataColumnNoKeyColumns"><value>Keine Schlüsselspalten gefunden</value></data>
|
||||
<data name="EditDataScriptFilePathNull"><value>Der Name der Ausgabedatei muss angegeben werden</value></data>
|
||||
<data name="EditDataUnsupportedObjectType"><value>Das Datenbankobjekt {0} kan nicht editiert werden</value></data>
|
||||
<data name="ConnectionServiceDbErrorDefaultNotConnected"><value>Spezifizierte URI '{0}' hat keine Standardverbindung</value></data>
|
||||
<data name="EditDataCommitInProgress"><value>Eine Commit-Anweisung wird ausgeführt. Bitte warten Sie bis zur Fertigstellung</value></data>
|
||||
<data name="SqlScriptFormatterDecimalMissingPrecision"><value>Für die Decimal-Spalte fehlt die Angabe der Genauigkeit und Dezimalstellenanzahl</value></data>
|
||||
<data name="EditDataComputedColumnPlaceholder"><value><TBD></value></data>
|
||||
<data name="QueryServiceResultSetAddNoRows"><value>Kann Zeile nicht an Ergebnisbuffer anhängen, da keine Zeilen im Datareader enthalten sind.</value></data>
|
||||
<data name="EditDataTimeOver24Hrs"><value>Der Wert für eine Spalte vom Typ TIME muss zwischen 00:00:00.0000000 und 23:59:59.9999999 liegen</value></data>
|
||||
<data name="EditDataNullNotAllowed"><value>NULL ist für diese Spalte nicht erlaubt</value></data>
|
||||
<data name="EditDataSessionAlreadyExists"><value>Es gibt bereits eine Session</value></data>
|
||||
<data name="EditDataSessionNotInitialized"><value>Eine Session wurde nocht nicht initialisiert</value></data>
|
||||
<data name="EditDataSessionAlreadyInitialized"><value>Eine Session wurde bereits initialisiert</value></data>
|
||||
<data name="EditDataSessionAlreadyInitializing"><value>Eine Session wurde bereits initialisiert oder befindet sich im Prozess der Initialisierung.</value></data>
|
||||
<data name="EditDataQueryFailed"><value>Fehler beim Ausführen der Abfrage. Weitere Informationen finden SIe in der Ausgabe</value></data>
|
||||
<data name="EditDataFilteringNegativeLimit"><value>Die Ergebnismengengrenze darf nicht negativ sein</value></data>
|
||||
<data name="QueryServiceCellNull"><value>NULL</value></data>
|
||||
<data name="EditDataMetadataObjectNameRequired"><value>Der Name des Objekts muss angegeben werden</value></data>
|
||||
<data name="EditDataMetadataTooManyIdentifiers"><value>Einen bestimmten Server oder Datenbank auszuwählen wird nicht unterstützt.</value></data>
|
||||
<data name="EditDataMetadataNotExtended"><value>Die Metadaten der Tabelle enthält keine erweiterten EIgenschaften.</value></data>
|
||||
<data name="EditDataObjectNotFound"><value>Tabelle oder Sicht zur Bearbeitung konnte nicht gefunden werden</value></data>
|
||||
<data name="TreeNodeError"><value>Fehler beim Erweitern von: {0}</value></data>
|
||||
<data name="ServerNodeConnectionError"><value>Fehler bei der Verbindung zu {0}</value></data>
|
||||
<data name="SchemaHierarchy_Aggregates"><value>Aggregate</value></data>
|
||||
<data name="SchemaHierarchy_ServerRoles"><value>Serverrollen</value></data>
|
||||
<data name="SchemaHierarchy_ApplicationRoles"><value>Anwendungsrollen</value></data>
|
||||
<data name="SchemaHierarchy_Assemblies"><value>Assemblys</value></data>
|
||||
<data name="SchemaHierarchy_AssemblyFiles"><value>Assemblydateien</value></data>
|
||||
<data name="SchemaHierarchy_AsymmetricKeys"><value>Asymmetrische Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseAsymmetricKeys"><value>Asymmetrische Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_DataCompressionOptions"><value>Datenkomprimierungsoptionen</value></data>
|
||||
<data name="SchemaHierarchy_Certificates"><value>Zertifikate</value></data>
|
||||
<data name="SchemaHierarchy_FileTables"><value>FileTables</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseCertificates"><value>Zertifikate</value></data>
|
||||
<data name="SchemaHierarchy_CheckConstraints"><value>Einschränkungen überprüfen</value></data>
|
||||
<data name="SchemaHierarchy_Columns"><value>Spalten</value></data>
|
||||
<data name="SchemaHierarchy_Constraints"><value>Einschränkungen</value></data>
|
||||
<data name="SchemaHierarchy_Contracts"><value>Verträge</value></data>
|
||||
<data name="SchemaHierarchy_Credentials"><value>Anmeldeinformationen</value></data>
|
||||
<data name="SchemaHierarchy_ErrorMessages"><value>Fehlermeldungen</value></data>
|
||||
<data name="SchemaHierarchy_ServerRoleMembership"><value>Serverrollenmitgliedschaft</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseOptions"><value>Datenbankoptionen</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseRoles"><value>Datenbankrollen</value></data>
|
||||
<data name="SchemaHierarchy_RoleMemberships"><value>Rollenmitgliedschaften</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseTriggers"><value>Datenbanktrigger</value></data>
|
||||
<data name="SchemaHierarchy_DefaultConstraints"><value>DEFAULT-Einschränkungen</value></data>
|
||||
<data name="SchemaHierarchy_Defaults"><value>Standardwerte</value></data>
|
||||
<data name="SchemaHierarchy_Sequences"><value>Sequenzen</value></data>
|
||||
<data name="SchemaHierarchy_Endpoints"><value>Endpunkte</value></data>
|
||||
<data name="SchemaHierarchy_EventNotifications"><value>Ereignisbenachrichtigungen</value></data>
|
||||
<data name="SchemaHierarchy_ServerEventNotifications"><value>Serverbenachrichtigungsereignisse</value></data>
|
||||
<data name="SchemaHierarchy_ExtendedProperties"><value>Erweiterte Eigenschaften</value></data>
|
||||
<data name="SchemaHierarchy_FileGroups"><value>Dateigruppen</value></data>
|
||||
<data name="SchemaHierarchy_ForeignKeys"><value>Fremdschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_FullTextCatalogs"><value>Volltextkataloge</value></data>
|
||||
<data name="SchemaHierarchy_FullTextIndexes"><value>Volltextindizes</value></data>
|
||||
<data name="SchemaHierarchy_Functions"><value>Funktionen</value></data>
|
||||
<data name="SchemaHierarchy_Indexes"><value>Indizes</value></data>
|
||||
<data name="SchemaHierarchy_InlineFunctions"><value>Inlinefunktionen</value></data>
|
||||
<data name="SchemaHierarchy_Keys"><value>Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_LinkedServers"><value>Verbindungsserver</value></data>
|
||||
<data name="SchemaHierarchy_LinkedServerLogins"><value>Anmeldungen für Verbindungsserver</value></data>
|
||||
<data name="SchemaHierarchy_Logins"><value>Anmeldungen</value></data>
|
||||
<data name="SchemaHierarchy_MasterKey"><value>Hauptschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_MasterKeys"><value>Hauptschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_MessageTypes"><value>Meldungstypen</value></data>
|
||||
<data name="SchemaHierarchy_MultiSelectFunctions"><value>Tabellenwertfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_Parameters"><value>Parameter</value></data>
|
||||
<data name="SchemaHierarchy_PartitionFunctions"><value>Partitionsfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_PartitionSchemes"><value>Partitionsschemas</value></data>
|
||||
<data name="SchemaHierarchy_Permissions"><value>Berechtigungen</value></data>
|
||||
<data name="SchemaHierarchy_PrimaryKeys"><value>Primärschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_Programmability"><value>Programmierbarkeit</value></data>
|
||||
<data name="SchemaHierarchy_Queues"><value>Warteschlangen</value></data>
|
||||
<data name="SchemaHierarchy_RemoteServiceBindings"><value>Remotedienstbindungen</value></data>
|
||||
<data name="SchemaHierarchy_ReturnedColumns"><value>Zurückgegebene Spalten</value></data>
|
||||
<data name="SchemaHierarchy_Roles"><value>Rollen</value></data>
|
||||
<data name="SchemaHierarchy_Routes"><value>Routen</value></data>
|
||||
<data name="SchemaHierarchy_Rules"><value>Regeln</value></data>
|
||||
<data name="SchemaHierarchy_Schemas"><value>Schemas</value></data>
|
||||
<data name="SchemaHierarchy_Security"><value>Sicherheit</value></data>
|
||||
<data name="SchemaHierarchy_ServerObjects"><value>Serverobjekte</value></data>
|
||||
<data name="SchemaHierarchy_Management"><value>Verwaltung</value></data>
|
||||
<data name="SchemaHierarchy_ServerTriggers"><value>Trigger</value></data>
|
||||
<data name="SchemaHierarchy_ServiceBroker"><value>Service Broker</value></data>
|
||||
<data name="SchemaHierarchy_Services"><value>Dienste</value></data>
|
||||
<data name="SchemaHierarchy_Signatures"><value>Signaturen</value></data>
|
||||
<data name="SchemaHierarchy_LogFiles"><value>Protokolldateien</value></data>
|
||||
<data name="SchemaHierarchy_Statistics"><value>Statistik</value></data>
|
||||
<data name="SchemaHierarchy_Storage"><value>Speicher</value></data>
|
||||
<data name="SchemaHierarchy_StoredProcedures"><value>Gespeicherte Prozeduren</value></data>
|
||||
<data name="SchemaHierarchy_SymmetricKeys"><value>Symmetrische Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_Synonyms"><value>Synonyme</value></data>
|
||||
<data name="SchemaHierarchy_Tables"><value>Tabellen</value></data>
|
||||
<data name="SchemaHierarchy_Triggers"><value>Trigger</value></data>
|
||||
<data name="SchemaHierarchy_Types"><value>Typen</value></data>
|
||||
<data name="SchemaHierarchy_UniqueKeys"><value>Eindeutige Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedDataTypes"><value>Benutzerdefinierte Datentypen</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedTypes"><value>Benutzerdefinierte Typen (CLR)</value></data>
|
||||
<data name="SchemaHierarchy_Users"><value>Benutzer</value></data>
|
||||
<data name="SchemaHierarchy_Views"><value>Sichten</value></data>
|
||||
<data name="SchemaHierarchy_XmlIndexes"><value>XML-Indizes</value></data>
|
||||
<data name="SchemaHierarchy_XMLSchemaCollections"><value>XML-Schemaauflistungen</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedTableTypes"><value>Benutzerdefinierte Tabellentypen</value></data>
|
||||
<data name="SchemaHierarchy_FilegroupFiles"><value>Dateien</value></data>
|
||||
<data name="MissingCaption"><value>Fehlende Beschriftung</value></data>
|
||||
<data name="SchemaHierarchy_BrokerPriorities"><value>Brokerprioritäten</value></data>
|
||||
<data name="SchemaHierarchy_CryptographicProviders"><value>Kryptografieanbieter</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseAuditSpecifications"><value>Datenbank-Überwachungsspezifikationen</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseEncryptionKeys"><value>Verschlüsselungsschlüssel für Datenbank</value></data>
|
||||
<data name="SchemaHierarchy_EventSessions"><value>Ereignissitzungen</value></data>
|
||||
<data name="SchemaHierarchy_FullTextStopLists"><value>Volltext-Stopplisten</value></data>
|
||||
<data name="SchemaHierarchy_ResourcePools"><value>Ressourcenpools</value></data>
|
||||
<data name="SchemaHierarchy_ServerAudits"><value>Überwachungen</value></data>
|
||||
<data name="SchemaHierarchy_ServerAuditSpecifications"><value>Serverüberwachungsspezifikationen</value></data>
|
||||
<data name="SchemaHierarchy_SpatialIndexes"><value>Räumliche Indizes</value></data>
|
||||
<data name="SchemaHierarchy_WorkloadGroups"><value>Arbeitsauslastungsgruppen</value></data>
|
||||
<data name="SchemaHierarchy_SqlFiles"><value>SQL-Dateien</value></data>
|
||||
<data name="SchemaHierarchy_ServerFunctions"><value>Serverfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SqlType"><value>SQL-Typ</value></data>
|
||||
<data name="SchemaHierarchy_ServerOptions"><value>Serveroptionen</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseDiagrams"><value>Datenbankdiagramme</value></data>
|
||||
<data name="SchemaHierarchy_SystemTables"><value>Systemtabellen</value></data>
|
||||
<data name="SchemaHierarchy_Databases"><value>Datenbanken</value></data>
|
||||
<data name="SchemaHierarchy_SystemContracts"><value>Systemverträge</value></data>
|
||||
<data name="SchemaHierarchy_SystemDatabases"><value>Systemdatenbanken</value></data>
|
||||
<data name="SchemaHierarchy_SystemMessageTypes"><value>Systemmeldungstypen</value></data>
|
||||
<data name="SchemaHierarchy_SystemQueues"><value>Systemwarteschlangen</value></data>
|
||||
<data name="SchemaHierarchy_SystemServices"><value>Systemdienste</value></data>
|
||||
<data name="SchemaHierarchy_SystemStoredProcedures"><value>Gespeicherte Systemprozeduren</value></data>
|
||||
<data name="SchemaHierarchy_SystemViews"><value>Systemsichten</value></data>
|
||||
<data name="SchemaHierarchy_DataTierApplications"><value>Datenebenenanwendungen</value></data>
|
||||
<data name="SchemaHierarchy_ExtendedStoredProcedures"><value>Erweiterte gespeicherte Prozeduren</value></data>
|
||||
<data name="SchemaHierarchy_SystemAggregateFunctions"><value>Aggregatfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemApproximateNumerics"><value>Ungefähre numerische Ausdrücke</value></data>
|
||||
<data name="SchemaHierarchy_SystemBinaryStrings"><value>Binärzeichenfolgen</value></data>
|
||||
<data name="SchemaHierarchy_SystemCharacterStrings"><value>Zeichenfolgen</value></data>
|
||||
<data name="SchemaHierarchy_SystemCLRDataTypes"><value>CLR-Datentypen</value></data>
|
||||
<data name="SchemaHierarchy_SystemConfigurationFunctions"><value>Konfigurationsfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemCursorFunctions"><value>Cursorfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemDataTypes"><value>Systemdatentypen</value></data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTime"><value>Datum und Uhrzeit</value></data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTimeFunctions"><value>Datums- und Uhrzeitfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemExactNumerics"><value>Genaue numerische Ausdrücke</value></data>
|
||||
<data name="SchemaHierarchy_SystemFunctions"><value>Systemfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemHierarchyIdFunctions"><value>Hierarchie-ID-Funktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemMathematicalFunctions"><value>Mathematische Funktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemMetadataFunctions"><value>Metadatenfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemOtherDataTypes"><value>Andere Datentypen</value></data>
|
||||
<data name="SchemaHierarchy_SystemOtherFunctions"><value>Andere Funktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemRowsetFunctions"><value>Rowsetfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemSecurityFunctions"><value>Sicherheitsfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemSpatialDataTypes"><value>Räumliche Datentypen</value></data>
|
||||
<data name="SchemaHierarchy_SystemStringFunctions"><value>Zeichenfolgenfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemSystemStatisticalFunctions"><value>Statistische Systemfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemTextAndImageFunctions"><value>Text- und Bildfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemUnicodeCharacterStrings"><value>Unicode-Zeichenfolgen</value></data>
|
||||
<data name="SchemaHierarchy_AggregateFunctions"><value>Aggregatfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_ScalarValuedFunctions"><value>Skalarwertfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_TableValuedFunctions"><value>Tabellenwertfunktionen</value></data>
|
||||
<data name="SchemaHierarchy_SystemExtendedStoredProcedures"><value>Erweiterte gespeicherte Systemprozeduren</value></data>
|
||||
<data name="SchemaHierarchy_BuiltInType"><value>Integrierte Typen</value></data>
|
||||
<data name="SchemaHierarchy_BuiltInServerRole"><value>Integrierte Serverrollen</value></data>
|
||||
<data name="SchemaHierarchy_UserWithPassword"><value>Benutzer mit Kennwort</value></data>
|
||||
<data name="SchemaHierarchy_SearchPropertyList"><value>Sucheigenschaftenliste</value></data>
|
||||
<data name="SchemaHierarchy_SecurityPolicies"><value>Sicherheitsrichtlinien</value></data>
|
||||
<data name="SchemaHierarchy_SecurityPredicates"><value>Sicherheitsprädikate</value></data>
|
||||
<data name="SchemaHierarchy_ServerRole"><value>Serverrolle</value></data>
|
||||
<data name="SchemaHierarchy_SearchPropertyLists"><value>Sucheigenschaftenlisten</value></data>
|
||||
<data name="SchemaHierarchy_ColumnStoreIndexes"><value>Spaltenspeicherindizes</value></data>
|
||||
<data name="SchemaHierarchy_TableTypeIndexes"><value>Tabellentypindex</value></data>
|
||||
<data name="SchemaHierarchy_SelectiveXmlIndexes"><value>Selektive XML-Indexe</value></data>
|
||||
<data name="SchemaHierarchy_XmlNamespaces"><value>XML-Namespaces</value></data>
|
||||
<data name="SchemaHierarchy_XmlTypedPromotedPaths"><value>XML-typisierte höher gestufte Pfade</value></data>
|
||||
<data name="SchemaHierarchy_SqlTypedPromotedPaths"><value>T-SQL-typisierte höher gestufte Pfade</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseScopedCredentials"><value>Datenbankweit gültige Anmeldeinformationen</value></data>
|
||||
<data name="SchemaHierarchy_ExternalDataSources"><value>Externe Datenquellen</value></data>
|
||||
<data name="SchemaHierarchy_ExternalFileFormats"><value>Externe Dateiformate</value></data>
|
||||
<data name="SchemaHierarchy_ExternalResources"><value>Externe Ressourcen</value></data>
|
||||
<data name="SchemaHierarchy_ExternalTables"><value>Externe Tabellen</value></data>
|
||||
<data name="SchemaHierarchy_AlwaysEncryptedKeys"><value>Immer verschlüsselte Schlüssel</value></data>
|
||||
<data name="SchemaHierarchy_ColumnMasterKeys"><value>Spaltenhauptschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_ColumnEncryptionKeys"><value>Spaltenverschlüsselungsschlüssel</value></data>
|
||||
<data name="SchemaHierarchy_Server"><value>Server</value></data>
|
||||
<data name="ScriptingParams_ConnectionString_Property_Invalid"><value>Fehler beim Analysieren der Eigenschaft ScriptingParams.ConnectionString.</value></data>
|
||||
<data name="ScriptingParams_FilePath_Property_Invalid"><value>Ungültiges Verzeichnis angeben in der Eigenschaft ScriptingParams.FilePath.</value></data>
|
||||
<data name="ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid"><value>Fehler beim Analysieren der Eigenschaft ScriptingListObjectsCompleteParams.ConnectionString</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterLabelFormatString"><value>{0} ({1}, {2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterNoDefaultLabel"><value>Kein Standard</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputLabel"><value>Eingabe</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputOutputLabel"><value>Eingabe/Ausgabe</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputReadOnlyLabel"><value>Eingabe/schreibgeschützt</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel"><value>Eingabe/Ausgabe/schreibgeschützt</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterDefaultLabel"><value>Standard</value></data>
|
||||
<data name="SchemaHierarchy_NullColumn_Label"><value>NULL</value></data>
|
||||
<data name="SchemaHierarchy_NotNullColumn_Label"><value>nicht NULL</value></data>
|
||||
<data name="SchemaHierarchy_UDDTLabelWithType"><value>{0} ({1}, {2})</value></data>
|
||||
<data name="SchemaHierarchy_UDDTLabelWithoutType"><value>{0} ({1})</value></data>
|
||||
<data name="SchemaHierarchy_ComputedColumnLabelWithType"><value>{0} ({1}berechnet, {2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_ComputedColumnLabelWithoutType"><value>{0} ({1}berechnet)</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithoutType"><value>{0} (Spaltensatz, {1})</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithType"><value>{0} (Spaltensatz, {1} {2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString"><value>{0} (Spaltensatz, {1}, {2}, {3})</value></data>
|
||||
<data name="UniqueIndex_LabelPart"><value>Eindeutig</value></data>
|
||||
<data name="NonUniqueIndex_LabelPart"><value>Nicht eindeutig</value></data>
|
||||
<data name="ClusteredIndex_LabelPart"><value>Gruppiert</value></data>
|
||||
<data name="NonClusteredIndex_LabelPart"><value>Nicht gruppiert</value></data>
|
||||
<data name="History_LabelPart"><value>Verlauf</value></data>
|
||||
<data name="SystemVersioned_LabelPart"><value>System-Mit Versionsangabe</value></data>
|
||||
<data name="unavailable"><value>Nicht verfügbar</value></data>
|
||||
<data name="filegroup_dialog_defaultFilegroup"><value>Aktuelle Standarddateigruppe: {0}</value></data>
|
||||
<data name="filegroup_dialog_title"><value>Neue Dateigruppe für "{0}"</value></data>
|
||||
<data name="filegroups_default"><value>Standard</value></data>
|
||||
<data name="filegroups_files"><value>Dateien</value></data>
|
||||
<data name="filegroups_name"><value>Name</value></data>
|
||||
<data name="filegroups_readonly"><value>Schreibgeschützt</value></data>
|
||||
<data name="general_autogrowth"><value>Automatische Vergrößerung/Maximale Größe</value></data>
|
||||
<data name="general_builderText"><value>...</value></data>
|
||||
<data name="general_default"><value><Standard></value></data>
|
||||
<data name="general_fileGroup"><value>Dateigruppe</value></data>
|
||||
<data name="general_fileName"><value>Logischer Name</value></data>
|
||||
<data name="general_fileType"><value>Dateityp</value></data>
|
||||
<data name="general_initialSize"><value>Anfangsgröße (MB)</value></data>
|
||||
<data name="general_newFilegroup"><value><neue Dateigruppe></value></data>
|
||||
<data name="general_path"><value>Pfad</value></data>
|
||||
<data name="general_physicalFileName"><value>Dateiname</value></data>
|
||||
<data name="general_rawDevice"><value><unformatiertes Medium></value></data>
|
||||
<data name="general_recoveryModel_bulkLogged"><value>Massenprotokolliert</value></data>
|
||||
<data name="general_recoveryModel_full"><value>Vollständig</value></data>
|
||||
<data name="general_recoveryModel_simple"><value>Einfach</value></data>
|
||||
<data name="general_titleSearchOwner"><value>Datenbankbesitzer auswählen</value></data>
|
||||
<data name="prototype_autogrowth_disabled"><value>Kein(e)</value></data>
|
||||
<data name="prototype_autogrowth_restrictedGrowthByMB"><value>Um {0} MB, auf {1} MB beschränkt</value></data>
|
||||
<data name="prototype_autogrowth_restrictedGrowthByPercent"><value>Um {0} Prozent, auf {1} MB beschränkt </value></data>
|
||||
<data name="prototype_autogrowth_unrestrictedGrowthByMB"><value>Um {0} MB, unbegrenzt</value></data>
|
||||
<data name="prototype_autogrowth_unrestrictedGrowthByPercent"><value>Um {0} Prozent, unbegrenzt</value></data>
|
||||
<data name="prototype_autogrowth_unlimitedfilestream"><value>Unbegrenzt</value></data>
|
||||
<data name="prototype_autogrowth_limitedfilestream"><value>Auf {0} MB beschränkt</value></data>
|
||||
<data name="prototype_db_category_automatic"><value>Automatisch</value></data>
|
||||
<data name="prototype_db_category_servicebroker"><value>Service Broker</value></data>
|
||||
<data name="prototype_db_category_collation"><value>Sortierung</value></data>
|
||||
<data name="prototype_db_category_cursor"><value>Cursor</value></data>
|
||||
<data name="prototype_db_category_misc"><value>Verschiedenes</value></data>
|
||||
<data name="prototype_db_category_recovery"><value>Wiederherstellung</value></data>
|
||||
<data name="prototype_db_category_state"><value>Status</value></data>
|
||||
<data name="prototype_db_prop_ansiNullDefault"><value>ANSI NULL Default</value></data>
|
||||
<data name="prototype_db_prop_ansiNulls"><value>ANSI NULLS aktiviert</value></data>
|
||||
<data name="prototype_db_prop_ansiPadding"><value>ANSI-Auffüllung aktiviert </value></data>
|
||||
<data name="prototype_db_prop_ansiWarnings"><value>ANSI Warnings aktiviert</value></data>
|
||||
<data name="prototype_db_prop_arithabort"><value>Abbruch bei arithmetischem Fehler aktiviert </value></data>
|
||||
<data name="prototype_db_prop_autoClose"><value>Automatisch schließen</value></data>
|
||||
<data name="prototype_db_prop_autoCreateStatistics"><value>Statistik automatisch erstellen</value></data>
|
||||
<data name="prototype_db_prop_autoShrink"><value>Automatisch verkleinern</value></data>
|
||||
<data name="prototype_db_prop_autoUpdateStatistics"><value>Statistiken automatisch aktualisieren </value></data>
|
||||
<data name="prototype_db_prop_autoUpdateStatisticsAsync"><value>Statistik automatisch asynchron aktualisieren</value></data>
|
||||
<data name="prototype_db_prop_caseSensitive"><value>Unterscheidung nach Groß-/Kleinschreibung</value></data>
|
||||
<data name="prototype_db_prop_closeCursorOnCommit"><value>Schließen des Cursors nach Commit aktiviert </value></data>
|
||||
<data name="prototype_db_prop_collation"><value>Sortierung</value></data>
|
||||
<data name="prototype_db_prop_concatNullYieldsNull"><value>Verketten von NULL-Werten ergibt NULL </value></data>
|
||||
<data name="prototype_db_prop_databaseCompatibilityLevel"><value>Datenbank-Kompatibilitätsgrad </value></data>
|
||||
<data name="prototype_db_prop_databaseState"><value>Datenbankstatus </value></data>
|
||||
<data name="prototype_db_prop_defaultCursor"><value>Standardcursor</value></data>
|
||||
<data name="prototype_db_prop_fullTextIndexing"><value>Volltextindizierung aktiviert </value></data>
|
||||
<data name="prototype_db_prop_numericRoundAbort"><value>Abbruch bei numerischem Runden </value></data>
|
||||
<data name="prototype_db_prop_pageVerify"><value>Seitenüberprüfung </value></data>
|
||||
<data name="prototype_db_prop_quotedIdentifier"><value>Bezeichner in Anführungszeichen aktiviert </value></data>
|
||||
<data name="prototype_db_prop_readOnly"><value>Datenbank schreibgeschützt</value></data>
|
||||
<data name="prototype_db_prop_recursiveTriggers"><value>Rekursive Trigger aktiviert </value></data>
|
||||
<data name="prototype_db_prop_restrictAccess"><value>Zugriff beschränken</value></data>
|
||||
<data name="prototype_db_prop_selectIntoBulkCopy"><value>Select Into/Bulk Copy</value></data>
|
||||
<data name="prototype_db_prop_honorBrokerPriority"><value>Brokerpriorität berücksichtigen</value></data>
|
||||
<data name="prototype_db_prop_serviceBrokerGuid"><value>Service Broker-Bezeichner</value></data>
|
||||
<data name="prototype_db_prop_brokerEnabled"><value>Broker aktiviert</value></data>
|
||||
<data name="prototype_db_prop_truncateLogOnCheckpoint"><value>Protokoll bei Prüfpunkt abschneiden </value></data>
|
||||
<data name="prototype_db_prop_dbChaining"><value>Datenbankübergreifende Besitzverkettung aktiviert</value></data>
|
||||
<data name="prototype_db_prop_trustworthy"><value>Vertrauenswürdig</value></data>
|
||||
<data name="prototype_db_prop_dateCorrelationOptimization"><value>Optimierung der Datumskorrelation aktiviert:
|
||||
prototype_db_prop_parameterization = Parameterization</value></data>
|
||||
<data name="prototype_db_prop_parameterization_value_forced"><value>Erzwungen</value></data>
|
||||
<data name="prototype_db_prop_parameterization_value_simple"><value>Einfach</value></data>
|
||||
<data name="prototype_file_dataFile"><value>ROWS (Daten)</value></data>
|
||||
<data name="prototype_file_logFile"><value>LOG</value></data>
|
||||
<data name="prototype_file_filestreamFile"><value>FILESTREAM-Daten</value></data>
|
||||
<data name="prototype_file_noFileGroup"><value>Nicht zutreffend</value></data>
|
||||
<data name="prototype_file_defaultpathstring"><value><Standardpfad></value></data>
|
||||
<data name="title_openConnectionsMustBeClosed"><value>Geöffnete Verbindungen</value></data>
|
||||
<data name="warning_openConnectionsMustBeClosed"><value>Zum Ändern der Datenbankeigenschaften muss SQL Server alle anderen Verbindungen mit der Datenbank schließen. Möchten Sie wirklich die Eigenschaften ändern und alle anderen Verbindungen schließen?</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_autoClosed"><value>AUTO_CLOSED</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_emergency"><value>EMERGENCY</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_inaccessible"><value>INACCESSIBLE</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_normal"><value>NORMAL</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_offline"><value>OFFLINE</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_recovering"><value>RECOVERING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_recoveryPending"><value>RECOVERY PENDING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_restoring"><value>RESTORING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_shutdown"><value>SHUTDOWN</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_standby"><value>STANDBY</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_suspect"><value>SUSPECT</value></data>
|
||||
<data name="prototype_db_prop_defaultCursor_value_global"><value>GLOBAL</value></data>
|
||||
<data name="prototype_db_prop_defaultCursor_value_local"><value>LOCAL</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_multiple"><value>MULTI_USER</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_restricted"><value>RESTRICTED_USER</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_single"><value>SINGLE_USER</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_checksum"><value>CHECKSUM</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_none"><value>NONE</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_tornPageDetection"><value>TORN_PAGE_DETECTION</value></data>
|
||||
<data name="prototype_db_prop_varDecimalEnabled"><value>VarDecimal-Speicherformat aktiviert</value></data>
|
||||
<data name="compatibilityLevel_katmai"><value>SQL Server 2008 (100)</value></data>
|
||||
<data name="prototype_db_prop_encryptionEnabled"><value>Verschlüsselung aktiviert</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_off"><value>AUS</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_on"><value>EIN</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_primary"><value>PRIMÄR</value></data>
|
||||
<data name="error_db_prop_invalidleadingColumns"><value>Die Anzahl führender Hashspalten ist bei der HASH-Verteilungsrichtlinie optional, sollte aber zwischen 1 und 16 Spalten liegen.</value></data>
|
||||
<data name="compatibilityLevel_denali"><value>SQL Server 2012 (110)</value></data>
|
||||
<data name="compatibilityLevel_sql14"><value>SQL Server 2014 (120)</value></data>
|
||||
<data name="compatibilityLevel_sql15"><value>SQL Server 2016 (130)</value></data>
|
||||
<data name="compatibilityLevel_sqlvNext"><value>SQL Server vNext (140)</value></data>
|
||||
<data name="general_containmentType_None"><value>Kein(e)</value></data>
|
||||
<data name="general_containmentType_Partial"><value>Teilweise</value></data>
|
||||
<data name="filegroups_filestreamFiles"><value>FILESTREAM-Dateien</value></data>
|
||||
<data name="prototype_file_noApplicableFileGroup"><value>Keine anwendbare Dateigruppe</value></data>
|
||||
<data name="DatabaseNotAccessible"><value>Auf die Datenbank "{0}" kann nicht zugegriffen werden.</value></data>
|
||||
<data name="QueryServiceResultSetHasNoResults"><value>Abfrage hat keine Ergebnis zum Zurückgeben</value></data>
|
||||
<data name="QueryServiceResultSetTooLarge"><value>Ergebnismenge ist zu groß, um sicher geladen zu werden</value></data>
|
||||
<data name="prototype_db_prop_parameterization"><value>Parametrisierung</value></data>
|
||||
<data name="ConflictWithNoRecovery"><value>Diese Option darf nicht angegeben werden, wenn eine Sicherung mit der NORECOVERY-Option wiederhergestellt wird.</value></data>
|
||||
<data name="InvalidPathForDatabaseFile"><value>Ungültiger Pfad für Datenbankdatei: {0}</value></data>
|
||||
<data name="Log"><value>Protokoll</value></data>
|
||||
<data name="RestorePlanFailed"><value>Fehler beim Erstellen des Wiederherstellungsplan</value></data>
|
||||
<data name="RestoreNotSupported"><value>Wiederherstellen der Datenbank wird nicht unterstützt.</value></data>
|
||||
<data name="RestoreTaskName"><value>Datenbank wiederherstellen</value></data>
|
||||
<data name="RestoreCopyOnly"><value>(nur kopieren)</value></data>
|
||||
<data name="RestoreBackupSetComponent"><value>Komponente</value></data>
|
||||
<data name="RestoreBackupSetType"><value>Typ</value></data>
|
||||
<data name="RestoreBackupSetServer"><value>Server</value></data>
|
||||
<data name="RestoreBackupSetDatabase"><value>Datenbank</value></data>
|
||||
<data name="RestoreBackupSetPosition"><value>Position</value></data>
|
||||
<data name="RestoreBackupSetFirstLsn"><value>Erste LSN</value></data>
|
||||
<data name="RestoreBackupSetLastLsn"><value>Letzte LSN</value></data>
|
||||
<data name="RestoreBackupSetCheckpointLsn"><value>Prüfpunkt-LSN</value></data>
|
||||
<data name="RestoreBackupSetFullLsn"><value>Vollständige LSN</value></data>
|
||||
<data name="RestoreBackupSetStartDate"><value>Startdatum</value></data>
|
||||
<data name="RestoreBackupSetFinishDate"><value>Beendigungsdatum</value></data>
|
||||
<data name="RestoreBackupSetSize"><value>Größe</value></data>
|
||||
<data name="RestoreBackupSetUserName"><value>Benutzername</value></data>
|
||||
<data name="RestoreBackupSetExpiration"><value>Ablaufdatum</value></data>
|
||||
<data name="RestoreBackupSetName"><value>Name</value></data>
|
||||
<data name="TheLastBackupTaken"><value>Letzte Sicherung ({0})</value></data>
|
||||
<data name="BackupTaskName"><value>Datenbank sichern</value></data>
|
||||
<data name="TaskInProgress"><value>In Bearbeitung</value></data>
|
||||
<data name="TaskCompleted"><value>Abgeschlossen</value></data>
|
||||
<data name="ScriptTaskName"><value>Skripterstellung</value></data>
|
||||
<data name="ProfilerConnectionNotFound"><value>Verbindung nicht gefunden</value></data>
|
||||
<data name="BackupPathIsFolderError"><value>Der angegebene Dateiname ist zugleich ein Verzeichnisname: {0}</value></data>
|
||||
<data name="InvalidBackupPathError"><value>Es kann nicht überprüft werden, ob der Speicherort der Sicherungsdatei vorhanden ist: {0}</value></data>
|
||||
<data name="InvalidPathError"><value>Auf den angegebenen Pfad auf dem Server kann nicht zugegriffen werden: {0}</value></data>
|
||||
<data name="NoBackupsetsToRestore"><value>Kein Sicherungssatz zur Wiederherstellung ausgewählt</value></data>
|
||||
<data name="NeverBackedUp"><value>Nie</value></data>
|
||||
<data name="AzureSqlDbEdition"><value>Azure SQL DB</value></data>
|
||||
<data name="AzureSqlDwEdition"><value>Azure SQL Data Warehouse</value></data>
|
||||
<data name="AzureSqlStretchEdition"><value>Azure SQL Stretch Database</value></data>
|
||||
<data name="Error_InvalidDirectoryName"><value>Der Pfad {0} ist kein gültiges Verzeichnis</value></data>
|
||||
<data name="Error_ExistingDirectoryName"><value>Die Datei {1} im Verzeichnis {0} existiert bereits.</value></data>
|
||||
<data name="EditDataValueTooLarge"><value>Der Wert {0} ist zu groß für eine Spalte mit dem Datentyp {1}</value></data>
|
||||
</root>
|
||||
489
src/Microsoft.Kusto.ServiceLayer/Localization/sr.es.resx
Normal file
489
src/Microsoft.Kusto.ServiceLayer/Localization/sr.es.resx
Normal file
@@ -0,0 +1,489 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader><resheader name="version"><value>1.3</value></resheader><resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><data name="ConnectionServiceConnectErrorNullParams"><value>Los parámetros de conexión no pueden ser nulos</value></data>
|
||||
<data name="ConnectionServiceListDbErrorNullOwnerUri"><value>OwnerUri no puede ser nulo ni estar vacío</value></data>
|
||||
<data name="ConnectionServiceListDbErrorNotConnected"><value>SpecifiedUri '{0}' no tiene una conexión existente</value></data>
|
||||
<data name="ConnectionServiceConnStringInvalidAuthType"><value>El valor '{0}' no es válido para AuthenticationType. Los valores válidos son 'Integrated' y 'SqlLogin'.</value></data>
|
||||
<data name="ConnectionServiceConnStringInvalidIntent"><value>El valor '{0}' no es válido para ApplicationIntent. Los valores válidos son 'ReadWrite' y 'ReadOnly'.</value></data>
|
||||
<data name="ConnectionServiceConnectionCanceled"><value>Conexión cancelada</value></data>
|
||||
<data name="ConnectionParamsValidateNullOwnerUri"><value>OwnerUri no puede ser nulo ni estar vacío</value></data>
|
||||
<data name="ConnectionParamsValidateNullConnection"><value>El objeto de detalles de conexión no puede ser nulo</value></data>
|
||||
<data name="ConnectionParamsValidateNullServerName"><value>ServerName no puede ser nulo ni estar vacío</value></data>
|
||||
<data name="ConnectionParamsValidateNullSqlAuth"><value>{0} no puede ser nulo ni estar vacío cuando se utiliza autenticación SqlLogin</value></data>
|
||||
<data name="QueryServiceCancelAlreadyCompleted"><value>Ya se ha completado la consulta, no se puede cancelar</value></data>
|
||||
<data name="QueryServiceCancelDisposeFailed"><value>La consulta fue cancelada con éxito, pero no se ha podido desechar. No se encontró el URI del propietario.</value></data>
|
||||
<data name="QueryServiceQueryCancelled"><value>Consulta cancelada por el usuario</value></data>
|
||||
<data name="QueryServiceSubsetBatchNotCompleted"><value>El lote aún no ha finalizado,</value></data>
|
||||
<data name="QueryServiceSubsetBatchOutOfRange"><value>Índice de lote no puede ser menor que 0 o mayor que el número de lotes</value></data>
|
||||
<data name="QueryServiceSubsetResultSetOutOfRange"><value>Índice del conjunto de resultados no puede ser menor que 0 o mayor que el número de conjuntos de resultados</value></data>
|
||||
<data name="QueryServiceDataReaderByteCountInvalid"><value>El número máximo de bytes a devolver debe ser mayor que cero</value></data>
|
||||
<data name="QueryServiceDataReaderCharCountInvalid"><value>El número máximo de caracteres a devolver debe ser mayor que cero</value></data>
|
||||
<data name="QueryServiceDataReaderXmlCountInvalid"><value>El número máximo de bytes XML a devolver debe ser mayor que cero</value></data>
|
||||
<data name="QueryServiceFileWrapperWriteOnly"><value>El método de acceso no puede ser de sólo escritura</value></data>
|
||||
<data name="QueryServiceFileWrapperNotInitialized"><value>FileStreamWrapper debe inicializarse antes de realizar operaciones</value></data>
|
||||
<data name="QueryServiceFileWrapperReadOnly"><value>Este FileStreamWrapper no se puede utilizar para escritura.</value></data>
|
||||
<data name="QueryServiceAffectedOneRow"><value>(1 fila afectada)</value></data>
|
||||
<data name="QueryServiceAffectedRows"><value>({0} filas afectadas)</value></data>
|
||||
<data name="QueryServiceCompletedSuccessfully"><value>Comandos finalizados correctamente.</value></data>
|
||||
<data name="QueryServiceErrorFormat"><value>Msg {0}, nivel {1} estado {2}, línea {3} {4} {5}</value></data>
|
||||
<data name="QueryServiceQueryFailed"><value>Error en la consulta: {0}</value></data>
|
||||
<data name="QueryServiceColumnNull"><value>(Ningún nombre de columna)</value></data>
|
||||
<data name="QueryServiceRequestsNoQuery"><value>La consulta solicitada no existe</value></data>
|
||||
<data name="QueryServiceQueryInvalidOwnerUri"><value>Este editor no está conectado a una base de datos</value></data>
|
||||
<data name="QueryServiceQueryInProgress"><value>Una consulta ya está en curso para esta sesión de editor. Por favor, cancelar esta consulta o esperar su finalización.</value></data>
|
||||
<data name="QueryServiceMessageSenderNotSql"><value>Remitente de eventos de OnInfoMessage debe ser un objeto SqlConnection</value></data>
|
||||
<data name="QueryServiceSaveAsResultSetNotComplete"><value>No se puede guardar el resultado hasta que haya finalizado la ejecución de la consulta</value></data>
|
||||
<data name="QueryServiceSaveAsMiscStartingError"><value>Error interno al iniciar el guardado de la tarea</value></data>
|
||||
<data name="QueryServiceSaveAsInProgress"><value>Una operacion de guardado en la misma ruta se encuentra en curso</value></data>
|
||||
<data name="QueryServiceSaveAsFail"><value>Error al guardar {0}: {1}</value></data>
|
||||
<data name="QueryServiceResultSetNotRead"><value>No se puede leer el subconjunto, a menos que los resultados se han leído desde el servidor</value></data>
|
||||
<data name="QueryServiceResultSetStartRowOutOfRange"><value>Fila de inicio no puede ser menor que 0 o mayor que el número de filas en el conjunto de resultados</value></data>
|
||||
<data name="QueryServiceResultSetRowCountOutOfRange"><value>La cantidad de filas debe ser un entero positivo</value></data>
|
||||
<data name="QueryServiceResultSetNoColumnSchema"><value>No se pudo recuperar el esquema de columna para el conjunto de resultados</value></data>
|
||||
<data name="QueryServiceExecutionPlanNotFound"><value>No se pudo recuperar un plan de ejecución del conjunto de resultados</value></data>
|
||||
<data name="PeekDefinitionAzureError"><value>Esta característica actualmente no se admite en la base de datos de SQL Azure y almacén de datos: {0}</value></data>
|
||||
<data name="PeekDefinitionError"><value>Se ha producido un error inesperado durante la ejecución de la definición de Peek: {0}</value></data>
|
||||
<data name="PeekDefinitionNoResultsError"><value>No se encontraron resultados.</value></data>
|
||||
<data name="PeekDefinitionDatabaseError"><value>No se pudo obtener ningún objeto asociado a la base de datos.</value></data>
|
||||
<data name="PeekDefinitionNotConnectedError"><value>Por favor, conéctese a un servidor</value></data>
|
||||
<data name="PeekDefinitionTimedoutError"><value>Tiempo de espera agotado para esta operación.</value></data>
|
||||
<data name="PeekDefinitionTypeNotSupportedError"><value>Esta característica no admite actualmente este tipo de objeto.</value></data>
|
||||
<data name="WorkspaceServicePositionLineOutOfRange"><value>Posición está fuera del intervalo de la línea de archivo</value></data>
|
||||
<data name="WorkspaceServicePositionColumnOutOfRange"><value>Posición está fuera del intervalo de la columna de la línea {0}</value></data>
|
||||
<data name="WorkspaceServiceBufferPositionOutOfOrder"><value>Posición de inicio ({0}, {1}) debe preceder o ser igual a la posición final ({2}, {3})</value></data>
|
||||
<data name="EE_BatchSqlMessageNoProcedureInfo"><value>Msg {0}, {1}, nivel de estado {2}, línea {3}</value></data>
|
||||
<data name="EE_BatchSqlMessageWithProcedureInfo"><value>Msj {0}, {1}, nivel de estado {2}, procedimiento {3}, línea {4}</value></data>
|
||||
<data name="EE_BatchSqlMessageNoLineInfo"><value>Msg {0}, nivel {1}, {2} de estado</value></data>
|
||||
<data name="EE_BatchError_Exception"><value>Se produjo un error al procesar el lote. Mensaje de error: {0}</value></data>
|
||||
<data name="EE_BatchExecutionInfo_RowsAffected"><value>({0} filas afectadas)</value></data>
|
||||
<data name="EE_ExecutionNotYetCompleteError"><value>La ejecución anterior aún no está completa.</value></data>
|
||||
<data name="EE_ScriptError_Error"><value>Se ha producido un error de secuencias de comandos.</value></data>
|
||||
<data name="EE_ScriptError_ParsingSyntax"><value>Se encontró sintaxis incorrecta mientras se estaba analizando {0}.</value></data>
|
||||
<data name="EE_ScriptError_FatalError"><value>Se ha producido un error grave.</value></data>
|
||||
<data name="EE_ExecutionInfo_FinalizingLoop"><value>La ejecución se completó {0} veces...</value></data>
|
||||
<data name="EE_ExecutionInfo_QueryCancelledbyUser"><value>Se canceló la consulta.</value></data>
|
||||
<data name="EE_BatchExecutionError_Halting"><value>Se produjo un error mientras se ejecutaba el lote.</value></data>
|
||||
<data name="EE_BatchExecutionError_Ignoring"><value>Se produjo un error mientras se ejecutaba el lote, pero se ha omitido el error.</value></data>
|
||||
<data name="EE_ExecutionInfo_InitializingLoop"><value>Beginning execution loop</value></data>
|
||||
<data name="EE_ExecutionError_CommandNotSupported"><value>No se admite el comando {0}.</value></data>
|
||||
<data name="EE_ExecutionError_VariableNotFound"><value>La variable {0} no se encontró.</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineError"><value>Error de ejecución de SQL: {0}</value></data>
|
||||
<data name="BatchParserWrapperExecutionError"><value>Ejecución de contenedor del analizador por lotes: {0} se encuentra... en la línea {1}: {2} Descripción: {3}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchMessage"><value>Lote analizador contenedor ejecución motor lote mensaje recibido: mensaje: {0} mensaje detallado: {1}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetProcessing"><value>Motor de ejecución de analizador contenedor lote ResultSet procesamiento por lotes: DataReader.FieldCount: {0} DataReader.RecordsAffected: {1}</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchResultSetFinished"><value>Finalizó el elemento ResultSet analizador contenedor ejecución motor los lotes.</value></data>
|
||||
<data name="BatchParserWrapperExecutionEngineBatchCancelling"><value>Cancelando la ejecución por lotes del contenedor del analizador por lotes.</value></data>
|
||||
<data name="EE_ScriptError_Warning"><value>Advertencia de scripting.</value></data>
|
||||
<data name="TroubleshootingAssistanceMessage"><value>Para obtener más información acerca de este error, vea los temas de solución de problemas en la documentación del producto.</value></data>
|
||||
<data name="BatchParser_CircularReference"><value>El archivo '{0}' se incluyó recursivamente.</value></data>
|
||||
<data name="BatchParser_CommentNotTerminated"><value>Falta la marca de final de comentario ' * /'.</value></data>
|
||||
<data name="BatchParser_StringNotTerminated"><value>Sin comilla de cierre después de la cadena de caracteres.</value></data>
|
||||
<data name="BatchParser_IncorrectSyntax"><value>Se encontró sintaxis incorrecta al analizar '{0}'.</value></data>
|
||||
<data name="BatchParser_VariableNotDefined"><value>La variable {0} no está definida.</value></data>
|
||||
<data name="TestLocalizationConstant"><value>prueba</value></data>
|
||||
<data name="ErrorEmptyStringReplacement"><value>Sustitución de una cadena vacía por una cadena vacía.</value></data>
|
||||
<data name="EditDataSessionNotFound"><value>Sesión de edición no existe,</value></data>
|
||||
<data name="EditDataQueryNotCompleted"><value>La consulta no ha finalizado.</value></data>
|
||||
<data name="EditDataQueryImproperResultSets"><value>La consulta no generó un único set de resultados</value></data>
|
||||
<data name="EditDataFailedAddRow"><value>Falló al agregar una nueva fila a la caché de actualización</value></data>
|
||||
<data name="EditDataRowOutOfRange"><value>El ID de la fila ingresado, se encuentra fuera del rango de filas de la caché de edición</value></data>
|
||||
<data name="EditDataUpdatePending"><value>Una actualización está pendiente para esta fila y debe de revertirse primero</value></data>
|
||||
<data name="EditDataUpdateNotPending"><value>El ID de la fila ingresado no tiene actualizaciones pendientes</value></data>
|
||||
<data name="EditDataObjectMetadataNotFound"><value>La metadata de la tabla o vista no pudo ser encontrada</value></data>
|
||||
<data name="EditDataInvalidFormatBinary"><value>Formato inválido para columna binaria</value></data>
|
||||
<data name="EditDataInvalidFormatBoolean"><value>Columnas del tipo boolean deben de ser numéricos 1 o 0, o tipo string true o false</value></data>
|
||||
<data name="EditDataCreateScriptMissingValue"><value>Falta un valor requerido de la celda</value></data>
|
||||
<data name="EditDataDeleteSetCell"><value>Existe una eliminación pendiente para esta fila, una actualización de celda no puede ser realizada.</value></data>
|
||||
<data name="EditDataColumnIdOutOfRange"><value>El ID de la columna debe de estar en el rango de columnas de la consulta.</value></data>
|
||||
<data name="EditDataColumnCannotBeEdited"><value>La columna no puede ser editada</value></data>
|
||||
<data name="EditDataColumnNoKeyColumns"><value>No se encontró ninguna columna clave</value></data>
|
||||
<data name="EditDataScriptFilePathNull"><value>Proporcione un nombre de archivo de salida</value></data>
|
||||
<data name="EditDataUnsupportedObjectType"><value>Objeto de base de datos {0} no puede ser usado para modificación.</value></data>
|
||||
<data name="ConnectionServiceDbErrorDefaultNotConnected"><value>SpecifiedUri '{0}' no tiene alguna conexión por defecto</value></data>
|
||||
<data name="EditDataCommitInProgress"><value>Una tarea de confirmación se encuentra en progreso. Por favor espere que la operación termine.</value></data>
|
||||
<data name="SqlScriptFormatterDecimalMissingPrecision"><value>Columna del tipo decimal no tiene precisión o escala numérica</value></data>
|
||||
<data name="EditDataComputedColumnPlaceholder"><value><TBD></value></data>
|
||||
<data name="QueryServiceResultSetAddNoRows"><value>No se pueden agregar filas al buffer de resultados, el lector de datos no contiene filas</value></data>
|
||||
<data name="EditDataTimeOver24Hrs"><value>Los valores en la columna TIME deben estar incluidos en el rango desde 00:00:00:000000 hasta 23:59:59.999999</value></data>
|
||||
<data name="EditDataNullNotAllowed"><value>No se permite un valor NULL en esta columna</value></data>
|
||||
<data name="EditDataSessionAlreadyExists"><value>La sesión de edición ya existe.</value></data>
|
||||
<data name="EditDataSessionNotInitialized"><value>La sesión de edición no se inicializó</value></data>
|
||||
<data name="EditDataSessionAlreadyInitialized"><value>La sesión de edición ya se inicializó</value></data>
|
||||
<data name="EditDataSessionAlreadyInitializing"><value>La sesión de edición ya se inicializo o se encuentra en proceso de inicialización</value></data>
|
||||
<data name="EditDataQueryFailed"><value>La ejecución de la consulta falló, ver los mensajes para obtener mas detalle</value></data>
|
||||
<data name="EditDataFilteringNegativeLimit"><value>El límite del resultado no puede ser negativo</value></data>
|
||||
<data name="QueryServiceCellNull"><value>NULL</value></data>
|
||||
<data name="EditDataMetadataObjectNameRequired"><value>Se debe proveer un nombre de objeto</value></data>
|
||||
<data name="EditDataMetadataTooManyIdentifiers"><value>No se permite especificar explícitamente el servidor o la base de datos</value></data>
|
||||
<data name="EditDataMetadataNotExtended"><value>Los metadatos de la tabla no tienen propiedades extendidas</value></data>
|
||||
<data name="EditDataObjectNotFound"><value>La tabla o vista solicitada para edición no se encuentra</value></data>
|
||||
<data name="TreeNodeError"><value>Error en expansión: {0}</value></data>
|
||||
<data name="ServerNodeConnectionError"><value>Error conectando a {0}</value></data>
|
||||
<data name="SchemaHierarchy_Aggregates"><value>Agregados</value></data>
|
||||
<data name="SchemaHierarchy_ServerRoles"><value>Roles de servidor</value></data>
|
||||
<data name="SchemaHierarchy_ApplicationRoles"><value>Roles de aplicación</value></data>
|
||||
<data name="SchemaHierarchy_Assemblies"><value>Ensamblados</value></data>
|
||||
<data name="SchemaHierarchy_AssemblyFiles"><value>Archivos de ensamblado</value></data>
|
||||
<data name="SchemaHierarchy_AsymmetricKeys"><value>Claves asimétricas</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseAsymmetricKeys"><value>Claves asimétricas</value></data>
|
||||
<data name="SchemaHierarchy_DataCompressionOptions"><value>Opciones de compresión de datos</value></data>
|
||||
<data name="SchemaHierarchy_Certificates"><value>Certificados</value></data>
|
||||
<data name="SchemaHierarchy_FileTables"><value>Tablas de archivos</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseCertificates"><value>Certificados</value></data>
|
||||
<data name="SchemaHierarchy_CheckConstraints"><value>Restricciones CHECK</value></data>
|
||||
<data name="SchemaHierarchy_Columns"><value>Columnas</value></data>
|
||||
<data name="SchemaHierarchy_Constraints"><value>Restricciones</value></data>
|
||||
<data name="SchemaHierarchy_Contracts"><value>Contratos</value></data>
|
||||
<data name="SchemaHierarchy_Credentials"><value>Credenciales</value></data>
|
||||
<data name="SchemaHierarchy_ErrorMessages"><value>Mensajes de error</value></data>
|
||||
<data name="SchemaHierarchy_ServerRoleMembership"><value>Pertenencia a roles de servidor</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseOptions"><value>Opciones de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseRoles"><value>Roles de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_RoleMemberships"><value>Pertenencias a roles</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseTriggers"><value>Desencadenadores de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_DefaultConstraints"><value>Restricciones DEFAULT</value></data>
|
||||
<data name="SchemaHierarchy_Defaults"><value>Valores predeterminados</value></data>
|
||||
<data name="SchemaHierarchy_Sequences"><value>Secuencias</value></data>
|
||||
<data name="SchemaHierarchy_Endpoints"><value>Extremos</value></data>
|
||||
<data name="SchemaHierarchy_EventNotifications"><value>Notificaciones de eventos</value></data>
|
||||
<data name="SchemaHierarchy_ServerEventNotifications"><value>Notificaciones de eventos de servidor</value></data>
|
||||
<data name="SchemaHierarchy_ExtendedProperties"><value>Propiedades extendidas</value></data>
|
||||
<data name="SchemaHierarchy_FileGroups"><value>Grupos de archivos</value></data>
|
||||
<data name="SchemaHierarchy_ForeignKeys"><value>Claves externas</value></data>
|
||||
<data name="SchemaHierarchy_FullTextCatalogs"><value>Catálogos de texto completo</value></data>
|
||||
<data name="SchemaHierarchy_FullTextIndexes"><value>Índices de texto completo</value></data>
|
||||
<data name="SchemaHierarchy_Functions"><value>Funciones</value></data>
|
||||
<data name="SchemaHierarchy_Indexes"><value>Índices</value></data>
|
||||
<data name="SchemaHierarchy_InlineFunctions"><value>Funciones Inline</value></data>
|
||||
<data name="SchemaHierarchy_Keys"><value>Claves</value></data>
|
||||
<data name="SchemaHierarchy_LinkedServers"><value>Servidores vinculados</value></data>
|
||||
<data name="SchemaHierarchy_LinkedServerLogins"><value>Inicios de sesión de servidor vinculado</value></data>
|
||||
<data name="SchemaHierarchy_Logins"><value>Inicios de sesión</value></data>
|
||||
<data name="SchemaHierarchy_MasterKey"><value>Clave maestra</value></data>
|
||||
<data name="SchemaHierarchy_MasterKeys"><value>Claves maestras</value></data>
|
||||
<data name="SchemaHierarchy_MessageTypes"><value>Tipos de mensaje</value></data>
|
||||
<data name="SchemaHierarchy_MultiSelectFunctions"><value>Funciones con valores de tabla</value></data>
|
||||
<data name="SchemaHierarchy_Parameters"><value>Parámetros</value></data>
|
||||
<data name="SchemaHierarchy_PartitionFunctions"><value>Funciones de partición</value></data>
|
||||
<data name="SchemaHierarchy_PartitionSchemes"><value>Esquemas de partición</value></data>
|
||||
<data name="SchemaHierarchy_Permissions"><value>Permisos</value></data>
|
||||
<data name="SchemaHierarchy_PrimaryKeys"><value>Claves principales</value></data>
|
||||
<data name="SchemaHierarchy_Programmability"><value>Programación</value></data>
|
||||
<data name="SchemaHierarchy_Queues"><value>Colas</value></data>
|
||||
<data name="SchemaHierarchy_RemoteServiceBindings"><value>Enlaces de servicio remoto</value></data>
|
||||
<data name="SchemaHierarchy_ReturnedColumns"><value>Columnas devueltos</value></data>
|
||||
<data name="SchemaHierarchy_Roles"><value>Roles</value></data>
|
||||
<data name="SchemaHierarchy_Routes"><value>Rutas</value></data>
|
||||
<data name="SchemaHierarchy_Rules"><value>Reglas</value></data>
|
||||
<data name="SchemaHierarchy_Schemas"><value>Esquemas</value></data>
|
||||
<data name="SchemaHierarchy_Security"><value>Seguridad</value></data>
|
||||
<data name="SchemaHierarchy_ServerObjects"><value>Objetos de servidor</value></data>
|
||||
<data name="SchemaHierarchy_Management"><value>Administración</value></data>
|
||||
<data name="SchemaHierarchy_ServerTriggers"><value>Desencadenadores</value></data>
|
||||
<data name="SchemaHierarchy_ServiceBroker"><value>Service Broker</value></data>
|
||||
<data name="SchemaHierarchy_Services"><value>Servicios</value></data>
|
||||
<data name="SchemaHierarchy_Signatures"><value>Firmas</value></data>
|
||||
<data name="SchemaHierarchy_LogFiles"><value>Archivos de registro</value></data>
|
||||
<data name="SchemaHierarchy_Statistics"><value>Estadísticas</value></data>
|
||||
<data name="SchemaHierarchy_Storage"><value>Almacenamiento</value></data>
|
||||
<data name="SchemaHierarchy_StoredProcedures"><value>Procedimientos almacenados</value></data>
|
||||
<data name="SchemaHierarchy_SymmetricKeys"><value>Claves simétricas</value></data>
|
||||
<data name="SchemaHierarchy_Synonyms"><value>Sinónimos</value></data>
|
||||
<data name="SchemaHierarchy_Tables"><value>Tablas</value></data>
|
||||
<data name="SchemaHierarchy_Triggers"><value>Desencadenadores</value></data>
|
||||
<data name="SchemaHierarchy_Types"><value>Tipos</value></data>
|
||||
<data name="SchemaHierarchy_UniqueKeys"><value>Claves únicas</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedDataTypes"><value>Tipos de datos definidos por el usuario</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedTypes"><value>Tipos definidos por el usuario (CLR)</value></data>
|
||||
<data name="SchemaHierarchy_Users"><value>Usuarios</value></data>
|
||||
<data name="SchemaHierarchy_Views"><value>Vistas</value></data>
|
||||
<data name="SchemaHierarchy_XmlIndexes"><value>Índices XML</value></data>
|
||||
<data name="SchemaHierarchy_XMLSchemaCollections"><value>Colecciones de esquemas XML</value></data>
|
||||
<data name="SchemaHierarchy_UserDefinedTableTypes"><value>Tipos de tablas definidos por el usuario</value></data>
|
||||
<data name="SchemaHierarchy_FilegroupFiles"><value>Archivos</value></data>
|
||||
<data name="MissingCaption"><value>Falta el título</value></data>
|
||||
<data name="SchemaHierarchy_BrokerPriorities"><value>Prioridades de Broker</value></data>
|
||||
<data name="SchemaHierarchy_CryptographicProviders"><value>Proveedores de servicios criptográficos</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseAuditSpecifications"><value>Especificaciones de auditoría de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseEncryptionKeys"><value>Claves de cifrado de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_EventSessions"><value>Sesiones de eventos</value></data>
|
||||
<data name="SchemaHierarchy_FullTextStopLists"><value>Listas de palabras irrelevantes de texto completo</value></data>
|
||||
<data name="SchemaHierarchy_ResourcePools"><value>Grupos de recursos de servidor</value></data>
|
||||
<data name="SchemaHierarchy_ServerAudits"><value>Auditorías</value></data>
|
||||
<data name="SchemaHierarchy_ServerAuditSpecifications"><value>Especificaciones de auditoría de servidor</value></data>
|
||||
<data name="SchemaHierarchy_SpatialIndexes"><value>Índices espaciales</value></data>
|
||||
<data name="SchemaHierarchy_WorkloadGroups"><value>Grupos de cargas de trabajo</value></data>
|
||||
<data name="SchemaHierarchy_SqlFiles"><value>Archivos SQL</value></data>
|
||||
<data name="SchemaHierarchy_ServerFunctions"><value>Funciones de servidor</value></data>
|
||||
<data name="SchemaHierarchy_SqlType"><value>Tipo SQL</value></data>
|
||||
<data name="SchemaHierarchy_ServerOptions"><value>Opciones de servidor</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseDiagrams"><value>Diagramas de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_SystemTables"><value>Tablas del sistema</value></data>
|
||||
<data name="SchemaHierarchy_Databases"><value>Bases de datos</value></data>
|
||||
<data name="SchemaHierarchy_SystemContracts"><value>Contratos del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemDatabases"><value>Bases de datos del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemMessageTypes"><value>Tipos de mensaje del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemQueues"><value>Colas del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemServices"><value>Servicios del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemStoredProcedures"><value>Procedimientos almacenados del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemViews"><value>Vistas del sistema</value></data>
|
||||
<data name="SchemaHierarchy_DataTierApplications"><value>Aplicaciones de capa de datos</value></data>
|
||||
<data name="SchemaHierarchy_ExtendedStoredProcedures"><value>Procedimientos almacenados extendidos</value></data>
|
||||
<data name="SchemaHierarchy_SystemAggregateFunctions"><value>Funciones de agregado</value></data>
|
||||
<data name="SchemaHierarchy_SystemApproximateNumerics"><value>Valores numéricos aproximados</value></data>
|
||||
<data name="SchemaHierarchy_SystemBinaryStrings"><value>Cadenas binarias</value></data>
|
||||
<data name="SchemaHierarchy_SystemCharacterStrings"><value>Cadenas de caracteres</value></data>
|
||||
<data name="SchemaHierarchy_SystemCLRDataTypes"><value>Tipos de datos CLR</value></data>
|
||||
<data name="SchemaHierarchy_SystemConfigurationFunctions"><value>Funciones de configuración</value></data>
|
||||
<data name="SchemaHierarchy_SystemCursorFunctions"><value>Funciones del cursor</value></data>
|
||||
<data name="SchemaHierarchy_SystemDataTypes"><value>Tipos de datos del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTime"><value>Fecha y hora</value></data>
|
||||
<data name="SchemaHierarchy_SystemDateAndTimeFunctions"><value>Funciones de fecha y hora</value></data>
|
||||
<data name="SchemaHierarchy_SystemExactNumerics"><value>Valores numéricos exactos</value></data>
|
||||
<data name="SchemaHierarchy_SystemFunctions"><value>Funciones del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemHierarchyIdFunctions"><value>Funciones de id. de jerarquía</value></data>
|
||||
<data name="SchemaHierarchy_SystemMathematicalFunctions"><value>Funciones matemáticas</value></data>
|
||||
<data name="SchemaHierarchy_SystemMetadataFunctions"><value>Funciones de metadatos</value></data>
|
||||
<data name="SchemaHierarchy_SystemOtherDataTypes"><value>Otros tipos de datos</value></data>
|
||||
<data name="SchemaHierarchy_SystemOtherFunctions"><value>Otras funciones</value></data>
|
||||
<data name="SchemaHierarchy_SystemRowsetFunctions"><value>Funciones de conjunto de filas</value></data>
|
||||
<data name="SchemaHierarchy_SystemSecurityFunctions"><value>Funciones de seguridad</value></data>
|
||||
<data name="SchemaHierarchy_SystemSpatialDataTypes"><value>Tipos de datos espaciales</value></data>
|
||||
<data name="SchemaHierarchy_SystemStringFunctions"><value>Funciones de cadena</value></data>
|
||||
<data name="SchemaHierarchy_SystemSystemStatisticalFunctions"><value>Funciones estadísticas del sistema</value></data>
|
||||
<data name="SchemaHierarchy_SystemTextAndImageFunctions"><value>Funciones de texto y de imagen</value></data>
|
||||
<data name="SchemaHierarchy_SystemUnicodeCharacterStrings"><value>Cadenas de caracteres Unicode</value></data>
|
||||
<data name="SchemaHierarchy_AggregateFunctions"><value>Funciones de agregado</value></data>
|
||||
<data name="SchemaHierarchy_ScalarValuedFunctions"><value>Funciones escalares</value></data>
|
||||
<data name="SchemaHierarchy_TableValuedFunctions"><value>Funciones con valores de tabla</value></data>
|
||||
<data name="SchemaHierarchy_SystemExtendedStoredProcedures"><value>Procedimientos almacenados extendidos del sistema</value></data>
|
||||
<data name="SchemaHierarchy_BuiltInType"><value>Tipos integrados</value></data>
|
||||
<data name="SchemaHierarchy_BuiltInServerRole"><value>Roles de servidor integrados</value></data>
|
||||
<data name="SchemaHierarchy_UserWithPassword"><value>Usuario con contraseña</value></data>
|
||||
<data name="SchemaHierarchy_SearchPropertyList"><value>Lista de propiedades de búsqueda</value></data>
|
||||
<data name="SchemaHierarchy_SecurityPolicies"><value>Directivas de seguridad</value></data>
|
||||
<data name="SchemaHierarchy_SecurityPredicates"><value>Predicados de seguridad</value></data>
|
||||
<data name="SchemaHierarchy_ServerRole"><value>Rol de servidor</value></data>
|
||||
<data name="SchemaHierarchy_SearchPropertyLists"><value>Listas de propiedades de búsqueda</value></data>
|
||||
<data name="SchemaHierarchy_ColumnStoreIndexes"><value>Índices de almacenamiento de columnas</value></data>
|
||||
<data name="SchemaHierarchy_TableTypeIndexes"><value>Índices de tipo de tabla</value></data>
|
||||
<data name="SchemaHierarchy_SelectiveXmlIndexes"><value>Índices XML selectivos</value></data>
|
||||
<data name="SchemaHierarchy_XmlNamespaces"><value>Espacios de nombres XML</value></data>
|
||||
<data name="SchemaHierarchy_XmlTypedPromotedPaths"><value>Rutas de acceso promovidas de tipo XML</value></data>
|
||||
<data name="SchemaHierarchy_SqlTypedPromotedPaths"><value>Rutas de acceso promovidas de tipo T-SQL</value></data>
|
||||
<data name="SchemaHierarchy_DatabaseScopedCredentials"><value>Credenciales de ámbito de base de datos</value></data>
|
||||
<data name="SchemaHierarchy_ExternalDataSources"><value>Orígenes de datos externos</value></data>
|
||||
<data name="SchemaHierarchy_ExternalFileFormats"><value>Formatos de archivo externo</value></data>
|
||||
<data name="SchemaHierarchy_ExternalResources"><value>Recursos externos</value></data>
|
||||
<data name="SchemaHierarchy_ExternalTables"><value>Tablas externas</value></data>
|
||||
<data name="SchemaHierarchy_AlwaysEncryptedKeys"><value>Siempre claves cifradas</value></data>
|
||||
<data name="SchemaHierarchy_ColumnMasterKeys"><value>Claves maestras de columna</value></data>
|
||||
<data name="SchemaHierarchy_ColumnEncryptionKeys"><value>Claves de cifrado de columna</value></data>
|
||||
<data name="SchemaHierarchy_Server"><value>Servidor</value></data>
|
||||
<data name="ScriptingParams_ConnectionString_Property_Invalid"><value>Error interpretando la propiedad ScriptingParams.ConnectionString</value></data>
|
||||
<data name="ScriptingParams_FilePath_Property_Invalid"><value>El directorio especificado en la propiedad ScriptingParams.FilePath no es válido</value></data>
|
||||
<data name="ScriptingListObjectsCompleteParams_ConnectionString_Property_Invalid"><value>Error interpretando la propiedad ScriptingListObjectsCompleteParams.ConnectionString</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterLabelFormatString"><value>{0} ({1}, {2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterNoDefaultLabel"><value>Sin valores predeterminados</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputLabel"><value>Entrada</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputOutputLabel"><value>Entrada/salida</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputReadOnlyLabel"><value>Entrada/solo lectura</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterInputOutputReadOnlyLabel"><value>Entrada/salida/solo lectura</value></data>
|
||||
<data name="SchemaHierarchy_SubroutineParameterDefaultLabel"><value>Predeterminado</value></data>
|
||||
<data name="SchemaHierarchy_NullColumn_Label"><value>NULL</value></data>
|
||||
<data name="SchemaHierarchy_NotNullColumn_Label"><value>no es NULL</value></data>
|
||||
<data name="SchemaHierarchy_UDDTLabelWithType"><value>{0} ({1}, {2})</value></data>
|
||||
<data name="SchemaHierarchy_UDDTLabelWithoutType"><value>{0} ({1})</value></data>
|
||||
<data name="SchemaHierarchy_ComputedColumnLabelWithType"><value>{0} ({1}calculado, {2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_ComputedColumnLabelWithoutType"><value>{0} ({1}calculado)</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithoutType"><value>{0} (Conjunto de columnas, {1})</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithType"><value>{0} (Conjunto de columnas, {1}{2}, {3})</value></data>
|
||||
<data name="SchemaHierarchy_ColumnSetLabelWithTypeAndKeyString"><value>{0} (Conjunto de columnas, {1}, {2}, {3})</value></data>
|
||||
<data name="UniqueIndex_LabelPart"><value>Único</value></data>
|
||||
<data name="NonUniqueIndex_LabelPart"><value>No único</value></data>
|
||||
<data name="ClusteredIndex_LabelPart"><value>Clúster</value></data>
|
||||
<data name="NonClusteredIndex_LabelPart"><value>No en clúster</value></data>
|
||||
<data name="History_LabelPart"><value>Historial</value></data>
|
||||
<data name="SystemVersioned_LabelPart"><value>Con versión del sistema</value></data>
|
||||
<data name="unavailable"><value>No disponible</value></data>
|
||||
<data name="filegroup_dialog_defaultFilegroup"><value>Grupo de archivos predeterminado: {0}</value></data>
|
||||
<data name="filegroup_dialog_title"><value>Grupo de archivos nuevo para: {0}</value></data>
|
||||
<data name="filegroups_default"><value>Predeterminado</value></data>
|
||||
<data name="filegroups_files"><value>Archivos</value></data>
|
||||
<data name="filegroups_name"><value>Nombre</value></data>
|
||||
<data name="filegroups_readonly"><value>Solo lectura</value></data>
|
||||
<data name="general_autogrowth"><value>Crecimiento automático / tamaño máximo</value></data>
|
||||
<data name="general_builderText"><value>...</value></data>
|
||||
<data name="general_default"><value><predeterminado></value></data>
|
||||
<data name="general_fileGroup"><value>Grupo de archivos</value></data>
|
||||
<data name="general_fileName"><value>Nombre lógico</value></data>
|
||||
<data name="general_fileType"><value>Tipo de archivo</value></data>
|
||||
<data name="general_initialSize"><value>Tamaño inicial (MB)</value></data>
|
||||
<data name="general_newFilegroup"><value><nuevo grupo de archivos></value></data>
|
||||
<data name="general_path"><value>Ruta de acceso</value></data>
|
||||
<data name="general_physicalFileName"><value>Nombre de archivo</value></data>
|
||||
<data name="general_rawDevice"><value><dispositivo sin formato></value></data>
|
||||
<data name="general_recoveryModel_bulkLogged"><value>Registro masivo</value></data>
|
||||
<data name="general_recoveryModel_full"><value>Completo</value></data>
|
||||
<data name="general_recoveryModel_simple"><value>Simple</value></data>
|
||||
<data name="general_titleSearchOwner"><value>Seleccionar propietario de base de datos</value></data>
|
||||
<data name="prototype_autogrowth_disabled"><value>Ninguno</value></data>
|
||||
<data name="prototype_autogrowth_restrictedGrowthByMB"><value>Por {0} MB, limitado a {1} MB</value></data>
|
||||
<data name="prototype_autogrowth_restrictedGrowthByPercent"><value>Por {0} porciento, limitado a {1} MB</value></data>
|
||||
<data name="prototype_autogrowth_unrestrictedGrowthByMB"><value>Por {0} MB, sin límite</value></data>
|
||||
<data name="prototype_autogrowth_unrestrictedGrowthByPercent"><value>Por {0} porciento, sin límite</value></data>
|
||||
<data name="prototype_autogrowth_unlimitedfilestream"><value>Sin límite</value></data>
|
||||
<data name="prototype_autogrowth_limitedfilestream"><value>Limitado a {0} MB</value></data>
|
||||
<data name="prototype_db_category_automatic"><value>Automático</value></data>
|
||||
<data name="prototype_db_category_servicebroker"><value>Service Broker</value></data>
|
||||
<data name="prototype_db_category_collation"><value>Intercalación</value></data>
|
||||
<data name="prototype_db_category_cursor"><value>Cursor</value></data>
|
||||
<data name="prototype_db_category_misc"><value>Varios</value></data>
|
||||
<data name="prototype_db_category_recovery"><value>Recuperación</value></data>
|
||||
<data name="prototype_db_category_state"><value>Estado</value></data>
|
||||
<data name="prototype_db_prop_ansiNullDefault"><value>ANSI NULL predeterminado</value></data>
|
||||
<data name="prototype_db_prop_ansiNulls"><value>ANSI NULLS habilitados</value></data>
|
||||
<data name="prototype_db_prop_ansiPadding"><value>Relleno ANSI habilitado</value></data>
|
||||
<data name="prototype_db_prop_ansiWarnings"><value>Advertencias ANSI habilitadas</value></data>
|
||||
<data name="prototype_db_prop_arithabort"><value>Anulación aritmética habilitada</value></data>
|
||||
<data name="prototype_db_prop_autoClose"><value>Cierre automático</value></data>
|
||||
<data name="prototype_db_prop_autoCreateStatistics"><value>Crear estadísticas automáticamente</value></data>
|
||||
<data name="prototype_db_prop_autoShrink"><value>Reducir automáticamente</value></data>
|
||||
<data name="prototype_db_prop_autoUpdateStatistics"><value>Actualizar estadísticas automáticamente</value></data>
|
||||
<data name="prototype_db_prop_autoUpdateStatisticsAsync"><value>Actualizar estadísticas automáticamente de forma asincrónica</value></data>
|
||||
<data name="prototype_db_prop_caseSensitive"><value>Sensible a mayúsculas y minúsculas</value></data>
|
||||
<data name="prototype_db_prop_closeCursorOnCommit"><value>Cierre del cursor al confirmar habilitado</value></data>
|
||||
<data name="prototype_db_prop_collation"><value>Intercalación</value></data>
|
||||
<data name="prototype_db_prop_concatNullYieldsNull"><value>Concatenar valores NULL produce NULL</value></data>
|
||||
<data name="prototype_db_prop_databaseCompatibilityLevel"><value>Nivel de compatibilidad de base de datos</value></data>
|
||||
<data name="prototype_db_prop_databaseState"><value>Estado de la base de datos</value></data>
|
||||
<data name="prototype_db_prop_defaultCursor"><value>Cursor predeterminado</value></data>
|
||||
<data name="prototype_db_prop_fullTextIndexing"><value>Índice de texto completo habilitado</value></data>
|
||||
<data name="prototype_db_prop_numericRoundAbort"><value>Anular redondeo numérico</value></data>
|
||||
<data name="prototype_db_prop_pageVerify"><value>Comprobación de página</value></data>
|
||||
<data name="prototype_db_prop_quotedIdentifier"><value>Identificadores entre comillas habilitados</value></data>
|
||||
<data name="prototype_db_prop_readOnly"><value>Base de datos de solo lectura</value></data>
|
||||
<data name="prototype_db_prop_recursiveTriggers"><value>Desencadenadores recursivos habilitados</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess"><value>Restringir acceso</value></data>
|
||||
<data name="prototype_db_prop_selectIntoBulkCopy"><value>Select Into/Bulk Copy</value></data>
|
||||
<data name="prototype_db_prop_honorBrokerPriority"><value>Asignar prioridad de agente</value></data>
|
||||
<data name="prototype_db_prop_serviceBrokerGuid"><value>Identificador de Service Broker</value></data>
|
||||
<data name="prototype_db_prop_brokerEnabled"><value>Broker habilitado</value></data>
|
||||
<data name="prototype_db_prop_truncateLogOnCheckpoint"><value>Truncar registro en el punto de control</value></data>
|
||||
<data name="prototype_db_prop_dbChaining"><value>Encadenamiento de propiedad entre bases de datos habilitado</value></data>
|
||||
<data name="prototype_db_prop_trustworthy"><value>De confianza</value></data>
|
||||
<data name="prototype_db_prop_dateCorrelationOptimization"><value>Optimización de correlación de fechas Enabledprototype_db_prop_parameterization = Parameterization</value></data>
|
||||
<data name="prototype_db_prop_parameterization_value_forced"><value>Forzado</value></data>
|
||||
<data name="prototype_db_prop_parameterization_value_simple"><value>Simple</value></data>
|
||||
<data name="prototype_file_dataFile"><value>Datos de ROWS</value></data>
|
||||
<data name="prototype_file_logFile"><value>LOG</value></data>
|
||||
<data name="prototype_file_filestreamFile"><value>Datos de FILESTREAM</value></data>
|
||||
<data name="prototype_file_noFileGroup"><value>No aplicable</value></data>
|
||||
<data name="prototype_file_defaultpathstring"><value><ruta predeterminada></value></data>
|
||||
<data name="title_openConnectionsMustBeClosed"><value>Conexiones abiertas</value></data>
|
||||
<data name="warning_openConnectionsMustBeClosed"><value>Para cambiar las propiedades de la base de datos, SQL Server debe cerrar todas las otras conexiones a la base de datos. ¿Seguro que desea cambiar las propiedades y cerrar todas las otras conexiones?</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_autoClosed"><value>AUTO_CLOSED</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_emergency"><value>EMERGENCY</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_inaccessible"><value>INACCESSIBLE</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_normal"><value>NORMAL</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_offline"><value>OFFLINE</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_recovering"><value>RECOVERING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_recoveryPending"><value>RECOVERY PENDING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_restoring"><value>RESTORING</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_shutdown"><value>SHUTDOWN</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_standby"><value>STANDBY</value></data>
|
||||
<data name="prototype_db_prop_databaseState_value_suspect"><value>SUSPECT</value></data>
|
||||
<data name="prototype_db_prop_defaultCursor_value_global"><value>GLOBAL</value></data>
|
||||
<data name="prototype_db_prop_defaultCursor_value_local"><value>LOCAL</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_multiple"><value>MULTI_USER</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_restricted"><value>RESTRICTED_USER</value></data>
|
||||
<data name="prototype_db_prop_restrictAccess_value_single"><value>SINGLE_USER</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_checksum"><value>CHECKSUM</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_none"><value>NONE</value></data>
|
||||
<data name="prototype_db_prop_pageVerify_value_tornPageDetection"><value>TORN_PAGE_DETECTION</value></data>
|
||||
<data name="prototype_db_prop_varDecimalEnabled"><value>Formato de almacenamiento VarDecimal habilitado</value></data>
|
||||
<data name="compatibilityLevel_katmai"><value>SQL Server 2008 (100)</value></data>
|
||||
<data name="prototype_db_prop_encryptionEnabled"><value>Cifrado habilitado</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_off"><value>OFF</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_on"><value>ON</value></data>
|
||||
<data name="prototype_db_prop_databasescopedconfig_value_primary"><value>PRIMARY</value></data>
|
||||
<data name="error_db_prop_invalidleadingColumns"><value>Para la directiva de distribución HASH, el número de columnas iniciales hash es opcional pero debe de ser entre 1 y 16 columnas</value></data>
|
||||
<data name="compatibilityLevel_denali"><value>SQL Server 2012 (110)</value></data>
|
||||
<data name="compatibilityLevel_sql14"><value>SQL Server 2014 (120)</value></data>
|
||||
<data name="compatibilityLevel_sql15"><value>SQL Server 2016 (130)</value></data>
|
||||
<data name="compatibilityLevel_sqlvNext"><value>SQL Server vNext (140)</value></data>
|
||||
<data name="general_containmentType_None"><value>Ninguno</value></data>
|
||||
<data name="general_containmentType_Partial"><value>Parcial</value></data>
|
||||
<data name="filegroups_filestreamFiles"><value>Archivos FILESTREAM</value></data>
|
||||
<data name="prototype_file_noApplicableFileGroup"><value>Grupo de archivos no aplicable</value></data>
|
||||
<data name="DatabaseNotAccessible"><value>La base de datos {0} no es accesible.</value></data>
|
||||
<data name="QueryServiceResultSetHasNoResults"><value>La consulta no devolvió resultados</value></data>
|
||||
<data name="QueryServiceResultSetTooLarge"><value>El conjunto de resultados contiene demasiada filas para cargarlo de forma segura</value></data>
|
||||
<data name="prototype_db_prop_parameterization"><value>Parametrización</value></data>
|
||||
<data name="ConflictWithNoRecovery"><value>No se permite restaurar una copia de seguridad con la opción NORECOVERY</value></data>
|
||||
<data name="InvalidPathForDatabaseFile"><value>Ruta de archivo no válida: '{0}'</value></data>
|
||||
<data name="Log"><value>Registro</value></data>
|
||||
<data name="RestorePlanFailed"><value>No se pudo crear un plan de restauraciones</value></data>
|
||||
<data name="RestoreNotSupported"><value>No se admite restaurar la base de datos</value></data>
|
||||
<data name="RestoreTaskName"><value>Restaurar base de datos</value></data>
|
||||
<data name="RestoreCopyOnly"><value>(Copiar solamente)</value></data>
|
||||
<data name="RestoreBackupSetComponent"><value>Componente</value></data>
|
||||
<data name="RestoreBackupSetType"><value>Tipo</value></data>
|
||||
<data name="RestoreBackupSetServer"><value>Servidor</value></data>
|
||||
<data name="RestoreBackupSetDatabase"><value>Base de datos</value></data>
|
||||
<data name="RestoreBackupSetPosition"><value>Posición</value></data>
|
||||
<data name="RestoreBackupSetFirstLsn"><value>Primer LSN</value></data>
|
||||
<data name="RestoreBackupSetLastLsn"><value>Último LSN</value></data>
|
||||
<data name="RestoreBackupSetCheckpointLsn"><value>Checkpoint LSN</value></data>
|
||||
<data name="RestoreBackupSetFullLsn"><value>LSN completo</value></data>
|
||||
<data name="RestoreBackupSetStartDate"><value>Fecha de inicio</value></data>
|
||||
<data name="RestoreBackupSetFinishDate"><value>Fecha de finalización</value></data>
|
||||
<data name="RestoreBackupSetSize"><value>Tamaño</value></data>
|
||||
<data name="RestoreBackupSetUserName"><value>Nombre del usuario</value></data>
|
||||
<data name="RestoreBackupSetExpiration"><value>Expiración</value></data>
|
||||
<data name="RestoreBackupSetName"><value>Nombre</value></data>
|
||||
<data name="TheLastBackupTaken"><value>La última copia de seguridad tomada ({0})</value></data>
|
||||
<data name="BackupTaskName"><value>Copia de seguridad de la base de datos</value></data>
|
||||
<data name="TaskInProgress"><value>En curso</value></data>
|
||||
<data name="TaskCompleted"><value>Completado</value></data>
|
||||
<data name="ScriptTaskName"><value>scripting </value></data>
|
||||
<data name="ProfilerConnectionNotFound"><value>Conexión no encontrada</value></data>
|
||||
<data name="BackupPathIsFolderError"><value>El nombre del archivo especificado es un nombre de directorio: {0}</value></data>
|
||||
<data name="InvalidBackupPathError"><value>No se puede verificar la existencia de la ubicación del archivo de copia de seguridad: {0}</value></data>
|
||||
<data name="InvalidPathError"><value>No se puede acceder a la ruta de acceso especificada en el servidor: {0}</value></data>
|
||||
<data name="NoBackupsetsToRestore"><value>Ningún backupset seleccionado para ser restaurado</value></data>
|
||||
<data name="NeverBackedUp"><value>Nunca</value></data>
|
||||
<data name="AzureSqlDbEdition"><value>Azure SQL Database </value></data>
|
||||
<data name="AzureSqlDwEdition"><value>Azure SQL Data Warehouse</value></data>
|
||||
<data name="AzureSqlStretchEdition"><value>Azure SQL Stretch Database</value></data>
|
||||
<data name="Error_InvalidDirectoryName"><value>La ruta de acceso [{0}] no es un directorio válido</value></data>
|
||||
<data name="Error_ExistingDirectoryName"><value>Ya existe un archivo {1} en el directorio '{0}'</value></data>
|
||||
<data name="EditDataValueTooLarge"><value>El valor {0} es muy grande para el tipo de columna {1} </value></data>
|
||||
</root>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user