mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-17 02:51:45 -05:00
Address warnings and (some) nullables (#2013)
This commit is contained in:
@@ -413,22 +413,19 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource.Kusto
|
|||||||
{
|
{
|
||||||
var returnList = new List<DataSourceObjectMetadata>();
|
var returnList = new List<DataSourceObjectMetadata>();
|
||||||
|
|
||||||
if (_folderMetadata.ContainsKey(key))
|
if (_folderMetadata.TryGetValue(key, out IEnumerable<FolderMetadata>? folderMetadata))
|
||||||
{
|
{
|
||||||
returnList.AddRange(_folderMetadata[key]
|
returnList.AddRange(folderMetadata.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
||||||
.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tableMetadata.ContainsKey(key))
|
if (_tableMetadata.TryGetValue(key, out IEnumerable<TableMetadata>? tableMetadata))
|
||||||
{
|
{
|
||||||
returnList.AddRange(_tableMetadata[key]
|
returnList.AddRange(tableMetadata.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
||||||
.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_functionMetadata.ContainsKey(key))
|
if (_functionMetadata.TryGetValue(key, out IEnumerable<FunctionMetadata>? functionMetadata))
|
||||||
{
|
{
|
||||||
returnList.AddRange(_functionMetadata[key]
|
returnList.AddRange(functionMetadata.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
||||||
.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnList;
|
return returnList;
|
||||||
@@ -515,16 +512,15 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource.Kusto
|
|||||||
private IEnumerable<DataSourceObjectMetadata> GetTableSchema(TableMetadata tableMetadata)
|
private IEnumerable<DataSourceObjectMetadata> GetTableSchema(TableMetadata tableMetadata)
|
||||||
{
|
{
|
||||||
var key = GenerateMetadataKey(tableMetadata.DatabaseName, tableMetadata.Name);
|
var key = GenerateMetadataKey(tableMetadata.DatabaseName, tableMetadata.Name);
|
||||||
if (_columnMetadata.ContainsKey(key))
|
if (_columnMetadata.TryGetValue(key, out IEnumerable<DataSourceObjectMetadata>? metadata))
|
||||||
{
|
{
|
||||||
return _columnMetadata[key];
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTableSchema(tableMetadata);
|
SetTableSchema(tableMetadata);
|
||||||
|
|
||||||
return _columnMetadata.ContainsKey(key)
|
return _columnMetadata.TryGetValue(key, out IEnumerable<DataSourceObjectMetadata>? columnMetadata)
|
||||||
? _columnMetadata[key]
|
? columnMetadata : Enumerable.Empty<DataSourceObjectMetadata>();
|
||||||
: Enumerable.Empty<DataSourceObjectMetadata>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetTableSchema(TableMetadata tableMetadata)
|
private void SetTableSchema(TableMetadata tableMetadata)
|
||||||
@@ -683,9 +679,9 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource.Kusto
|
|||||||
Urn = $"{tableKey}.{table.TableName}"
|
Urn = $"{tableKey}.{table.TableName}"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tableFolders.ContainsKey(tableKey.ToString()))
|
if (tableFolders.TryGetValue(tableKey.ToString(), out List<TableMetadata>? tableMetadataList))
|
||||||
{
|
{
|
||||||
tableFolders[tableKey.ToString()].Add(tableMetadata);
|
tableMetadataList.Add(tableMetadata);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using Microsoft.Kusto.ServiceLayer.DataSource.Metadata;
|
|||||||
|
|
||||||
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
namespace Microsoft.Kusto.ServiceLayer.DataSource
|
||||||
{
|
{
|
||||||
public static class KustoQueryUtils
|
public static partial 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.
|
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.
|
||||||
|
|
||||||
@@ -30,7 +30,6 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
string result = name;
|
string result = name;
|
||||||
Regex rx = new Regex("[^_a-zA-Z0-9]");
|
|
||||||
string [] kustoKeywordList = {"and", "anomalychart", "areachart", "asc", "barchart", "between", "bool", "boolean", "by",
|
string [] kustoKeywordList = {"and", "anomalychart", "areachart", "asc", "barchart", "between", "bool", "boolean", "by",
|
||||||
"columnchart", "consume", "contains", "containscs", "count", "date", "datetime", "default", "desc", "distinct",
|
"columnchart", "consume", "contains", "containscs", "count", "date", "datetime", "default", "desc", "distinct",
|
||||||
"double", "dynamic", "endswith", "evaluate", "extend", "false", "filter", "find", "first", "flags", "float",
|
"double", "dynamic", "endswith", "evaluate", "extend", "false", "filter", "find", "first", "flags", "float",
|
||||||
@@ -41,7 +40,7 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
"take", "time", "timechart", "timeline", "timepivot", "timespan", "to", "top", "toscalar", "true", "union",
|
"take", "time", "timechart", "timeline", "timepivot", "timespan", "to", "top", "toscalar", "true", "union",
|
||||||
"unstacked", "viewers", "where", "withsource"}; // add more keywords here
|
"unstacked", "viewers", "where", "withsource"}; // add more keywords here
|
||||||
|
|
||||||
var escapeName = rx.IsMatch(name) || kustoKeywordList.Any(name.Contains) || alwaysEscape;
|
var escapeName = GetNameRegex().IsMatch(name) || kustoKeywordList.Any(name.Contains) || alwaysEscape;
|
||||||
if (escapeName)
|
if (escapeName)
|
||||||
{
|
{
|
||||||
if (name.IndexOf('"') > -1)
|
if (name.IndexOf('"') > -1)
|
||||||
@@ -79,14 +78,14 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
public static void SafeAdd<T>(this Dictionary<string, Dictionary<string, T>> dictionary, string key,
|
public static void SafeAdd<T>(this Dictionary<string, Dictionary<string, T>> dictionary, string key,
|
||||||
T metadata) where T : DataSourceObjectMetadata
|
T metadata) where T : DataSourceObjectMetadata
|
||||||
{
|
{
|
||||||
if (dictionary.ContainsKey(key))
|
if (dictionary.TryGetValue(key, out Dictionary<string, T>? metadataCollection))
|
||||||
{
|
{
|
||||||
if (dictionary[key].ContainsKey(metadata.Name))
|
if (metadataCollection.ContainsKey(metadata.Name))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary[key].Add(metadata.Name, metadata);
|
metadataCollection.Add(metadata.Name, metadata);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -97,14 +96,14 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
public static void SafeAdd<T>(this Dictionary<string, SortedDictionary<string, DataSourceObjectMetadata>> dictionary, string key,
|
public static void SafeAdd<T>(this Dictionary<string, SortedDictionary<string, DataSourceObjectMetadata>> dictionary, string key,
|
||||||
T node) where T : DataSourceObjectMetadata
|
T node) where T : DataSourceObjectMetadata
|
||||||
{
|
{
|
||||||
if (dictionary.ContainsKey(key))
|
if (dictionary.TryGetValue(key, out SortedDictionary<string, DataSourceObjectMetadata>? metadataCollection))
|
||||||
{
|
{
|
||||||
if (dictionary[key].ContainsKey(node.PrettyName))
|
if (metadataCollection.ContainsKey(node.PrettyName))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary[key].Add(node.PrettyName, node);
|
metadataCollection.Add(node.PrettyName, node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -123,9 +122,9 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
public static void AddRange<T>(this ConcurrentDictionary<string, IEnumerable<T>> dictionary, string key,
|
public static void AddRange<T>(this ConcurrentDictionary<string, IEnumerable<T>> dictionary, string key,
|
||||||
List<T> metadatas) where T : DataSourceObjectMetadata
|
List<T> metadatas) where T : DataSourceObjectMetadata
|
||||||
{
|
{
|
||||||
if (dictionary.ContainsKey(key))
|
if (dictionary.TryGetValue(key, out IEnumerable<T>? value))
|
||||||
{
|
{
|
||||||
metadatas.AddRange(dictionary[key]);
|
metadatas.AddRange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary[key] = metadatas.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase).ToList();
|
dictionary[key] = metadatas.OrderBy(x => x.PrettyName, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
@@ -133,11 +132,16 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource
|
|||||||
|
|
||||||
public static string ParseDatabaseName(string databaseName)
|
public static string ParseDatabaseName(string databaseName)
|
||||||
{
|
{
|
||||||
var regex = new Regex(@"(?<=\().+?(?=\))");
|
var regex = GetDatabaseNameRegex();
|
||||||
|
|
||||||
return regex.IsMatch(databaseName)
|
return regex.IsMatch(databaseName)
|
||||||
? regex.Match(databaseName).Value
|
? regex.Match(databaseName).Value
|
||||||
: databaseName;
|
: databaseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("(?<=\\().+?(?=\\))")]
|
||||||
|
private static partial Regex GetDatabaseNameRegex();
|
||||||
|
[GeneratedRegex("[^_a-zA-Z0-9]")]
|
||||||
|
private static partial Regex GetNameRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using Microsoft.Kusto.ServiceLayer.Workspace.Contracts;
|
|||||||
|
|
||||||
namespace Microsoft.Kusto.ServiceLayer.DataSource.Monitor
|
namespace Microsoft.Kusto.ServiceLayer.DataSource.Monitor
|
||||||
{
|
{
|
||||||
public class MonitorDataSource : DataSourceBase
|
public partial class MonitorDataSource : DataSourceBase
|
||||||
{
|
{
|
||||||
private readonly MonitorClient _monitorClient;
|
private readonly MonitorClient _monitorClient;
|
||||||
private readonly IntellisenseClientBase _intellisenseClient;
|
private readonly IntellisenseClientBase _intellisenseClient;
|
||||||
@@ -158,7 +158,7 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource.Monitor
|
|||||||
|
|
||||||
private string ParseWorkspaceId(string workspace)
|
private string ParseWorkspaceId(string workspace)
|
||||||
{
|
{
|
||||||
var regex = new Regex(@"(?<=\().+?(?=\))");
|
var regex = GetWorkspaceIdRegex();
|
||||||
|
|
||||||
return regex.IsMatch(workspace)
|
return regex.IsMatch(workspace)
|
||||||
? regex.Match(workspace).Value
|
? regex.Match(workspace).Value
|
||||||
@@ -227,5 +227,8 @@ namespace Microsoft.Kusto.ServiceLayer.DataSource.Monitor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("(?<=\\().+?(?=\\))")]
|
||||||
|
private static partial Regex GetWorkspaceIdRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,11 +198,9 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
lock (this._bindingContextLock)
|
lock (this._bindingContextLock)
|
||||||
{
|
{
|
||||||
if (this.BindingContextMap.ContainsKey(key))
|
if (this.BindingContextMap.TryGetValue(key, out IBindingContext? bindingContext))
|
||||||
{
|
{
|
||||||
// disconnect existing connection
|
// disconnect existing connection
|
||||||
var bindingContext = this.BindingContextMap[key];
|
|
||||||
|
|
||||||
// remove key from the map
|
// remove key from the map
|
||||||
this.BindingContextMap.Remove(key);
|
this.BindingContextMap.Remove(key);
|
||||||
this.BindingContextTasks.Remove(bindingContext);
|
this.BindingContextTasks.Remove(bindingContext);
|
||||||
|
|||||||
@@ -1011,13 +1011,13 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uri"></param>
|
/// <param name="uri"></param>
|
||||||
/// <param name="createIfNotExists">Creates a new instance if one doesn't exist</param>
|
/// <param name="createIfNotExists">Creates a new instance if one doesn't exist</param>
|
||||||
internal ScriptParseInfo GetScriptParseInfo(string uri, bool createIfNotExists = false)
|
internal ScriptParseInfo? GetScriptParseInfo(string uri, bool createIfNotExists = false)
|
||||||
{
|
{
|
||||||
lock (this.parseMapLock)
|
lock (this.parseMapLock)
|
||||||
{
|
{
|
||||||
if (this.ScriptParseInfoMap.ContainsKey(uri))
|
if (this.ScriptParseInfoMap.TryGetValue(uri, out ScriptParseInfo? scriptParseInfo))
|
||||||
{
|
{
|
||||||
return this.ScriptParseInfoMap[uri];
|
return scriptParseInfo;
|
||||||
}
|
}
|
||||||
else if (createIfNotExists)
|
else if (createIfNotExists)
|
||||||
{
|
{
|
||||||
@@ -1091,7 +1091,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there is a single statement on the line, track it so that we can return it regardless of where the user's cursor is
|
// If there is a single statement on the line, track it so that we can return it regardless of where the user's cursor is
|
||||||
SqlStatement lineStatement = null;
|
SqlStatement? lineStatement = null;
|
||||||
bool? lineHasSingleStatement = null;
|
bool? lineHasSingleStatement = null;
|
||||||
|
|
||||||
// check if the batch matches parameters
|
// check if the batch matches parameters
|
||||||
@@ -1125,7 +1125,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
|
|||||||
|
|
||||||
if (lineHasSingleStatement == true)
|
if (lineHasSingleStatement == true)
|
||||||
{
|
{
|
||||||
return lineStatement.Sql;
|
return lineStatement?.Sql ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<DebugType>portable</DebugType>
|
<DebugType>portable</DebugType>
|
||||||
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- False alerts, disabled due to issue: https://github.com/dotnet/roslyn/issues/65850 -->
|
||||||
<NoWarn>$(NoWarn);SYSLIB1045;CA1311;CA1854</NoWarn>
|
<NoWarn>$(NoWarn);CS8795</NoWarn>
|
||||||
<AssemblyTitle>SqlTools Kusto Editor Services Host Protocol Library</AssemblyTitle>
|
<AssemblyTitle>SqlTools Kusto Editor Services Host Protocol Library</AssemblyTitle>
|
||||||
<Description>Provides message types and client/server APIs for the SqlTools Kusto Editor Services JSON protocol.</Description>
|
<Description>Provides message types and client/server APIs for the SqlTools Kusto Editor Services JSON protocol.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using Microsoft.Kusto.ServiceLayer.QueryExecution.Contracts;
|
using Microsoft.Kusto.ServiceLayer.QueryExecution.Contracts;
|
||||||
using Microsoft.Kusto.ServiceLayer.QueryExecution.DataStorage;
|
using Microsoft.Kusto.ServiceLayer.QueryExecution.DataStorage;
|
||||||
using Microsoft.Kusto.ServiceLayer.Utility;
|
using Microsoft.Kusto.ServiceLayer.Utility;
|
||||||
@@ -24,7 +26,7 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
/// Class that represents a resultset the was generated from a query. Contains logic for
|
/// Class that represents a resultset the was generated from a query. Contains logic for
|
||||||
/// storing and retrieving results. Is contained by a Batch class.
|
/// storing and retrieving results. Is contained by a Batch class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ResultSet : IDisposable
|
public partial class ResultSet : IDisposable
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
|
|
||||||
@@ -343,7 +345,7 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
// Verify the request hasn't been cancelled
|
// Verify the request hasn't been cancelled
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
var dataReader = new StorageDataReader(dbDataReader);
|
||||||
|
|
||||||
// Open a writer for the file
|
// Open a writer for the file
|
||||||
//
|
//
|
||||||
@@ -478,7 +480,7 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the new task
|
// Create the new task
|
||||||
Task saveAsTask = new Task(async () =>
|
var saveAsTask = new Task(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -602,7 +604,7 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
//
|
//
|
||||||
sendResultsSemphore.Wait();
|
sendResultsSemphore.Wait();
|
||||||
|
|
||||||
ResultSet currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
var currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
||||||
if (LastUpdatedSummary == null) // We need to send results available message.
|
if (LastUpdatedSummary == null) // We need to send results available message.
|
||||||
{
|
{
|
||||||
// Fire off results Available task and await it
|
// Fire off results Available task and await it
|
||||||
@@ -677,13 +679,12 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
{
|
{
|
||||||
if (Columns?.Length > 0 && RowCount != 0)
|
if (Columns?.Length > 0 && RowCount != 0)
|
||||||
{
|
{
|
||||||
Regex regex = new Regex(@"({.*?})");
|
|
||||||
var row = GetRow(0);
|
var row = GetRow(0);
|
||||||
for (int i = 0; i < Columns.Length; i++)
|
for (int i = 0; i < Columns.Length; i++)
|
||||||
{
|
{
|
||||||
if (Columns[i].DataTypeName.Equals("nvarchar"))
|
if (Columns[i].DataTypeName.Equals("nvarchar"))
|
||||||
{
|
{
|
||||||
if (regex.IsMatch(row[i].DisplayValue))
|
if (GetJsonRegex().IsMatch(row[i].DisplayValue))
|
||||||
{
|
{
|
||||||
Columns[i].IsJson = true;
|
Columns[i].IsJson = true;
|
||||||
}
|
}
|
||||||
@@ -726,7 +727,7 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
// Returning false from .ReadAsync means there aren't any rows.
|
// Returning false from .ReadAsync means there aren't any rows.
|
||||||
|
|
||||||
// Create a storage data reader, read it, make sure there were results
|
// Create a storage data reader, read it, make sure there were results
|
||||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
var dataReader = new StorageDataReader(dbDataReader);
|
||||||
if (!await dataReader.ReadAsync(CancellationToken.None))
|
if (!await dataReader.ReadAsync(CancellationToken.None))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
||||||
@@ -742,6 +743,9 @@ namespace Microsoft.Kusto.ServiceLayer.QueryExecution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("({.*?})")]
|
||||||
|
private static partial Regex GetJsonRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace Microsoft.Kusto.ServiceLayer.Scripting
|
|||||||
// Leaving the server name blank will automatically match whatever the server SMO is running against.
|
// Leaving the server name blank will automatically match whatever the server SMO is running against.
|
||||||
string urn = string.Format(
|
string urn = string.Format(
|
||||||
"Server[@Name='{0}']/Database[@Name='{1}']/{2}[@Name='{3}' {4}]",
|
"Server[@Name='{0}']/Database[@Name='{1}']/{2}[@Name='{3}' {4}]",
|
||||||
server.ToUpper(),
|
server.ToUpper(System.Globalization.CultureInfo.InvariantCulture),
|
||||||
Urn.EscapeString(database),
|
Urn.EscapeString(database),
|
||||||
scriptingObject.Type,
|
scriptingObject.Type,
|
||||||
Urn.EscapeString(scriptingObject.Name),
|
Urn.EscapeString(scriptingObject.Name),
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ namespace Microsoft.Kusto.ServiceLayer.Utility
|
|||||||
|
|
||||||
public bool CanReadFromDisk { get; private set; }
|
public bool CanReadFromDisk { get; private set; }
|
||||||
|
|
||||||
public string LowercaseClientUri
|
public string LowercaseClientUri => ClientUri?.ToLower(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ClientUri?.ToLower();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,11 +14,11 @@ namespace Microsoft.Kusto.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides utilities for converting from SQL script syntax into POCOs.
|
/// Provides utilities for converting from SQL script syntax into POCOs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class FromSqlScript
|
public static partial class FromSqlScript
|
||||||
{
|
{
|
||||||
// Regex: optionally starts with N, captures string wrapped in single quotes
|
// Regex: optionally starts with N, captures string wrapped in single quotes
|
||||||
private static readonly Regex StringRegex = new Regex("^N?'(.*)'$", RegexOptions.Compiled);
|
private static readonly Regex StringRegex = GetStringRegex();
|
||||||
private static readonly Regex BracketRegex = new Regex(@"^\[(.*)\]$", RegexOptions.Compiled);
|
private static readonly Regex BracketRegex = GetBracketRegex();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes a multipart identifier as used in a SQL script into an array of the multiple
|
/// Decodes a multipart identifier as used in a SQL script into an array of the multiple
|
||||||
@@ -33,8 +33,8 @@ namespace Microsoft.Kusto.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
/// </exception>
|
/// </exception>
|
||||||
public static string[] DecodeMultipartIdentifier(string multipartIdentifier)
|
public static string[] DecodeMultipartIdentifier(string multipartIdentifier)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
List<string> namedParts = new List<string>();
|
var namedParts = new List<string>();
|
||||||
bool insideBrackets = false;
|
bool insideBrackets = false;
|
||||||
bool bracketsClosed = false;
|
bool bracketsClosed = false;
|
||||||
for (int i = 0; i < multipartIdentifier.Length; i++)
|
for (int i = 0; i < multipartIdentifier.Length; i++)
|
||||||
@@ -152,6 +152,11 @@ namespace Microsoft.Kusto.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
return value.Replace(new string(escapeCharacter, 2), escapeCharacter.ToString());
|
return value.Replace(new string(escapeCharacter, 2), escapeCharacter.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("^N?'(.*)'$", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetStringRegex();
|
||||||
|
[GeneratedRegex("^\\[(.*)\\]$", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetBracketRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace.Contracts
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id
|
public string Id
|
||||||
{
|
{
|
||||||
get { return this.ClientUri.ToLower(); }
|
get { return this.ClientUri.ToLower(System.Globalization.CultureInfo.InvariantCulture); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace
|
|||||||
/// Manages a "workspace" of script files that are open for a particular
|
/// Manages a "workspace" of script files that are open for a particular
|
||||||
/// editing session. Also helps to navigate references between ScriptFiles.
|
/// editing session. Also helps to navigate references between ScriptFiles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Workspace : IDisposable
|
public partial class Workspace : IDisposable
|
||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
@@ -115,8 +115,8 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace
|
|||||||
}
|
}
|
||||||
// This method allows FileNotFoundException to bubble up
|
// This method allows FileNotFoundException to bubble up
|
||||||
// if the file isn't found.
|
// if the file isn't found.
|
||||||
using (FileStream fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
using (var fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
||||||
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
scriptFile = new ScriptFile(resolvedFile.FilePath, resolvedFile.ClientUri,streamReader);
|
scriptFile = new ScriptFile(resolvedFile.FilePath, resolvedFile.ClientUri,streamReader);
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace
|
|||||||
|
|
||||||
// Client sent the path in URI format, extract the local path and trim
|
// Client sent the path in URI format, extract the local path and trim
|
||||||
// any extraneous slashes
|
// any extraneous slashes
|
||||||
Uri fileUri = new Uri(clientUri);
|
var fileUri = new Uri(clientUri);
|
||||||
filePath = fileUri.LocalPath;
|
filePath = fileUri.LocalPath;
|
||||||
if (filePath.StartsWith("//") || filePath.StartsWith("\\\\") || filePath.StartsWith("/"))
|
if (filePath.StartsWith("//") || filePath.StartsWith("\\\\") || filePath.StartsWith("/"))
|
||||||
{
|
{
|
||||||
@@ -206,7 +206,7 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Regex.Replace(path, @"`(?=[ \[\]])", "");
|
return GetEscapeRegex().Replace(path, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -361,6 +361,9 @@ namespace Microsoft.Kusto.ServiceLayer.Workspace
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("`(?=[ \\[\\]])")]
|
||||||
|
private static partial Regex GetEscapeRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,9 @@
|
|||||||
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
||||||
<AssemblyTitle>SqlTools Editor Services Credentials Manager Library</AssemblyTitle>
|
<AssemblyTitle>SqlTools Editor Services Credentials Manager Library</AssemblyTitle>
|
||||||
<Description>Provides message types and client/server APIs for the SqlTools Credential Services JSON protocol.</Description>
|
<Description>Provides message types and client/server APIs for the SqlTools Credential Services JSON protocol.</Description>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- SYSLIB1054: Use LibraryImportAttribute instead of DllImportAttribute to generate p/invoke marshalling code at compile time.
|
||||||
|
This is a Diagnostic Alert .NET 7 onwards.Changing to LibraryImportAttribute would require additional code changes,
|
||||||
|
therefore this warning is suppressed.-->
|
||||||
<NoWarn>$(NoWarn);SYSLIB1054</NoWarn>
|
<NoWarn>$(NoWarn);SYSLIB1054</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal implementation class to implement IBatchEventHandlers
|
/// Internal implementation class to implement IBatchEventHandlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class BatchEventNotificationHandler : IBatchEventsHandler
|
internal sealed class BatchEventNotificationHandler : IBatchEventsHandler
|
||||||
{
|
{
|
||||||
public void OnBatchError(object sender, BatchErrorEventArgs args)
|
public void OnBatchError(object sender, BatchErrorEventArgs args)
|
||||||
{
|
{
|
||||||
@@ -477,7 +477,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private class BatchInfo
|
private sealed class BatchInfo
|
||||||
{
|
{
|
||||||
public BatchInfo(int startLine, int startColumn, string batchText, SqlCmdCommand sqlCmdCommand, int repeatCount = 1)
|
public BatchInfo(int startLine, int startColumn, string batchText, SqlCmdCommand sqlCmdCommand, int repeatCount = 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<Version>$(VersionPrefix)</Version>
|
<Version>$(VersionPrefix)</Version>
|
||||||
<FileVersion>$(VersionPrefix)</FileVersion>
|
<FileVersion>$(VersionPrefix)</FileVersion>
|
||||||
<InformationalVersion>$(VersionPrefix)</InformationalVersion>
|
<InformationalVersion>$(VersionPrefix)</InformationalVersion>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- Disable CA1852 (Seal internal types) as it depends on SrGen Tool -->
|
||||||
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class is used as value in the dictionary to ensure that the type of value is correct.
|
/// This class is used as value in the dictionary to ensure that the type of value is correct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class AmbientValue
|
private sealed class AmbientValue
|
||||||
{
|
{
|
||||||
private readonly Type _type;
|
private readonly Type _type;
|
||||||
private readonly bool _isTypeNullable;
|
private readonly bool _isTypeNullable;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region CacheKey implementation
|
#region CacheKey implementation
|
||||||
internal class CacheKey : IEquatable<CacheKey>
|
internal sealed class CacheKey : IEquatable<CacheKey>
|
||||||
{
|
{
|
||||||
private string dataSource;
|
private string dataSource;
|
||||||
private string dbName;
|
private string dbName;
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExponentialDelayRetryPolicy : RetryPolicy
|
internal sealed class ExponentialDelayRetryPolicy : RetryPolicy
|
||||||
{
|
{
|
||||||
private readonly int _maxRetryCount;
|
private readonly int _maxRetryCount;
|
||||||
private readonly double _intervalFactor;
|
private readonly double _intervalFactor;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<StartupObject />
|
<StartupObject />
|
||||||
<Description>Provides the default for SqlTools applications.</Description>
|
<Description>Provides the default for SqlTools applications.</Description>
|
||||||
<Copyright><EFBFBD> Microsoft Corporation. All rights reserved.</Copyright>
|
<Copyright><EFBFBD> Microsoft Corporation. All rights reserved.</Copyright>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- Disable CA1852 (Seal internal types) as it depends on SrGen Tool -->
|
||||||
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
|
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
|
||||||
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
|
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
|
||||||
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- Disable CA1852 (Seal internal types) as it depends on SrGen Tool -->
|
||||||
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
<NoWarn>$(NoWarn);CA1852</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages"/>
|
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj" />
|
<ProjectReference Include="..\Microsoft.SqlTools.Hosting\Microsoft.SqlTools.Hosting.csproj" />
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Microsoft.SqlTools.ResourceProvider
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main application class for the executable that supports the resource provider and identity services
|
/// Main application class for the executable that supports the resource provider and identity services
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class Program
|
internal sealed class Program
|
||||||
{
|
{
|
||||||
private const string ServiceName = "SqlToolsResourceProviderService.exe";
|
private const string ServiceName = "SqlToolsResourceProviderService.exe";
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -51,9 +49,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
return Name.GetHashCode();
|
return Name.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
return obj is AzureEdition && ((AzureEdition)obj).Name.Equals(Name);
|
return obj is AzureEdition edition && edition.Name.Equals(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(AzureEdition left, AzureEdition right)
|
public static bool operator ==(AzureEdition left, AzureEdition right)
|
||||||
@@ -82,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
var azureEdition =
|
var azureEdition =
|
||||||
AzureServiceObjectiveInfo.Keys.FirstOrDefault(
|
AzureServiceObjectiveInfo.Keys.FirstOrDefault(
|
||||||
key => key.Name.ToLowerInvariant().Equals(edition.ToLowerInvariant()));
|
key => key.Name.ToLowerInvariant().Equals(edition.ToLowerInvariant()));
|
||||||
if (azureEdition != null)
|
if (azureEdition! != null)
|
||||||
{
|
{
|
||||||
return azureEdition;
|
return azureEdition;
|
||||||
}
|
}
|
||||||
@@ -358,9 +356,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
/// <returns>StorageAccountType string value for the current storageType</returns>
|
/// <returns>StorageAccountType string value for the current storageType</returns>
|
||||||
public static string GetStorageAccountTypeFromString(string storageAccountType)
|
public static string GetStorageAccountTypeFromString(string storageAccountType)
|
||||||
{
|
{
|
||||||
if (bsrAPIToUIValueMapping.ContainsKey(storageAccountType))
|
if (bsrAPIToUIValueMapping.TryGetValue(storageAccountType, out string? value))
|
||||||
{
|
{
|
||||||
return bsrAPIToUIValueMapping[storageAccountType];
|
return value;
|
||||||
}
|
}
|
||||||
return storageAccountType;
|
return storageAccountType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1100,7 +1100,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
|
|
||||||
const string UrnFormatStr = "Server/JobServer[@Name='{0}']/Job[@Name='{1}']/Schedule[@Name='{2}']";
|
const string UrnFormatStr = "Server/JobServer[@Name='{0}']/Job[@Name='{1}']/Schedule[@Name='{2}']";
|
||||||
string serverName = dataContainer.Server.Name.ToUpper();
|
string serverName = dataContainer.Server.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
string scheduleUrn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, schedule.Name);
|
string scheduleUrn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, schedule.Name);
|
||||||
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
STParameters param = new STParameters(dataContainer.Document);
|
||||||
@@ -1132,7 +1132,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
||||||
dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
||||||
|
|
||||||
XmlDocument jobDoc = CreateJobXmlDocument(dataContainer.Server.Name.ToUpper(), jobName);
|
XmlDocument jobDoc = CreateJobXmlDocument(dataContainer.Server.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture), jobName);
|
||||||
dataContainer.Init(jobDoc.InnerXml);
|
dataContainer.Init(jobDoc.InnerXml);
|
||||||
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
STParameters param = new STParameters(dataContainer.Document);
|
||||||
@@ -1487,9 +1487,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
string jobRuntime = jobHistory.RunDate.ToString("yyyyMMddHHmmss");
|
string jobRuntime = jobHistory.RunDate.ToString("yyyyMMddHHmmss");
|
||||||
AgentNotebookHistoryInfo notebookHistory = jobHistory;
|
AgentNotebookHistoryInfo notebookHistory = jobHistory;
|
||||||
if (notebookHistoriesDict.ContainsKey(jobRuntime))
|
if (notebookHistoriesDict.TryGetValue(jobRuntime, out DataRow dataRow))
|
||||||
{
|
{
|
||||||
notebookHistory.MaterializedNotebookId = (int)notebookHistoriesDict[jobRuntime]["materialized_id"];
|
notebookHistory.MaterializedNotebookId = (int)dataRow["materialized_id"];
|
||||||
notebookHistory.MaterializedNotebookErrorInfo = notebookHistoriesDict[jobRuntime]["notebook_error"] as string;
|
notebookHistory.MaterializedNotebookErrorInfo = notebookHistoriesDict[jobRuntime]["notebook_error"] as string;
|
||||||
notebookHistory.MaterializedNotebookName = notebookHistoriesDict[jobRuntime]["notebook_name"] as string;
|
notebookHistory.MaterializedNotebookName = notebookHistoriesDict[jobRuntime]["notebook_name"] as string;
|
||||||
notebookHistory.MaterializedNotebookPin = (bool)notebookHistoriesDict[jobRuntime]["pin"];
|
notebookHistory.MaterializedNotebookPin = (bool)notebookHistoriesDict[jobRuntime]["pin"];
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -32,10 +30,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
this.data = data;
|
this.data = data;
|
||||||
var availableSystems =
|
var availableSystems =
|
||||||
dataContainer.Server.JobServer.EnumSubSystems()
|
dataContainer.Server?.JobServer.EnumSubSystems()
|
||||||
.Rows.OfType<DataRow>()
|
.Rows.OfType<DataRow>()
|
||||||
.Select(r => (AgentSubSystem)Convert.ToInt32(r["subsystem_id"]));
|
.Select(r => (AgentSubSystem)Convert.ToInt32(r["subsystem_id"]));
|
||||||
|
if (availableSystems != null)
|
||||||
|
{
|
||||||
foreach (var agentSubSystemId in availableSystems)
|
foreach (var agentSubSystemId in availableSystems)
|
||||||
{
|
{
|
||||||
var agentSubSystem = CreateJobStepSubSystem(agentSubSystemId, dataContainer, data);
|
var agentSubSystem = CreateJobStepSubSystem(agentSubSystemId, dataContainer, data);
|
||||||
@@ -46,23 +45,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public JobStepSubSystem[] AvailableSubSystems
|
public JobStepSubSystem[] AvailableSubSystems
|
||||||
{
|
{
|
||||||
get { return this.subSystems.Keys.OrderBy(k => (int) k).Select(k => this.subSystems[k]).ToArray(); }
|
get { return this.subSystems.Keys.OrderBy(k => (int)k).Select(k => this.subSystems[k]).ToArray(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public JobStepSubSystem Lookup(AgentSubSystem key)
|
public JobStepSubSystem Lookup(AgentSubSystem key)
|
||||||
{
|
{
|
||||||
JobStepSubSystem rv = null;
|
JobStepSubSystem rv = null;
|
||||||
if (this.subSystems.ContainsKey(key))
|
if (this.subSystems.TryGetValue(key, out JobStepSubSystem? value))
|
||||||
{
|
{
|
||||||
return this.subSystems[key];
|
return value;
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof (AgentSubSystem));
|
private static TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(AgentSubSystem));
|
||||||
// Returns name of the subsystem for a given enum value
|
// Returns name of the subsystem for a given enum value
|
||||||
public static string LookupFriendlyName(AgentSubSystem key)
|
public static string LookupFriendlyName(AgentSubSystem key)
|
||||||
{
|
{
|
||||||
@@ -74,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
// Have to subtract first enum value to bring the
|
// Have to subtract first enum value to bring the
|
||||||
// index to 0-based index
|
// index to 0-based index
|
||||||
return typeConverter.ConvertToInvariantString((Enum) key);
|
return typeConverter.ConvertToInvariantString((Enum)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JobStepSubSystem CreateJobStepSubSystem(
|
private static JobStepSubSystem CreateJobStepSubSystem(
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
if (jobData.Job != null)
|
if (jobData.Job != null)
|
||||||
{
|
{
|
||||||
const string UrnFormatStr = "Server/JobServer[@Name='{0}']/Job[@Name='{1}']/Step[@Name='{2}']";
|
const string UrnFormatStr = "Server/JobServer[@Name='{0}']/Job[@Name='{1}']/Step[@Name='{2}']";
|
||||||
string serverName = this.DataContainer.Server.Name.ToUpper();
|
string serverName = this.DataContainer.Server.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
string urn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, stepName);
|
string urn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, stepName);
|
||||||
jobStep = jobData.Job.Parent.Parent.GetSmoObject(urn) as JobStep;
|
jobStep = jobData.Job.Parent.Parent.GetSmoObject(urn) as JobStep;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// simple job schedule structure.
|
/// simple job schedule structure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public struct SimpleJobSchedule
|
public partial struct SimpleJobSchedule
|
||||||
{
|
{
|
||||||
#region consts
|
#region consts
|
||||||
private const int EndOfDay = 235959;
|
private const int EndOfDay = 235959;
|
||||||
@@ -44,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
private FrequencyTypes frequencyTypes;
|
private FrequencyTypes frequencyTypes;
|
||||||
private FrequencySubDayTypes frequencySubDayTypes;
|
private FrequencySubDayTypes frequencySubDayTypes;
|
||||||
private FrequencyRelativeIntervals frequencyRelativeIntervals;
|
private FrequencyRelativeIntervals frequencyRelativeIntervals;
|
||||||
private System.Boolean isEnabled;
|
private bool isEnabled;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
@@ -100,7 +100,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
public static DateTime ConvertIntToDateTime(int source)
|
public static DateTime ConvertIntToDateTime(int source)
|
||||||
{
|
{
|
||||||
return new DateTime(source / 10000
|
return new DateTime(source / 10000
|
||||||
, (source / 100) % 100
|
, source / 100 % 100
|
||||||
, source % 100);
|
, source % 100);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -126,7 +126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
public static TimeSpan ConvertIntToTimeSpan(int source)
|
public static TimeSpan ConvertIntToTimeSpan(int source)
|
||||||
{
|
{
|
||||||
return new TimeSpan(source / 10000
|
return new TimeSpan(source / 10000
|
||||||
, (source / 100) % 100
|
, source / 100 % 100
|
||||||
, source % 100);
|
, source % 100);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -150,13 +150,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// <returns>JobScheduleData object</returns>
|
/// <returns>JobScheduleData object</returns>
|
||||||
public JobScheduleData ToJobScheduleData()
|
public JobScheduleData ToJobScheduleData()
|
||||||
{
|
{
|
||||||
JobScheduleData data = new JobScheduleData();
|
var data = new JobScheduleData();
|
||||||
data.Name = this.Name;
|
data.Name = this.Name;
|
||||||
data.Enabled = this.IsEnabled;
|
data.Enabled = this.IsEnabled;
|
||||||
data.ActiveStartDate = SimpleJobSchedule.ConvertIntToDateLocalized(this.ActiveStartDate);
|
data.ActiveStartDate = ConvertIntToDateLocalized(this.ActiveStartDate);
|
||||||
data.ActiveStartTime = SimpleJobSchedule.ConvertIntToTimeSpan(this.ActiveStartTimeOfDay);
|
data.ActiveStartTime = ConvertIntToTimeSpan(this.ActiveStartTimeOfDay);
|
||||||
data.ActiveEndDate = SimpleJobSchedule.ConvertIntToDateLocalized(this.ActiveEndDate);
|
data.ActiveEndDate = ConvertIntToDateLocalized(this.ActiveEndDate);
|
||||||
data.ActiveEndTime = SimpleJobSchedule.ConvertIntToTimeSpan(this.ActiveEndTimeOfDay);
|
data.ActiveEndTime = ConvertIntToTimeSpan(this.ActiveEndTimeOfDay);
|
||||||
data.FrequencyTypes = this.FrequencyTypes;
|
data.FrequencyTypes = this.FrequencyTypes;
|
||||||
data.FrequencyInterval = this.FrequencyInterval;
|
data.FrequencyInterval = this.FrequencyInterval;
|
||||||
data.FrequencyRecurranceFactor = this.FrequencyRecurrenceFactor;
|
data.FrequencyRecurranceFactor = this.FrequencyRecurrenceFactor;
|
||||||
@@ -173,15 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// <returns>new SimpleJobSchedule</returns>
|
/// <returns>new SimpleJobSchedule</returns>
|
||||||
public static SimpleJobSchedule FromJobScheduleData(JobScheduleData source)
|
public static SimpleJobSchedule FromJobScheduleData(JobScheduleData source)
|
||||||
{
|
{
|
||||||
SimpleJobSchedule schedule = new SimpleJobSchedule();
|
var schedule = new SimpleJobSchedule();
|
||||||
|
|
||||||
schedule.Name = source.Name;
|
schedule.Name = source.Name;
|
||||||
schedule.ID = source.ID;
|
schedule.ID = source.ID;
|
||||||
schedule.IsEnabled = source.Enabled;
|
schedule.IsEnabled = source.Enabled;
|
||||||
schedule.ActiveStartDate = SimpleJobSchedule.ConvertDateTimeToInt(source.ActiveStartDate);
|
schedule.ActiveStartDate = ConvertDateTimeToInt(source.ActiveStartDate);
|
||||||
schedule.ActiveStartTimeOfDay = SimpleJobSchedule.ConvertTimeSpanToInt(source.ActiveStartTime);
|
schedule.ActiveStartTimeOfDay = ConvertTimeSpanToInt(source.ActiveStartTime);
|
||||||
schedule.ActiveEndDate = SimpleJobSchedule.ConvertDateTimeToInt(source.ActiveEndDate);
|
schedule.ActiveEndDate = ConvertDateTimeToInt(source.ActiveEndDate);
|
||||||
schedule.ActiveEndTimeOfDay = SimpleJobSchedule.ConvertTimeSpanToInt(source.ActiveEndTime);
|
schedule.ActiveEndTimeOfDay = ConvertTimeSpanToInt(source.ActiveEndTime);
|
||||||
schedule.FrequencyTypes = source.FrequencyTypes;
|
schedule.FrequencyTypes = source.FrequencyTypes;
|
||||||
schedule.FrequencyInterval = source.FrequencyInterval;
|
schedule.FrequencyInterval = source.FrequencyInterval;
|
||||||
schedule.FrequencyRecurrenceFactor = source.FrequencyRecurranceFactor;
|
schedule.FrequencyRecurrenceFactor = source.FrequencyRecurranceFactor;
|
||||||
@@ -293,7 +293,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder daysOfWeek = new StringBuilder();
|
var daysOfWeek = new StringBuilder();
|
||||||
// Start matching with Monday. GetLocalizedDaysOfWeek() must start with Monday too.
|
// Start matching with Monday. GetLocalizedDaysOfWeek() must start with Monday too.
|
||||||
WeekDays dayOfWeek = WeekDays.Monday;
|
WeekDays dayOfWeek = WeekDays.Monday;
|
||||||
foreach (string localizedDayOfWeek in GetLocalizedDaysOfWeek())
|
foreach (string localizedDayOfWeek in GetLocalizedDaysOfWeek())
|
||||||
@@ -309,7 +309,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
// There's no easy way to advance to the next enum value, so since we know
|
// There's no easy way to advance to the next enum value, so since we know
|
||||||
// it's a bitfield mask we do a left shift ourselves.
|
// it's a bitfield mask we do a left shift ourselves.
|
||||||
int nextDay = ((int)dayOfWeek) << 1;
|
int nextDay = (int)dayOfWeek << 1;
|
||||||
dayOfWeek = (WeekDays)nextDay;
|
dayOfWeek = (WeekDays)nextDay;
|
||||||
if (dayOfWeek > WeekDays.Saturday)
|
if (dayOfWeek > WeekDays.Saturday)
|
||||||
{
|
{
|
||||||
@@ -449,7 +449,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
MonthlyRelativeWeekDays relativeDays = (MonthlyRelativeWeekDays) this.FrequencyInterval;
|
var relativeDays = (MonthlyRelativeWeekDays) this.FrequencyInterval;
|
||||||
|
|
||||||
switch (relativeDays)
|
switch (relativeDays)
|
||||||
{
|
{
|
||||||
@@ -671,10 +671,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
string ExpandFormatString(string format)
|
string ExpandFormatString(string format)
|
||||||
{
|
{
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
var stringBuilder = new StringBuilder();
|
||||||
int lastIndex = 0;
|
int lastIndex = 0;
|
||||||
|
|
||||||
MatchCollection matches = Regex.Matches(format, @"\{(?<property>\w+)\}");
|
MatchCollection matches = GetPropertyDescriptorRegex().Matches(format);
|
||||||
|
|
||||||
if (matches.Count > 0)
|
if (matches.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -687,7 +687,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
if (property != null)
|
if (property != null)
|
||||||
{
|
{
|
||||||
object propertyValue = property.GetValue(this);
|
object propertyValue = property.GetValue(this);
|
||||||
propertyValue = propertyValue != null ? propertyValue.ToString() : String.Empty;
|
propertyValue = propertyValue != null ? propertyValue.ToString() : string.Empty;
|
||||||
|
|
||||||
stringBuilder.Append(format.Substring(lastIndex, match.Index - lastIndex));
|
stringBuilder.Append(format.Substring(lastIndex, match.Index - lastIndex));
|
||||||
stringBuilder.Append(propertyValue as string);
|
stringBuilder.Append(propertyValue as string);
|
||||||
@@ -705,6 +705,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
return new string[] { "SR.Monday", "SR.Tuesday", "SR.Wednesday", "SR.Thursday", "SR.Friday", "SR.Saturday", "SR.Sunday" };
|
return new string[] { "SR.Monday", "SR.Tuesday", "SR.Wednesday", "SR.Thursday", "SR.Friday", "SR.Saturday", "SR.Sunday" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("\\{(?<property>\\w+)\\}")]
|
||||||
|
private static partial Regex GetPropertyDescriptorRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Microsoft.SqlTools.ServiceLayer.AzureFunctions
|
|||||||
return a.ArgumentList
|
return a.ArgumentList
|
||||||
?.Arguments
|
?.Arguments
|
||||||
.Where(a => a.Expression.Kind() == SyntaxKind.StringLiteralExpression && a.NameEquals == null) // Operations are string literals who don't have a name (Route is always a named param)
|
.Where(a => a.Expression.Kind() == SyntaxKind.StringLiteralExpression && a.NameEquals == null) // Operations are string literals who don't have a name (Route is always a named param)
|
||||||
.Select(a => a.ToString().TrimStringQuotes().ToUpper()) // upper case for consistent naming
|
.Select(a => a.ToString().TrimStringQuotes().ToUpper(System.Globalization.CultureInfo.InvariantCulture)) // upper case for consistent naming
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1420,7 +1420,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
{
|
{
|
||||||
// Secure Enclaves is not mapped to SqlConnection, it's only used for throwing validation errors
|
// Secure Enclaves is not mapped to SqlConnection, it's only used for throwing validation errors
|
||||||
// when Enclave Attestation Protocol is missing.
|
// when Enclave Attestation Protocol is missing.
|
||||||
switch (connectionDetails.SecureEnclaves.ToUpper())
|
switch (connectionDetails.SecureEnclaves.ToUpper(CultureInfo.InvariantCulture))
|
||||||
{
|
{
|
||||||
case "ENABLED":
|
case "ENABLED":
|
||||||
if (string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
if (string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
||||||
@@ -1437,7 +1437,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
||||||
{
|
{
|
||||||
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
||||||
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
|
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper(CultureInfo.InvariantCulture) == "DISABLED")
|
||||||
{
|
{
|
||||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
||||||
}
|
}
|
||||||
@@ -1454,7 +1454,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationUrl))
|
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationUrl))
|
||||||
{
|
{
|
||||||
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
if (connectionBuilder.ColumnEncryptionSetting != SqlConnectionColumnEncryptionSetting.Enabled
|
||||||
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
|
|| string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper(CultureInfo.InvariantCulture) == "DISABLED")
|
||||||
{
|
{
|
||||||
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static ModelTypeClass MapType(string type)
|
public static ModelTypeClass MapType(string type)
|
||||||
{
|
{
|
||||||
switch (type.ToLower())
|
switch (type.ToLower(System.Globalization.CultureInfo.InvariantCulture))
|
||||||
{
|
{
|
||||||
case "table":
|
case "table":
|
||||||
return ModelSchema.Table;
|
return ModelSchema.Table;
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -49,9 +47,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public RestorePlanDetailInfo CreateOptionInfo(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject)
|
public RestorePlanDetailInfo CreateOptionInfo(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject)
|
||||||
{
|
{
|
||||||
if(optionBuilders.ContainsKey(optionKey))
|
if (optionBuilders.TryGetValue(optionKey, out OptionBuilder? value))
|
||||||
{
|
{
|
||||||
return Create(optionKey, restoreDataObject, optionBuilders[optionKey]);
|
return Create(optionKey, restoreDataObject, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -68,9 +66,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
/// <param name="optionInfo"></param>
|
/// <param name="optionInfo"></param>
|
||||||
public void UpdateOption(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject, RestorePlanDetailInfo optionInfo)
|
public void UpdateOption(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject, RestorePlanDetailInfo optionInfo)
|
||||||
{
|
{
|
||||||
if (optionBuilders.ContainsKey(optionKey))
|
if (optionBuilders.TryGetValue(optionKey, out OptionBuilder? value))
|
||||||
{
|
{
|
||||||
var builder = optionBuilders[optionKey];
|
var builder = value;
|
||||||
var currentValue = builder.CurrentValueFunction(restoreDataObject);
|
var currentValue = builder.CurrentValueFunction(restoreDataObject);
|
||||||
var defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
var defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
||||||
var validateResult = builder.ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
var validateResult = builder.ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
||||||
@@ -102,9 +100,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
{
|
{
|
||||||
if (restoreDataObject != null)
|
if (restoreDataObject != null)
|
||||||
{
|
{
|
||||||
if (optionBuilders.ContainsKey(optionKey))
|
if (optionBuilders.TryGetValue(optionKey, out OptionBuilder? builder))
|
||||||
{
|
{
|
||||||
var builder = optionBuilders[optionKey];
|
|
||||||
if (restoreDataObject.RestoreParams != null && restoreDataObject.RestoreParams.Options.ContainsKey(optionKey))
|
if (restoreDataObject.RestoreParams != null && restoreDataObject.RestoreParams.Options.ContainsKey(optionKey))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -149,15 +146,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
public string ValidateOption(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject)
|
public string ValidateOption(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject)
|
||||||
{
|
{
|
||||||
string errorMessage = string.Empty;
|
string errorMessage = string.Empty;
|
||||||
if (optionBuilders.ContainsKey(optionKey))
|
if (optionBuilders.TryGetValue(optionKey, out OptionBuilder? builder))
|
||||||
{
|
{
|
||||||
var builder = optionBuilders[optionKey];
|
|
||||||
var currentValue = builder.CurrentValueFunction(restoreDataObject);
|
var currentValue = builder.CurrentValueFunction(restoreDataObject);
|
||||||
var defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
var defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
||||||
OptionValidationResult result = optionBuilders[optionKey].ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
OptionValidationResult result = optionBuilders[optionKey].ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
||||||
if (result.IsReadOnly)
|
if (result.IsReadOnly)
|
||||||
{
|
{
|
||||||
if(!ValueEqualsDefault(currentValue, defaultValue))
|
if (!ValueEqualsDefault(currentValue, defaultValue))
|
||||||
{
|
{
|
||||||
builder.SetValueFunction(restoreDataObject, defaultValue);
|
builder.SetValueFunction(restoreDataObject, defaultValue);
|
||||||
errorMessage = $"{optionKey} is ready only and cannot be modified";
|
errorMessage = $"{optionKey} is ready only and cannot be modified";
|
||||||
@@ -180,15 +176,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
|
|
||||||
private bool ValueEqualsDefault(object currentValue, object defaultValue)
|
private bool ValueEqualsDefault(object currentValue, object defaultValue)
|
||||||
{
|
{
|
||||||
if(currentValue == null && defaultValue == null)
|
if (currentValue == null)
|
||||||
{
|
{
|
||||||
return true;
|
return defaultValue == null;
|
||||||
}
|
}
|
||||||
if(currentValue == null && defaultValue != null)
|
else if (defaultValue == null)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (currentValue != null && defaultValue == null)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -200,311 +192,311 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
{
|
{
|
||||||
Register(RestoreOptionsHelper.RelocateDbFiles,
|
Register(RestoreOptionsHelper.RelocateDbFiles,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RelocateAllFiles;
|
return restoreDataObject.RelocateAllFiles;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult
|
return new OptionValidationResult
|
||||||
{
|
{
|
||||||
IsReadOnly = restoreDataObject.DbFiles.Count == 0
|
IsReadOnly = restoreDataObject.DbFiles.Count == 0
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RelocateAllFiles = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.RelocateDbFiles);
|
restoreDataObject.RelocateAllFiles = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.RelocateDbFiles);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.DataFileFolder,
|
Register(RestoreOptionsHelper.DataFileFolder,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DefaultDataFileFolder;
|
return restoreDataObject.DefaultDataFileFolder;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DataFilesFolder;
|
return restoreDataObject.DataFilesFolder;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult
|
return new OptionValidationResult
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.DataFilesFolder = GetValueAs<string>(value);
|
restoreDataObject.DataFilesFolder = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.LogFileFolder,
|
Register(RestoreOptionsHelper.LogFileFolder,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DefaultLogFileFolder;
|
return restoreDataObject.DefaultLogFileFolder;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.LogFilesFolder;
|
return restoreDataObject.LogFilesFolder;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult
|
return new OptionValidationResult
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.LogFilesFolder = GetValueAs<string>(value);
|
restoreDataObject.LogFilesFolder = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.ReplaceDatabase,
|
Register(RestoreOptionsHelper.ReplaceDatabase,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RestoreOptions.ReplaceDatabase;
|
return restoreDataObject.RestoreOptions.ReplaceDatabase;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult();
|
return new OptionValidationResult();
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RestoreOptions.ReplaceDatabase = GetValueAs<bool>(value);
|
restoreDataObject.RestoreOptions.ReplaceDatabase = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.KeepReplication,
|
Register(RestoreOptionsHelper.KeepReplication,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RestoreOptions.KeepReplication;
|
return restoreDataObject.RestoreOptions.KeepReplication;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState == DatabaseRecoveryState.WithNoRecovery
|
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState == DatabaseRecoveryState.WithNoRecovery
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RestoreOptions.KeepReplication = GetValueAs<bool>(value);
|
restoreDataObject.RestoreOptions.KeepReplication = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.SetRestrictedUser,
|
Register(RestoreOptionsHelper.SetRestrictedUser,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RestoreOptions.SetRestrictedUser;
|
return restoreDataObject.RestoreOptions.SetRestrictedUser;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RestoreOptions.SetRestrictedUser = GetValueAs<bool>(value);
|
restoreDataObject.RestoreOptions.SetRestrictedUser = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.RecoveryState,
|
Register(RestoreOptionsHelper.RecoveryState,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return DatabaseRecoveryState.WithRecovery.ToString();
|
return DatabaseRecoveryState.WithRecovery.ToString();
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RestoreOptions.RecoveryState.ToString();
|
return restoreDataObject.RestoreOptions.RecoveryState.ToString();
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RestoreOptions.RecoveryState = GetValueAs<DatabaseRecoveryState>(value);
|
restoreDataObject.RestoreOptions.RecoveryState = GetValueAs<DatabaseRecoveryState>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.StandbyFile,
|
Register(RestoreOptionsHelper.StandbyFile,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DefaultStandbyFile;
|
return restoreDataObject.DefaultStandbyFile;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.RestoreOptions.StandByFile;
|
return restoreDataObject.RestoreOptions.StandByFile;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState != DatabaseRecoveryState.WithStandBy
|
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState != DatabaseRecoveryState.WithStandBy
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.RestoreOptions.StandByFile = GetValueAs<string>(value);
|
restoreDataObject.RestoreOptions.StandByFile = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.BackupTailLog,
|
Register(RestoreOptionsHelper.BackupTailLog,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.IsTailLogBackupPossible;
|
return restoreDataObject.IsTailLogBackupPossible;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.BackupTailLog;
|
return restoreDataObject.BackupTailLog;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.IsTailLogBackupPossible
|
IsReadOnly = !restoreDataObject.IsTailLogBackupPossible
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.BackupTailLog = GetValueAs<bool>(value);
|
restoreDataObject.BackupTailLog = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.TailLogBackupFile,
|
Register(RestoreOptionsHelper.TailLogBackupFile,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DefaultTailLogbackupFile;
|
return restoreDataObject.DefaultTailLogbackupFile;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.TailLogBackupFile;
|
return restoreDataObject.TailLogBackupFile;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupPossible
|
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupPossible
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.TailLogBackupFile = GetValueAs<string>(value);
|
restoreDataObject.TailLogBackupFile = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.TailLogWithNoRecovery,
|
Register(RestoreOptionsHelper.TailLogWithNoRecovery,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.IsTailLogBackupWithNoRecoveryPossible;
|
return restoreDataObject.IsTailLogBackupWithNoRecoveryPossible;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.TailLogWithNoRecovery;
|
return restoreDataObject.TailLogWithNoRecovery;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupWithNoRecoveryPossible
|
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupWithNoRecoveryPossible
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.TailLogWithNoRecovery = GetValueAs<bool>(value);
|
restoreDataObject.TailLogWithNoRecovery = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.CloseExistingConnections,
|
Register(RestoreOptionsHelper.CloseExistingConnections,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.CloseExistingConnections;
|
return restoreDataObject.CloseExistingConnections;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = !restoreDataObject.CanDropExistingConnections
|
IsReadOnly = !restoreDataObject.CanDropExistingConnections
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.CloseExistingConnections = GetValueAs<bool>(value);
|
restoreDataObject.CloseExistingConnections = GetValueAs<bool>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.SourceDatabaseName,
|
Register(RestoreOptionsHelper.SourceDatabaseName,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.DefaultSourceDbName;
|
return restoreDataObject.DefaultSourceDbName;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.SourceDatabaseName;
|
return restoreDataObject.SourceDatabaseName;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
string errorMessage = string.Empty;
|
string errorMessage = string.Empty;
|
||||||
var sourceDbNames = restoreDataObject.SourceDbNames;
|
var sourceDbNames = restoreDataObject.SourceDbNames;
|
||||||
@@ -517,38 +509,38 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
ErrorMessage = errorMessage
|
ErrorMessage = errorMessage
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.SourceDatabaseName = GetValueAs<string>(value);
|
restoreDataObject.SourceDatabaseName = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
Register(RestoreOptionsHelper.TargetDatabaseName,
|
Register(RestoreOptionsHelper.TargetDatabaseName,
|
||||||
new OptionBuilder
|
new OptionBuilder
|
||||||
{
|
(
|
||||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.OverwriteTargetDatabase ? restoreDataObject.DefaultSourceDbName : restoreDataObject.DefaultTargetDbName;
|
return restoreDataObject.OverwriteTargetDatabase ? restoreDataObject.DefaultSourceDbName : restoreDataObject.DefaultTargetDbName;
|
||||||
},
|
},
|
||||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||||
{
|
{
|
||||||
return restoreDataObject.TargetDatabaseName;
|
return restoreDataObject.TargetDatabaseName;
|
||||||
},
|
},
|
||||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||||
{
|
{
|
||||||
return new OptionValidationResult()
|
return new OptionValidationResult()
|
||||||
{
|
{
|
||||||
IsReadOnly = false
|
IsReadOnly = false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
restoreDataObject.TargetDatabaseName = GetValueAs<string>(value);
|
restoreDataObject.TargetDatabaseName = GetValueAs<string>(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal T GetValueAs<T>(object value)
|
internal T GetValueAs<T>(object value)
|
||||||
@@ -587,6 +579,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
|||||||
public Func<IRestoreDatabaseTaskDataObject, object, object, OptionValidationResult> ValidateFunction { get; set; }
|
public Func<IRestoreDatabaseTaskDataObject, object, object, OptionValidationResult> ValidateFunction { get; set; }
|
||||||
public Func<IRestoreDatabaseTaskDataObject, object> CurrentValueFunction { get; set; }
|
public Func<IRestoreDatabaseTaskDataObject, object> CurrentValueFunction { get; set; }
|
||||||
public Func<IRestoreDatabaseTaskDataObject, object, bool> SetValueFunction { get; set; }
|
public Func<IRestoreDatabaseTaskDataObject, object, bool> SetValueFunction { get; set; }
|
||||||
|
|
||||||
|
public OptionBuilder(Func<IRestoreDatabaseTaskDataObject, object> defaultValueFunction, Func<IRestoreDatabaseTaskDataObject, object, object, OptionValidationResult> validateFunction, Func<IRestoreDatabaseTaskDataObject, object> currentValueFunction, Func<IRestoreDatabaseTaskDataObject, object, bool> setValueFunction)
|
||||||
|
{
|
||||||
|
this.DefaultValueFunction = defaultValueFunction;
|
||||||
|
this.ValidateFunction = validateFunction;
|
||||||
|
this.CurrentValueFunction = currentValueFunction;
|
||||||
|
this.SetValueFunction = setValueFunction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class OptionValidationResult
|
internal class OptionValidationResult
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Representation of a cell that should have a value inserted or updated
|
/// Representation of a cell that should have a value inserted or updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class CellUpdate
|
public sealed partial class CellUpdate
|
||||||
{
|
{
|
||||||
private const string NullString = @"NULL";
|
private const string NullString = @"NULL";
|
||||||
private const string TextNullString = @"'NULL'";
|
private const string TextNullString = @"'NULL'";
|
||||||
private static readonly Regex HexRegex = new Regex("0x[0-9A-F]+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex HexRegex = GetCharacterRegex();
|
||||||
private static readonly TimeSpan MaxTimespan = TimeSpan.FromHours(24);
|
private static readonly TimeSpan MaxTimespan = TimeSpan.FromHours(24);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -231,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
|||||||
|
|
||||||
private void ProcessTimespanColumn(string valueAsString)
|
private void ProcessTimespanColumn(string valueAsString)
|
||||||
{
|
{
|
||||||
TimeSpan ts = TimeSpan.Parse(valueAsString, CultureInfo.CurrentCulture);
|
var ts = TimeSpan.Parse(valueAsString, CultureInfo.CurrentCulture);
|
||||||
if (ts >= MaxTimespan)
|
if (ts >= MaxTimespan)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(SR.EditDataTimeOver24Hrs);
|
throw new InvalidOperationException(SR.EditDataTimeOver24Hrs);
|
||||||
@@ -270,6 +270,9 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
|||||||
ValueAsString = valueAsString;
|
ValueAsString = valueAsString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("0x[0-9A-F]+", RegexOptions.IgnoreCase | RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetCharacterRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for building hierarchy of Graph objects from ShowPlan Record Set
|
/// Base class for building hierarchy of Graph objects from ShowPlan Record Set
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class DataReaderNodeBuilder: INodeBuilder
|
internal abstract partial class DataReaderNodeBuilder: INodeBuilder
|
||||||
{
|
{
|
||||||
#region Constructor
|
#region Constructor
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
/// <returns>An array of AnalysisServices Graph objects.</returns>
|
/// <returns>An array of AnalysisServices Graph objects.</returns>
|
||||||
public ShowPlanGraph[] Execute(object dataSource)
|
public ShowPlanGraph[] Execute(object dataSource)
|
||||||
{
|
{
|
||||||
IDataReader reader = dataSource as IDataReader;
|
var reader = dataSource as IDataReader;
|
||||||
|
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
throw new ArgumentException(SR.Keys.UnknownShowPlanSource);
|
throw new ArgumentException(SR.Keys.UnknownShowPlanSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ShowPlanGraph> graphs = new List<ShowPlanGraph>();
|
var graphs = new List<ShowPlanGraph>();
|
||||||
Dictionary<int, Node> currentGraphNodes = null;
|
Dictionary<int, Node> currentGraphNodes = null;
|
||||||
NodeBuilderContext context = null;
|
NodeBuilderContext context = null;
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (names[i] != null && !((values[i] is DBNull) || values[i] == null))
|
if (names[i] != null && !(values[i] is DBNull || values[i] == null))
|
||||||
{
|
{
|
||||||
node[names[i]] = values[i];
|
node[names[i]] = values[i];
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
string argument = node["Argument"] as string;
|
string argument = node["Argument"] as string;
|
||||||
if (argument != null)
|
if (argument != null)
|
||||||
{
|
{
|
||||||
Match match = argumentObjectExpression.Match(argument);
|
Match match = GetargumentObjectExpressionRegex().Match(argument);
|
||||||
if (match != Match.Empty)
|
if (match != Match.Empty)
|
||||||
{
|
{
|
||||||
node["Object"] = match.Groups["Object"].Value;
|
node["Object"] = match.Groups["Object"].Value;
|
||||||
@@ -236,8 +236,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove spaces and other special characters from physical and logical names
|
// Remove spaces and other special characters from physical and logical names
|
||||||
physicalOpType = operatorReplaceExpression.Replace(physicalOpType, "");
|
physicalOpType = GetOperatorReplaceExpressionRegex().Replace(physicalOpType, "");
|
||||||
logicalOpType = operatorReplaceExpression.Replace(logicalOpType, "");
|
logicalOpType = GetOperatorReplaceExpressionRegex().Replace(logicalOpType, "");
|
||||||
|
|
||||||
Operation physicalOp = OperationTable.GetPhysicalOperation(physicalOpType);
|
Operation physicalOp = OperationTable.GetPhysicalOperation(physicalOpType);
|
||||||
Operation logicalOp = OperationTable.GetLogicalOperation(logicalOpType);
|
Operation logicalOp = OperationTable.GetLogicalOperation(logicalOpType);
|
||||||
@@ -290,8 +290,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
|||||||
|
|
||||||
#region Private members
|
#region Private members
|
||||||
|
|
||||||
private static Regex operatorReplaceExpression = new Regex(@"[ \-]", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
[GeneratedRegex("[ \\-]", RegexOptions.Compiled | RegexOptions.CultureInvariant)]
|
||||||
private static Regex argumentObjectExpression = new Regex(@"OBJECT:\((?<Object>[^\)]*)\)", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
private static partial Regex GetOperatorReplaceExpressionRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("OBJECT:\\((?<Object>[^\\)]*)\\)", RegexOptions.Compiled | RegexOptions.CultureInvariant)]
|
||||||
|
private static partial Regex GetargumentObjectExpressionRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,10 +191,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
lock (this.bindingContextLock)
|
lock (this.bindingContextLock)
|
||||||
{
|
{
|
||||||
if (this.BindingContextMap.ContainsKey(key))
|
if (this.BindingContextMap.TryGetValue(key, out IBindingContext? bindingContext))
|
||||||
{
|
{
|
||||||
// disconnect existing connection
|
// disconnect existing connection
|
||||||
var bindingContext = this.BindingContextMap[key];
|
|
||||||
if (bindingContext.ServerConnection != null && bindingContext.ServerConnection.IsOpen)
|
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
|
// Disconnecting can take some time so run it in a separate task so that it doesn't block removal
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a completion item from SQL parser declaration item
|
/// Creates a completion item from SQL parser declaration item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SqlCompletionItem
|
public partial class SqlCompletionItem
|
||||||
{
|
{
|
||||||
private static Regex ValidSqlNameRegex = new Regex(@"^[\p{L}_@#][\p{L}\p{N}@$#_]{0,127}$");
|
[GeneratedRegex("^[\\p{L}_@#][\\p{L}\\p{N}@$#_]{0,127}$")]
|
||||||
|
private static partial Regex GetValidSqlNameRegex();
|
||||||
private static DelimitedIdentifier BracketedIdentifiers = new DelimitedIdentifier { Start = "[", End = "]" };
|
private static DelimitedIdentifier BracketedIdentifiers = new DelimitedIdentifier { Start = "[", End = "]" };
|
||||||
private static DelimitedIdentifier FunctionPostfix = new DelimitedIdentifier { Start = "", End = "()" };
|
private static DelimitedIdentifier FunctionPostfix = new DelimitedIdentifier { Start = "", End = "()" };
|
||||||
private static DelimitedIdentifier[] DelimitedIdentifiers =
|
private static DelimitedIdentifier[] DelimitedIdentifiers =
|
||||||
@@ -79,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
|||||||
case DeclarationType.Schema:
|
case DeclarationType.Schema:
|
||||||
// Only quote if we need to - i.e. if this isn't a valid name (has characters that need escaping such as [)
|
// Only quote if we need to - i.e. if this isn't a valid name (has characters that need escaping such as [)
|
||||||
// or if it's a reserved word
|
// or if it's a reserved word
|
||||||
if (!ValidSqlNameRegex.IsMatch(DeclarationTitle) || AutoCompleteHelper.IsReservedWord(InsertText))
|
if (!GetValidSqlNameRegex().IsMatch(DeclarationTitle) || AutoCompleteHelper.IsReservedWord(InsertText))
|
||||||
{
|
{
|
||||||
InsertText = WithDelimitedIdentifier(BracketedIdentifiers, DeclarationTitle);
|
InsertText = WithDelimitedIdentifier(BracketedIdentifiers, DeclarationTitle);
|
||||||
}
|
}
|
||||||
@@ -197,7 +198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
|||||||
int startColumn,
|
int startColumn,
|
||||||
int endColumn)
|
int endColumn)
|
||||||
{
|
{
|
||||||
CompletionItem item = new CompletionItem()
|
var item = new CompletionItem()
|
||||||
{
|
{
|
||||||
Label = label,
|
Label = label,
|
||||||
Kind = kind,
|
Kind = kind,
|
||||||
|
|||||||
@@ -1869,10 +1869,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
lock (this.parseMapLock)
|
lock (this.parseMapLock)
|
||||||
{
|
{
|
||||||
if (this.ScriptParseInfoMap.ContainsKey(uri))
|
if (this.ScriptParseInfoMap.TryGetValue(uri, out ScriptParseInfo value))
|
||||||
{
|
{
|
||||||
Logger.Verbose($"Found ScriptParseInfo for uri {uri}");
|
Logger.Verbose($"Found ScriptParseInfo for uri {uri}");
|
||||||
return this.ScriptParseInfoMap[uri];
|
return value;
|
||||||
}
|
}
|
||||||
else if (createIfNotExists)
|
else if (createIfNotExists)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1191,7 +1191,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
<urn>Server[@Name='{0}']</urn>
|
<urn>Server[@Name='{0}']</urn>
|
||||||
<itemtype>Database</itemtype>
|
<itemtype>Database</itemtype>
|
||||||
</params></formdescription> ",
|
</params></formdescription> ",
|
||||||
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
connInfo.ConnectionDetails.ServerName.ToUpper(CultureInfo.InvariantCulture),
|
||||||
connInfo.ConnectionDetails.UserName);
|
connInfo.ConnectionDetails.UserName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1205,7 +1205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
<urn>Server[@Name='{0}']</urn>
|
<urn>Server[@Name='{0}']</urn>
|
||||||
<database>{2}</database>
|
<database>{2}</database>
|
||||||
</params></formdescription> ",
|
</params></formdescription> ",
|
||||||
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
connInfo.ConnectionDetails.ServerName.ToUpper(CultureInfo.InvariantCulture),
|
||||||
connInfo.ConnectionDetails.UserName,
|
connInfo.ConnectionDetails.UserName,
|
||||||
connInfo.ConnectionDetails.DatabaseName);
|
connInfo.ConnectionDetails.DatabaseName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
<RuntimeIdentifiers>$(ToolsServiceTargetRuntimes)</RuntimeIdentifiers>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
|
||||||
<NoWarn>$(NoWarn);SYSLIB1045;CA1311;CA1854;CS8600;CS8603;CS8625</NoWarn>
|
|
||||||
<AssemblyTitle>SqlTools Editor Services Host Protocol Library</AssemblyTitle>
|
<AssemblyTitle>SqlTools Editor Services Host Protocol Library</AssemblyTitle>
|
||||||
<Description>Provides message types and client/server APIs for the SqlTools Editor Services JSON protocol.</Description>
|
<Description>Provides message types and client/server APIs for the SqlTools Editor Services JSON protocol.</Description>
|
||||||
|
<!-- False alerts, disabled due to issue: https://github.com/dotnet/roslyn/issues/65850 -->
|
||||||
|
<NoWarn>$(NoWarn);CS8795</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
|||||||
|
|
||||||
if ((currentEvent.Name.Equals("sql_batch_completed")
|
if ((currentEvent.Name.Equals("sql_batch_completed")
|
||||||
|| currentEvent.Name.Equals("sql_batch_starting"))
|
|| currentEvent.Name.Equals("sql_batch_starting"))
|
||||||
&& currentEvent.Values.ContainsKey("batch_text"))
|
&& currentEvent.Values.TryGetValue("batch_text", out string value))
|
||||||
{
|
{
|
||||||
return currentEvent.Values["batch_text"].Contains("SELECT target_data FROM sys.dm_xe_session_targets")
|
return value.Contains("SELECT target_data FROM sys.dm_xe_session_targets")
|
||||||
|| currentEvent.Values["batch_text"].Contains("SELECT target_data FROM sys.dm_xe_database_session_targets");
|
|| currentEvent.Values["batch_text"].Contains("SELECT target_data FROM sys.dm_xe_database_session_targets");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writer for exporting results to a Markdown table.
|
/// Writer for exporting results to a Markdown table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SaveAsMarkdownFileStreamWriter : SaveAsStreamWriter
|
public partial class SaveAsMarkdownFileStreamWriter : SaveAsStreamWriter
|
||||||
{
|
{
|
||||||
private const string Delimiter = "|";
|
private const string Delimiter = "|";
|
||||||
private static readonly Regex NewlineRegex = new Regex(@"(\r\n|\n|\r)", RegexOptions.Compiled);
|
|
||||||
|
[GeneratedRegex("(\\r\\n|\\n|\\r)", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetNewLineRegex();
|
||||||
|
|
||||||
private readonly Encoding _encoding;
|
private readonly Encoding _encoding;
|
||||||
private readonly string _lineSeparator;
|
private readonly string _lineSeparator;
|
||||||
@@ -72,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
|||||||
this.WriteLine($"{Delimiter}{rowLine}{Delimiter}");
|
this.WriteLine($"{Delimiter}{rowLine}{Delimiter}");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string EncodeMarkdownField(string? field)
|
internal static string EncodeMarkdownField(string field)
|
||||||
{
|
{
|
||||||
// Special case for nulls
|
// Special case for nulls
|
||||||
if (field == null)
|
if (field == null)
|
||||||
@@ -89,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
|||||||
// @TODO: Allow option to encode multiple whitespace characters as
|
// @TODO: Allow option to encode multiple whitespace characters as
|
||||||
|
|
||||||
// Replace newlines with br tags, since cell values must be single line
|
// Replace newlines with br tags, since cell values must be single line
|
||||||
field = NewlineRegex.Replace(field, @"<br />");
|
field = GetNewLineRegex().Replace(field, @"<br />");
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
/// Class that represents a resultset the was generated from a query. Contains logic for
|
/// Class that represents a resultset the was generated from a query. Contains logic for
|
||||||
/// storing and retrieving results. Is contained by a Batch class.
|
/// storing and retrieving results. Is contained by a Batch class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ResultSet : IDisposable
|
public partial class ResultSet : IDisposable
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
// ReSharper disable once AccessToDisposedClosure The lambda is used immediately in string.Join call
|
// ReSharper disable once AccessToDisposedClosure The lambda is used immediately in string.Join call
|
||||||
IEnumerable<string> rowValues = fileOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, 0, Columns)[0].DisplayValue);
|
IEnumerable<string> rowValues = fileOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, 0, Columns)[0].DisplayValue);
|
||||||
string singleString = string.Join(string.Empty, rowValues);
|
string singleString = string.Join(string.Empty, rowValues);
|
||||||
DbCellValue cellValue = new DbCellValue
|
var cellValue = new DbCellValue
|
||||||
{
|
{
|
||||||
DisplayValue = singleString,
|
DisplayValue = singleString,
|
||||||
IsNull = false,
|
IsNull = false,
|
||||||
@@ -369,7 +369,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
// Verify the request hasn't been cancelled
|
// Verify the request hasn't been cancelled
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
var dataReader = new StorageDataReader(dbDataReader);
|
||||||
|
|
||||||
// Open a writer for the file
|
// Open a writer for the file
|
||||||
//
|
//
|
||||||
@@ -514,7 +514,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the new task
|
// Create the new task
|
||||||
Task saveAsTask = new Task(async () =>
|
var saveAsTask = new Task(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -638,7 +638,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
//
|
//
|
||||||
sendResultsSemphore.Wait();
|
sendResultsSemphore.Wait();
|
||||||
|
|
||||||
ResultSet currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
var currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
||||||
if (LastUpdatedSummary == null) // We need to send results available message.
|
if (LastUpdatedSummary == null) // We need to send results available message.
|
||||||
{
|
{
|
||||||
// Fire off results Available task and await it
|
// Fire off results Available task and await it
|
||||||
@@ -739,13 +739,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
{
|
{
|
||||||
if (Columns?.Length > 0 && RowCount != 0)
|
if (Columns?.Length > 0 && RowCount != 0)
|
||||||
{
|
{
|
||||||
Regex regex = new Regex(@"({.*?})");
|
|
||||||
var row = GetRow(0);
|
var row = GetRow(0);
|
||||||
for (int i = 0; i < Columns.Length; i++)
|
for (int i = 0; i < Columns.Length; i++)
|
||||||
{
|
{
|
||||||
if (Columns[i].DataTypeName.Equals("nvarchar"))
|
if (Columns[i].DataTypeName.Equals("nvarchar"))
|
||||||
{
|
{
|
||||||
if (regex.IsMatch(row[i].DisplayValue))
|
if (GetJsonRegex().IsMatch(row[i].DisplayValue))
|
||||||
{
|
{
|
||||||
Columns[i].IsJson = true;
|
Columns[i].IsJson = true;
|
||||||
}
|
}
|
||||||
@@ -788,7 +787,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
// Returning false from .ReadAsync means there aren't any rows.
|
// Returning false from .ReadAsync means there aren't any rows.
|
||||||
|
|
||||||
// Create a storage data reader, read it, make sure there were results
|
// Create a storage data reader, read it, make sure there were results
|
||||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
var dataReader = new StorageDataReader(dbDataReader);
|
||||||
if (!await dataReader.ReadAsync(CancellationToken.None))
|
if (!await dataReader.ReadAsync(CancellationToken.None))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
||||||
@@ -804,6 +803,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("({.*?})")]
|
||||||
|
private static partial Regex GetJsonRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal class for utilities shared between multiple schema compare operations
|
/// Internal class for utilities shared between multiple schema compare operations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class SchemaCompareUtils
|
internal static partial class SchemaCompareUtils
|
||||||
{
|
{
|
||||||
internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
|
internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
|
||||||
{
|
{
|
||||||
@@ -31,7 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffEntry diffEntry = new DiffEntry();
|
var diffEntry = new DiffEntry();
|
||||||
diffEntry.UpdateAction = difference.UpdateAction;
|
diffEntry.UpdateAction = difference.UpdateAction;
|
||||||
diffEntry.DifferenceType = difference.DifferenceType;
|
diffEntry.DifferenceType = difference.DifferenceType;
|
||||||
diffEntry.Name = difference.Name;
|
diffEntry.Name = difference.Name;
|
||||||
@@ -86,8 +86,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ObjectIdentifier id = new ObjectIdentifier(sourceObj.NameParts);
|
var id = new ObjectIdentifier(sourceObj.NameParts);
|
||||||
SchemaComparisonExcludedObjectId excludedObjId = new SchemaComparisonExcludedObjectId(sourceObj.SqlObjectType, id);
|
var excludedObjId = new SchemaComparisonExcludedObjectId(sourceObj.SqlObjectType, id);
|
||||||
return excludedObjId;
|
return excludedObjId;
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
@@ -145,7 +145,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
|||||||
// remove leading and trailing whitespace
|
// remove leading and trailing whitespace
|
||||||
script = script.Trim();
|
script = script.Trim();
|
||||||
// replace all multiple spaces with single space
|
// replace all multiple spaces with single space
|
||||||
script = Regex.Replace(script, " {2,}", " ");
|
script = GetScriptRegex().Replace(script, " ");
|
||||||
}
|
}
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
@@ -159,5 +159,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
|||||||
}
|
}
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(" {2,}")]
|
||||||
|
private static partial Regex GetScriptRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
string tokenType = GetTokenTypeFromQuickInfo(quickInfoText, tokenText, caseSensitivity);
|
string tokenType = GetTokenTypeFromQuickInfo(quickInfoText, tokenText, caseSensitivity);
|
||||||
if (tokenType != null)
|
if (tokenType != null)
|
||||||
{
|
{
|
||||||
if (sqlObjectTypesFromQuickInfo.ContainsKey(tokenType.ToLowerInvariant()))
|
if (sqlObjectTypesFromQuickInfo.TryGetValue(tokenType.ToLowerInvariant(), out string sqlObjectType))
|
||||||
{
|
{
|
||||||
// With SqlLogin authentication, the defaultSchema property throws an Exception when accessed.
|
// With SqlLogin authentication, the defaultSchema property throws an Exception when accessed.
|
||||||
// This workaround ensures that a schema name is present by attempting
|
// This workaround ensures that a schema name is present by attempting
|
||||||
@@ -203,8 +203,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
Location[] locations = GetSqlObjectDefinition(
|
Location[] locations = GetSqlObjectDefinition(
|
||||||
tokenText,
|
tokenText,
|
||||||
schemaName,
|
schemaName,
|
||||||
sqlObjectTypesFromQuickInfo[tokenType.ToLowerInvariant()]
|
sqlObjectType);
|
||||||
);
|
|
||||||
DefinitionResult result = new DefinitionResult
|
DefinitionResult result = new DefinitionResult
|
||||||
{
|
{
|
||||||
IsErrorResult = this.error,
|
IsErrorResult = this.error,
|
||||||
@@ -232,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal DefinitionResult GetDefinitionUsingDeclarationType(DeclarationType type, string databaseQualifiedName, string tokenText, string schemaName)
|
internal DefinitionResult GetDefinitionUsingDeclarationType(DeclarationType type, string databaseQualifiedName, string tokenText, string schemaName)
|
||||||
{
|
{
|
||||||
if (sqlObjectTypes.ContainsKey(type))
|
if (sqlObjectTypes.TryGetValue(type, out string sqlObjectType))
|
||||||
{
|
{
|
||||||
// With SqlLogin authentication, the defaultSchema property throws an Exception when accessed.
|
// With SqlLogin authentication, the defaultSchema property throws an Exception when accessed.
|
||||||
// This workaround ensures that a schema name is present by attempting
|
// This workaround ensures that a schema name is present by attempting
|
||||||
@@ -246,8 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
Location[] locations = GetSqlObjectDefinition(
|
Location[] locations = GetSqlObjectDefinition(
|
||||||
tokenText,
|
tokenText,
|
||||||
schemaName,
|
schemaName,
|
||||||
sqlObjectTypes[type]
|
sqlObjectType);
|
||||||
);
|
|
||||||
DefinitionResult result = new DefinitionResult
|
DefinitionResult result = new DefinitionResult
|
||||||
{
|
{
|
||||||
IsErrorResult = this.error,
|
IsErrorResult = this.error,
|
||||||
@@ -288,7 +286,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
string[] lines = File.ReadAllLines(tempFileName);
|
string[] lines = File.ReadAllLines(tempFileName);
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
string createSyntax = null;
|
string createSyntax = null;
|
||||||
if (objectScriptMap.ContainsKey(objectType.ToLower()))
|
if (objectScriptMap.ContainsKey(objectType.ToLower(System.Globalization.CultureInfo.InvariantCulture)))
|
||||||
{
|
{
|
||||||
createSyntax = string.Format("CREATE");
|
createSyntax = string.Format("CREATE");
|
||||||
foreach (string line in lines)
|
foreach (string line in lines)
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
|||||||
|
|
||||||
// Leaving the server name blank will automatically match whatever the server SMO is running against.
|
// Leaving the server name blank will automatically match whatever the server SMO is running against.
|
||||||
StringBuilder urnBuilder = new StringBuilder();
|
StringBuilder urnBuilder = new StringBuilder();
|
||||||
urnBuilder.AppendFormat("Server[@Name='{0}']/", server.ToUpper());
|
urnBuilder.AppendFormat("Server[@Name='{0}']/", server.ToUpper(System.Globalization.CultureInfo.InvariantCulture));
|
||||||
urnBuilder.AppendFormat("Database[@Name='{0}']/", Urn.EscapeString(database));
|
urnBuilder.AppendFormat("Database[@Name='{0}']/", Urn.EscapeString(database));
|
||||||
|
|
||||||
bool hasParentObject = !string.IsNullOrWhiteSpace(scriptingObject.ParentName)
|
bool hasParentObject = !string.IsNullOrWhiteSpace(scriptingObject.ParentName)
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
|||||||
|
|
||||||
public T GetValue(string displayName)
|
public T GetValue(string displayName)
|
||||||
{
|
{
|
||||||
if (this.Mapping.ContainsKey(displayName))
|
if (this.Mapping.TryGetValue(displayName, out T value))
|
||||||
{
|
{
|
||||||
return this.Mapping[displayName];
|
return value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ClientUri?.ToLower();
|
return ClientUri?.ToLower(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides utilities for converting from SQL script syntax into POCOs.
|
/// Provides utilities for converting from SQL script syntax into POCOs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class FromSqlScript
|
public static partial class FromSqlScript
|
||||||
{
|
{
|
||||||
// Regex: optionally starts with N, captures string wrapped in single quotes
|
// Regex: optionally starts with N, captures string wrapped in single quotes
|
||||||
private static readonly Regex StringRegex = new Regex("^N?'(.*)'$", RegexOptions.Compiled);
|
[GeneratedRegex("^N?'(.*)'$", RegexOptions.Compiled)]
|
||||||
private static readonly Regex BracketRegex = new Regex(@"^\[(.*)\]$", RegexOptions.Compiled);
|
private static partial Regex GetStringRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^\\[(.*)\\]$", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetBracketRegex();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes a multipart identifier as used in a SQL script into an array of the multiple
|
/// Decodes a multipart identifier as used in a SQL script into an array of the multiple
|
||||||
@@ -35,8 +38,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
/// </exception>
|
/// </exception>
|
||||||
public static string[] DecodeMultipartIdentifier(string multipartIdentifier)
|
public static string[] DecodeMultipartIdentifier(string multipartIdentifier)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
List<string> namedParts = new List<string>();
|
var namedParts = new List<string>();
|
||||||
bool insideBrackets = false;
|
bool insideBrackets = false;
|
||||||
bool bracketsClosed = false;
|
bool bracketsClosed = false;
|
||||||
for (int i = 0; i < multipartIdentifier.Length; i++)
|
for (int i = 0; i < multipartIdentifier.Length; i++)
|
||||||
@@ -122,7 +125,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
literal = literal.Trim('(', ')');
|
literal = literal.Trim('(', ')');
|
||||||
|
|
||||||
// Attempt to unwrap inverted commas around a string
|
// Attempt to unwrap inverted commas around a string
|
||||||
Match match = StringRegex.Match(literal);
|
Match match = GetStringRegex().Match(literal);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
// Like: N'stuff' or 'stuff'
|
// Like: N'stuff' or 'stuff'
|
||||||
@@ -136,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identifer">Identifier to check.</param>
|
/// <param name="identifer">Identifier to check.</param>
|
||||||
/// <returns>Boolean indicating if identifier is escaped with brackets.</returns>
|
/// <returns>Boolean indicating if identifier is escaped with brackets.</returns>
|
||||||
public static bool IsIdentifierBracketed(string identifer) => BracketRegex.IsMatch(identifer);
|
public static bool IsIdentifierBracketed(string identifer) => GetBracketRegex().IsMatch(identifer);
|
||||||
|
|
||||||
#region Private Helpers
|
#region Private Helpers
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace.Contracts
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id
|
public string Id
|
||||||
{
|
{
|
||||||
get { return this.ClientUri.ToLower(); }
|
get { return this.ClientUri.ToLower(System.Globalization.CultureInfo.InvariantCulture); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
/// Manages a "workspace" of script files that are open for a particular
|
/// Manages a "workspace" of script files that are open for a particular
|
||||||
/// editing session. Also helps to navigate references between ScriptFiles.
|
/// editing session. Also helps to navigate references between ScriptFiles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Workspace : IDisposable
|
public partial class Workspace : IDisposable
|
||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
}
|
}
|
||||||
// This method allows FileNotFoundException to bubble up
|
// This method allows FileNotFoundException to bubble up
|
||||||
// if the file isn't found.
|
// if the file isn't found.
|
||||||
using (FileStream fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
using (var fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
||||||
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
scriptFile = new ScriptFile(resolvedFile.FilePath, resolvedFile.ClientUri,streamReader);
|
scriptFile = new ScriptFile(resolvedFile.FilePath, resolvedFile.ClientUri,streamReader);
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
|
|
||||||
// Client sent the path in URI format, extract the local path and trim
|
// Client sent the path in URI format, extract the local path and trim
|
||||||
// any extraneous slashes
|
// any extraneous slashes
|
||||||
Uri fileUri = new Uri(clientUri);
|
var fileUri = new Uri(clientUri);
|
||||||
filePath = fileUri.LocalPath;
|
filePath = fileUri.LocalPath;
|
||||||
if (filePath.StartsWith("//") || filePath.StartsWith("\\\\") || filePath.StartsWith("/"))
|
if (filePath.StartsWith("//") || filePath.StartsWith("\\\\") || filePath.StartsWith("/"))
|
||||||
{
|
{
|
||||||
@@ -208,7 +208,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Regex.Replace(path, @"`(?=[ \[\]])", "");
|
return GetEscapeRegex().Replace(path, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -363,6 +363,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("`(?=[ \\[\\]])")]
|
||||||
|
private static partial Regex GetEscapeRegex();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using System.IO;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.AzureFunctions
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.AzureFunctions
|
||||||
{
|
{
|
||||||
class AzureFunctionsServiceTests
|
internal sealed class AzureFunctionsServiceTests
|
||||||
{
|
{
|
||||||
private string testAzureFunctionsFolder = Path.Combine("..", "..", "..", "AzureFunctions", "AzureFunctionTestFiles");
|
private string testAzureFunctionsFolder = Path.Combine("..", "..", "..", "AzureFunctions", "AzureFunctionTestFiles");
|
||||||
|
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ReliableConnectionTests
|
public class ReliableConnectionTests
|
||||||
{
|
{
|
||||||
internal class TestDataTransferErrorDetectionStrategy : DataTransferErrorDetectionStrategy
|
internal sealed class TestDataTransferErrorDetectionStrategy : DataTransferErrorDetectionStrategy
|
||||||
{
|
{
|
||||||
public bool InvokeCanRetrySqlException(SqlException exception)
|
public bool InvokeCanRetrySqlException(SqlException exception)
|
||||||
{
|
{
|
||||||
return CanRetrySqlException(exception);
|
return CanRetrySqlException(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal class TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy : SqlAzureTemporaryAndIgnorableErrorDetectionStrategy
|
internal sealed class TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy : SqlAzureTemporaryAndIgnorableErrorDetectionStrategy
|
||||||
{
|
{
|
||||||
public TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy()
|
public TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy()
|
||||||
: base (new int[] { 100 })
|
: base (new int[] { 100 })
|
||||||
@@ -54,7 +54,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestFixedDelayPolicy : FixedDelayPolicy
|
internal sealed class TestFixedDelayPolicy : FixedDelayPolicy
|
||||||
{
|
{
|
||||||
public TestFixedDelayPolicy(
|
public TestFixedDelayPolicy(
|
||||||
IErrorDetectionStrategy strategy,
|
IErrorDetectionStrategy strategy,
|
||||||
@@ -77,7 +77,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestProgressiveRetryPolicy : ProgressiveRetryPolicy
|
internal sealed class TestProgressiveRetryPolicy : ProgressiveRetryPolicy
|
||||||
{
|
{
|
||||||
public TestProgressiveRetryPolicy(
|
public TestProgressiveRetryPolicy(
|
||||||
IErrorDetectionStrategy strategy,
|
IErrorDetectionStrategy strategy,
|
||||||
@@ -97,7 +97,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestTimeBasedRetryPolicy : TimeBasedRetryPolicy
|
internal sealed class TestTimeBasedRetryPolicy : TimeBasedRetryPolicy
|
||||||
{
|
{
|
||||||
public TestTimeBasedRetryPolicy(
|
public TestTimeBasedRetryPolicy(
|
||||||
IErrorDetectionStrategy strategy,
|
IErrorDetectionStrategy strategy,
|
||||||
@@ -916,7 +916,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
|
|||||||
command.UpdatedRowSource = UpdateRowSource.None;
|
command.UpdatedRowSource = UpdateRowSource.None;
|
||||||
Assert.AreEqual(UpdateRowSource.None, command.UpdatedRowSource);
|
Assert.AreEqual(UpdateRowSource.None, command.UpdatedRowSource);
|
||||||
Assert.NotNull(command.GetUnderlyingCommand());
|
Assert.NotNull(command.GetUnderlyingCommand());
|
||||||
Assert.Throws<InvalidOperationException>(() => command.ValidateConnectionIsSet());
|
Assert.Throws<InvalidOperationException>(command.ValidateConnectionIsSet);
|
||||||
command.Prepare();
|
command.Prepare();
|
||||||
Assert.NotNull(command.CreateParameter());
|
Assert.NotNull(command.CreateParameter());
|
||||||
command.Cancel();
|
command.Cancel();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnec
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DisasterRecovery
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DisasterRecovery
|
||||||
{
|
{
|
||||||
class BackupRestoreUrlTests
|
internal sealed class BackupRestoreUrlTests
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create simple backup test
|
/// Create simple backup test
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DisasterRecovery
|
|||||||
string backUpFilePath = string.Empty;
|
string backUpFilePath = string.Empty;
|
||||||
if (backupFileNames != null)
|
if (backupFileNames != null)
|
||||||
{
|
{
|
||||||
var filePaths = backupFileNames.Select(x => GetBackupFilePath(x));
|
var filePaths = backupFileNames.Select(GetBackupFilePath);
|
||||||
backUpFilePath = filePaths.Aggregate((current, next) => current + " ," + next);
|
backUpFilePath = filePaths.Aggregate((current, next) => current + " ," + next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
|
|||||||
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
||||||
{
|
{
|
||||||
Uri = scriptFile.ClientUri,
|
Uri = scriptFile.ClientUri,
|
||||||
Language = LanguageService.SQL_LANG.ToLower(),
|
Language = LanguageService.SQL_LANG.ToLower(System.Globalization.CultureInfo.InvariantCulture),
|
||||||
Flavor = "MSSQL"
|
Flavor = "MSSQL"
|
||||||
}, eventContextSql.Object);
|
}, eventContextSql.Object);
|
||||||
await langService.DelayedDiagnosticsTask; // to ensure completion and validation before moveing to next step
|
await langService.DelayedDiagnosticsTask; // to ensure completion and validation before moveing to next step
|
||||||
@@ -379,7 +379,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
|
|||||||
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
||||||
{
|
{
|
||||||
Uri = scriptFile.ClientUri,
|
Uri = scriptFile.ClientUri,
|
||||||
Language = LanguageService.SQL_CMD_LANG.ToLower(),
|
Language = LanguageService.SQL_CMD_LANG.ToLower(System.Globalization.CultureInfo.InvariantCulture),
|
||||||
Flavor = "MSSQL"
|
Flavor = "MSSQL"
|
||||||
}, eventContextSqlCmd.Object);
|
}, eventContextSqlCmd.Object);
|
||||||
await langService.DelayedDiagnosticsTask;
|
await langService.DelayedDiagnosticsTask;
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
<PackageId>Microsoft.SqlTools.ServiceLayer.IntegrationTests</PackageId>
|
<PackageId>Microsoft.SqlTools.ServiceLayer.IntegrationTests</PackageId>
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
|
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
|
||||||
<NoWarn>$(NoWarn);SYSLIB1045;IDE0200;IDE0230;CA1311;CA1852;CA1854</NoWarn>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../src/Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
|
<ProjectReference Include="../../src/Microsoft.SqlTools.Hosting/Microsoft.SqlTools.Hosting.csproj" />
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ using static Microsoft.SqlTools.ServiceLayer.ObjectExplorer.ObjectExplorerServic
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
||||||
{
|
{
|
||||||
public class ObjectExplorerServiceTests
|
public partial class ObjectExplorerServiceTests
|
||||||
{
|
{
|
||||||
private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService;
|
private ObjectExplorerService _service = TestServiceProvider.Instance.ObjectExplorerService;
|
||||||
|
|
||||||
@@ -124,10 +124,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
{
|
{
|
||||||
var query = "";
|
var query = "";
|
||||||
string databaseName = "#testDb#";
|
string databaseName = "#testDb#";
|
||||||
await RunTest(databaseName, query, "TestDb", async (testDbName, session) =>
|
await RunTest(databaseName, query, "TestDb", ExpandAndVerifyDatabaseNode);
|
||||||
{
|
|
||||||
await ExpandAndVerifyDatabaseNode(testDbName, session);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -376,7 +373,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);
|
||||||
//connectParams.Connection.Pooling = false;
|
//connectParams.Connection.Pooling = false;
|
||||||
ConnectionDetails details = connectParams.Connection;
|
ConnectionDetails details = connectParams.Connection;
|
||||||
string uri = ObjectExplorerService.GenerateUri(details);
|
string uri = GenerateUri(details);
|
||||||
|
|
||||||
var session = await _service.DoCreateSession(details, uri);
|
var session = await _service.DoCreateSession(details, uri);
|
||||||
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "OE session created for database: {0}", databaseName));
|
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "OE session created for database: {0}", databaseName));
|
||||||
@@ -387,10 +384,10 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
{
|
{
|
||||||
Assert.That(session, Is.Not.Null, nameof(session));
|
Assert.That(session, Is.Not.Null, nameof(session));
|
||||||
Assert.That(session.Root, Is.Not.Null, nameof(session.Root));
|
Assert.That(session.Root, Is.Not.Null, nameof(session.Root));
|
||||||
NodeInfo nodeInfo = session.Root.ToNodeInfo();
|
var nodeInfo = session.Root.ToNodeInfo();
|
||||||
Assert.That(nodeInfo.IsLeaf, Is.False, "Should not be a leaf node");
|
Assert.That(nodeInfo.IsLeaf, Is.False, "Should not be a leaf node");
|
||||||
|
|
||||||
NodeInfo? databaseNode = null;
|
NodeInfo databaseNode = null;
|
||||||
|
|
||||||
if (serverNode)
|
if (serverNode)
|
||||||
{
|
{
|
||||||
@@ -435,7 +432,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
{
|
{
|
||||||
Assert.NotNull(session);
|
Assert.NotNull(session);
|
||||||
Assert.NotNull(session.Root);
|
Assert.NotNull(session.Root);
|
||||||
NodeInfo nodeInfo = session.Root.ToNodeInfo();
|
var nodeInfo = session.Root.ToNodeInfo();
|
||||||
Assert.AreEqual(false, nodeInfo.IsLeaf);
|
Assert.AreEqual(false, nodeInfo.IsLeaf);
|
||||||
Assert.AreEqual(nodeInfo.NodeType, NodeTypes.Database.ToString());
|
Assert.AreEqual(nodeInfo.NodeType, NodeTypes.Database.ToString());
|
||||||
Assert.True(nodeInfo.Label.Contains(databaseName));
|
Assert.True(nodeInfo.Label.Contains(databaseName));
|
||||||
@@ -457,7 +454,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
Console.WriteLine($"Session closed uri:{uri}");
|
Console.WriteLine($"Session closed uri:{uri}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session, StringBuilder? stringBuilder = null, bool verifySystemObjects = false)
|
private async Task ExpandTree(NodeInfo node, ObjectExplorerSession session, StringBuilder stringBuilder = null, bool verifySystemObjects = false)
|
||||||
{
|
{
|
||||||
if (node != null && !node.IsLeaf)
|
if (node != null && !node.IsLeaf)
|
||||||
{
|
{
|
||||||
@@ -552,7 +549,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
private async Task<bool> VerifyObjectExplorerTest(string databaseName, string testDbPrefix, string queryFileName, string baselineFileName, bool verifySystemObjects = false)
|
private async Task<bool> VerifyObjectExplorerTest(string databaseName, string testDbPrefix, string queryFileName, string baselineFileName, bool verifySystemObjects = false)
|
||||||
{
|
{
|
||||||
var query = string.IsNullOrEmpty(queryFileName) ? string.Empty : LoadScript(queryFileName);
|
var query = string.IsNullOrEmpty(queryFileName) ? string.Empty : LoadScript(queryFileName);
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
var stringBuilder = new StringBuilder();
|
||||||
await RunTest(databaseName, query, testDbPrefix, async (testDbName, session) =>
|
await RunTest(databaseName, query, testDbPrefix, async (testDbName, session) =>
|
||||||
{
|
{
|
||||||
await ExpandServerNodeAndVerifyDatabaseHierachy(testDbName, session, false);
|
await ExpandServerNodeAndVerifyDatabaseHierachy(testDbName, session, false);
|
||||||
@@ -564,7 +561,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
|
|
||||||
// Dropped ledger objects have a randomly generated GUID appended to their name when they are deleted
|
// Dropped ledger objects have a randomly generated GUID appended to their name when they are deleted
|
||||||
// For testing purposes, those guids need to be replaced with a deterministic string
|
// For testing purposes, those guids need to be replaced with a deterministic string
|
||||||
actual = Regex.Replace(actual, "[A-Z0-9]{32}", "<<NonDeterministic>>");
|
actual = GetBaselineRegex().Replace(actual, "<<NonDeterministic>>");
|
||||||
|
|
||||||
// Write output to a bin directory for easier comparison
|
// Write output to a bin directory for easier comparison
|
||||||
string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty;
|
string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty;
|
||||||
@@ -640,5 +637,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectExplorer
|
|||||||
FileInfo inputFile = GetBaseLineFile(fileName);
|
FileInfo inputFile = GetBaseLineFile(fileName);
|
||||||
return TestUtilities.ReadTextAndNormalizeLineEndings(inputFile.FullName);
|
return TestUtilities.ReadTextAndNormalizeLineEndings(inputFile.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("[A-Z0-9]{32}")]
|
||||||
|
private static partial Regex GetBaselineRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.AutoParameterization
|
|||||||
// SQL greater than 300000 characters should throw
|
// SQL greater than 300000 characters should throw
|
||||||
string bigSql = string.Concat(Repeat(element: sqlLength_300, count: 1100));
|
string bigSql = string.Concat(Repeat(element: sqlLength_300, count: 1100));
|
||||||
DbCommand command2 = new SqlCommand { CommandText = bigSql };
|
DbCommand command2 = new SqlCommand { CommandText = bigSql };
|
||||||
Assert.Throws<ParameterizationScriptTooLargeException>(() => command2.Parameterize());
|
Assert.Throws<ParameterizationScriptTooLargeException>(command2.Parameterize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -128,7 +128,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.AutoParameterization
|
|||||||
string sql = string.Concat(Repeat(element: invalidSql, count: 1000));
|
string sql = string.Concat(Repeat(element: invalidSql, count: 1000));
|
||||||
DbCommand command = new SqlCommand { CommandText = sql };
|
DbCommand command = new SqlCommand { CommandText = sql };
|
||||||
|
|
||||||
Assert.Throws<ParameterizationParsingException>(() => command.Parameterize());
|
Assert.Throws<ParameterizationParsingException>(command.Parameterize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -149,7 +149,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.AutoParameterization
|
|||||||
GO";
|
GO";
|
||||||
|
|
||||||
DbCommand command = new SqlCommand { CommandText = sql };
|
DbCommand command = new SqlCommand { CommandText = sql };
|
||||||
Assert.Throws<ParameterizationFormatException>(() => command.Parameterize());
|
Assert.Throws<ParameterizationFormatException>(command.Parameterize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using Azure.Storage.Sas;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.DisasterRecovery
|
||||||
{
|
{
|
||||||
class SharedAccessSignatureCreatorTests
|
internal sealed class SharedAccessSignatureCreatorTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void GetServiceSasUriForContainerReturnsNullWhenCannotGenerateSasUri()
|
public void GetServiceSasUriForContainerReturnsNullWhenCannotGenerateSasUri()
|
||||||
|
|||||||
@@ -105,8 +105,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
yield return new object[] {"0x000", new byte[] {0x00, 0x00}, "0x0000"}; // Base16, odd
|
yield return new object[] {"0x000", new byte[] {0x00, 0x00}, "0x0000"}; // Base16, odd
|
||||||
|
|
||||||
// Single byte tests
|
// Single byte tests
|
||||||
yield return new object[] {"50", new byte[] {0x32}, "0x32"}; // Base10
|
yield return new object[] {"50", "2"u8.ToArray(), "0x32"}; // Base10
|
||||||
yield return new object[] {"050", new byte[] {0x32}, "0x32"}; // Base10, leading zeros
|
yield return new object[] {"050", "2"u8.ToArray(), "0x32"}; // Base10, leading zeros
|
||||||
yield return new object[] {"0xF0", new byte[] {0xF0}, "0xF0"}; // Base16
|
yield return new object[] {"0xF0", new byte[] {0xF0}, "0xF0"}; // Base16
|
||||||
yield return new object[] {"0x0F", new byte[] {0x0F}, "0x0F"}; // Base16, leading zeros
|
yield return new object[] {"0x0F", new byte[] {0x0F}, "0x0F"}; // Base16, leading zeros
|
||||||
yield return new object[] {"0xF", new byte[] {0x0F}, "0x0F"}; // Base16, odd
|
yield return new object[] {"0xF", new byte[] {0x0F}, "0x0F"}; // Base16, odd
|
||||||
@@ -296,7 +296,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
return new DbColumnWrapper(new CellUpdateTestDbColumn(typeof(T), dataTypeName, allowNull, colSize));
|
return new DbColumnWrapper(new CellUpdateTestDbColumn(typeof(T), dataTypeName, allowNull, colSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CellUpdateTestDbColumn : DbColumn
|
private sealed class CellUpdateTestDbColumn : DbColumn
|
||||||
{
|
{
|
||||||
public CellUpdateTestDbColumn(Type dataType, string dataTypeName, bool allowNull = true, int? colSize = null)
|
public CellUpdateTestDbColumn(Type dataType, string dataTypeName, bool allowNull = true, int? colSize = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,18 +21,18 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
||||||
{
|
{
|
||||||
public class RowCreateTests
|
public partial class RowCreateTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public async Task RowCreateConstruction()
|
public async Task RowCreateConstruction()
|
||||||
{
|
{
|
||||||
// Setup: Create the values to store
|
// Setup: Create the values to store
|
||||||
const long rowId = 100;
|
const long rowId = 100;
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
|
|
||||||
// If: I create a RowCreate instance
|
// If: I create a RowCreate instance
|
||||||
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
|
var rc = new RowCreate(rowId, rs, data.TableMetadata);
|
||||||
|
|
||||||
// Then: The values I provided should be available
|
// Then: The values I provided should be available
|
||||||
Assert.AreEqual(rowId, rc.RowId);
|
Assert.AreEqual(rowId, rc.RowId);
|
||||||
@@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// Setup: Generate the parameters for the row create
|
// Setup: Generate the parameters for the row create
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I ask for a script to be generated without setting any values
|
// If: I ask for a script to be generated without setting any values
|
||||||
// Then: An exception should be thrown for missing cells
|
// Then: An exception should be thrown for missing cells
|
||||||
@@ -116,11 +116,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the parameters for the row create
|
// ... Generate the parameters for the row create
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, colsWithDefaultConstraints, colsThatAllowNull);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, colsWithDefaultConstraints, colsThatAllowNull);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
|
|
||||||
// ... Create a row create and set the appropriate number of cells
|
// ... Create a row create and set the appropriate number of cells
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
Common.AddCells(rc, valuesToSkipSetting);
|
Common.AddCells(rc, valuesToSkipSetting);
|
||||||
|
|
||||||
// If: I ask for the script for the row insert
|
// If: I ask for the script for the row insert
|
||||||
@@ -139,8 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
if (expectedOutput == null)
|
if (expectedOutput == null)
|
||||||
{
|
{
|
||||||
// If expected output was null make sure we match the default values reges
|
// If expected output was null make sure we match the default values reges
|
||||||
Regex r = new Regex(@"INSERT INTO (.+) DEFAULT VALUES");
|
Match m = GetInsert1Regex().Match(sql);
|
||||||
Match m = r.Match(sql);
|
|
||||||
Assert.True(m.Success);
|
Assert.True(m.Success);
|
||||||
|
|
||||||
// Table name matches
|
// Table name matches
|
||||||
@@ -149,8 +148,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Do the whole validation
|
// Do the whole validation
|
||||||
Regex r = new Regex(@"INSERT INTO (.+)\((.+)\) VALUES \((.+)\)");
|
Match m = GetInsert2Regex().Match(sql);
|
||||||
Match m = r.Match(sql);
|
|
||||||
Assert.True(m.Success);
|
Assert.True(m.Success);
|
||||||
|
|
||||||
// Table name matches
|
// Table name matches
|
||||||
@@ -174,14 +172,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the parameters for the row create
|
// ... Generate the parameters for the row create
|
||||||
const long rowId = 100;
|
const long rowId = 100;
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
|
|
||||||
// ... Setup a db reader for the result of an insert
|
// ... Setup a db reader for the result of an insert
|
||||||
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
|
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
|
||||||
|
|
||||||
// If: I ask for the change to be applied
|
// If: I ask for the change to be applied
|
||||||
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
|
var rc = new RowCreate(rowId, rs, data.TableMetadata);
|
||||||
await rc.ApplyChanges(newRowReader);
|
await rc.ApplyChanges(newRowReader);
|
||||||
|
|
||||||
// Then: The result set should have an additional row in it
|
// Then: The result set should have an additional row in it
|
||||||
@@ -226,9 +224,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the row create object
|
// ... Generate the row create object
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
|
|
||||||
// ... Create a mock db connection for building the command
|
// ... Create a mock db connection for building the command
|
||||||
var mockConn = new TestSqlConnection();
|
var mockConn = new TestSqlConnection();
|
||||||
@@ -280,14 +278,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the parameters for the row create
|
// ... Generate the parameters for the row create
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
|
|
||||||
// ... Mock db connection for building the command
|
// ... Mock db connection for building the command
|
||||||
var mockConn = new TestSqlConnection(null);
|
var mockConn = new TestSqlConnection(null);
|
||||||
|
|
||||||
// ... Create a row create and set the appropriate number of cells
|
// ... Create a row create and set the appropriate number of cells
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
Common.AddCells(rc, valuesToSkip);
|
Common.AddCells(rc, valuesToSkip);
|
||||||
|
|
||||||
// If: I ask for the command for the row insert
|
// If: I ask for the command for the row insert
|
||||||
@@ -311,8 +309,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
Assert.AreEqual(3, splitSql.Length);
|
Assert.AreEqual(3, splitSql.Length);
|
||||||
|
|
||||||
// Check the declare statement first
|
// Check the declare statement first
|
||||||
Regex declareRegex = new Regex(@"^DECLARE @(.+) TABLE \((.+)\)$");
|
Match declareMatch = GetDeclareRegex().Match(splitSql[0]);
|
||||||
Match declareMatch = declareRegex.Match(splitSql[0]);
|
|
||||||
Assert.True(declareMatch.Success);
|
Assert.True(declareMatch.Success);
|
||||||
|
|
||||||
// Declared table name matches
|
// Declared table name matches
|
||||||
@@ -327,7 +324,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
if (expectedOutput.ExpectedInColumns == 0 || expectedOutput.ExpectedInValues == 0)
|
if (expectedOutput.ExpectedInColumns == 0 || expectedOutput.ExpectedInValues == 0)
|
||||||
{
|
{
|
||||||
// If expected output was null make sure we match the default values reges
|
// If expected output was null make sure we match the default values reges
|
||||||
Regex insertRegex = new Regex(@"^INSERT INTO (.+) OUTPUT (.+) INTO @(.+) DEFAULT VALUES$");
|
var insertRegex = GetInsertRegex();
|
||||||
Match insertMatch = insertRegex.Match(splitSql[1]);
|
Match insertMatch = insertRegex.Match(splitSql[1]);
|
||||||
Assert.True(insertMatch.Success);
|
Assert.True(insertMatch.Success);
|
||||||
|
|
||||||
@@ -347,7 +344,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Do the whole validation
|
// Do the whole validation
|
||||||
Regex insertRegex = new Regex(@"^INSERT INTO (.+)\((.+)\) OUTPUT (.+) INTO @(.+) VALUES \((.+)\)$");
|
var insertRegex = GetInsertFullRegex();
|
||||||
Match insertMatch = insertRegex.Match(splitSql[1]);
|
Match insertMatch = insertRegex.Match(splitSql[1]);
|
||||||
Assert.True(insertMatch.Success);
|
Assert.True(insertMatch.Success);
|
||||||
|
|
||||||
@@ -380,7 +377,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the select statement last
|
// Check the select statement last
|
||||||
Regex selectRegex = new Regex(@"^SELECT (.+) FROM @(.+)$");
|
var selectRegex = GetSelectRegex();
|
||||||
Match selectMatch = selectRegex.Match(splitSql[2]);
|
Match selectMatch = selectRegex.Match(splitSql[2]);
|
||||||
Assert.True(selectMatch.Success);
|
Assert.True(selectMatch.Success);
|
||||||
|
|
||||||
@@ -425,9 +422,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup: Generate a row create with default values
|
// Setup: Generate a row create with default values
|
||||||
const long rowId = 100;
|
const long rowId = 100;
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 3, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 3, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
|
var rc = new RowCreate(rowId, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I request an edit row from the row create
|
// If: I request an edit row from the row create
|
||||||
EditRow er = rc.GetEditRow(null);
|
EditRow er = rc.GetEditRow(null);
|
||||||
@@ -451,9 +448,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup: Generate a row create with an identity column
|
// Setup: Generate a row create with an identity column
|
||||||
const long rowId = 100;
|
const long rowId = 100;
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
|
||||||
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
|
var rc = new RowCreate(rowId, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I request an edit row from the row created
|
// If: I request an edit row from the row created
|
||||||
EditRow er = rc.GetEditRow(null);
|
EditRow er = rc.GetEditRow(null);
|
||||||
@@ -573,7 +570,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var etm = Common.GetCustomEditTableMetadata(cols);
|
var etm = Common.GetCustomEditTableMetadata(cols);
|
||||||
|
|
||||||
// ... Create the row create
|
// ... Create the row create
|
||||||
RowCreate rc = new RowCreate(100, rs, etm);
|
var rc = new RowCreate(100, rs, etm);
|
||||||
|
|
||||||
// If: I set a cell in the newly created row to something that will be corrected
|
// If: I set a cell in the newly created row to something that will be corrected
|
||||||
EditUpdateCellResult eucr = rc.SetCell(0, "1000");
|
EditUpdateCellResult eucr = rc.SetCell(0, "1000");
|
||||||
@@ -644,9 +641,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the parameters for the row create
|
// ... Generate the parameters for the row create
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I attempt to revert a cell that has not been set
|
// If: I attempt to revert a cell that has not been set
|
||||||
EditRevertCellResult result = rc.RevertCell(0);
|
EditRevertCellResult result = rc.RevertCell(0);
|
||||||
@@ -673,9 +670,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the parameters for the row create
|
// ... Generate the parameters for the row create
|
||||||
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
|
||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
|
var rc = new RowCreate(100, rs, data.TableMetadata);
|
||||||
rc.SetCell(0, "1");
|
rc.SetCell(0, "1");
|
||||||
|
|
||||||
// If: I attempt to revert a cell that was set
|
// If: I attempt to revert a cell that was set
|
||||||
@@ -720,5 +717,25 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
public int ExpectedInValues { get; }
|
public int ExpectedInValues { get; }
|
||||||
public int ExpectedOutColumns { get; }
|
public int ExpectedOutColumns { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Generated Regex
|
||||||
|
[GeneratedRegex("INSERT INTO (.+) DEFAULT VALUES")]
|
||||||
|
private static partial Regex GetInsert1Regex();
|
||||||
|
|
||||||
|
[GeneratedRegex("INSERT INTO (.+)\\((.+)\\) VALUES \\((.+)\\)")]
|
||||||
|
private static partial Regex GetInsert2Regex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^DECLARE @(.+) TABLE \\((.+)\\)$")]
|
||||||
|
private static partial Regex GetDeclareRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^INSERT INTO (.+) OUTPUT (.+) INTO @(.+) DEFAULT VALUES$")]
|
||||||
|
private static partial Regex GetInsertRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^INSERT INTO (.+)\\((.+)\\) OUTPUT (.+) INTO @(.+) VALUES \\((.+)\\)$")]
|
||||||
|
private static partial Regex GetInsertFullRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^SELECT (.+) FROM @(.+)$")]
|
||||||
|
private static partial Regex GetSelectRegex();
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
return resultSet;
|
return resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RowEditTester : RowEditBase
|
private sealed class RowEditTester : RowEditBase
|
||||||
{
|
{
|
||||||
public RowEditTester(ResultSet rs, EditTableMetadata meta) : base(0, rs, meta) { }
|
public RowEditTester(ResultSet rs, EditTableMetadata meta) : base(0, rs, meta) { }
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
||||||
{
|
{
|
||||||
public class RowUpdateTests
|
public partial class RowUpdateTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public async Task RowUpdateConstruction()
|
public async Task RowUpdateConstruction()
|
||||||
@@ -32,7 +32,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
|
|
||||||
// If: I create a RowUpdate instance
|
// If: I create a RowUpdate instance
|
||||||
RowUpdate rc = new RowUpdate(rowId, rs, data.TableMetadata);
|
var rc = new RowUpdate(rowId, rs, data.TableMetadata);
|
||||||
|
|
||||||
// Then: The values I provided should be available
|
// Then: The values I provided should be available
|
||||||
Assert.AreEqual(rowId, rc.RowId);
|
Assert.AreEqual(rowId, rc.RowId);
|
||||||
@@ -61,7 +61,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
|
|
||||||
// If:
|
// If:
|
||||||
// ... I add updates to all the cells in the row
|
// ... I add updates to all the cells in the row
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
Common.AddCells(ru, 1);
|
Common.AddCells(ru, 1);
|
||||||
|
|
||||||
// ... Then I update a cell back to it's old value
|
// ... Then I update a cell back to it's old value
|
||||||
@@ -83,8 +83,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
Assert.True(eucr.IsRowDirty);
|
Assert.True(eucr.IsRowDirty);
|
||||||
|
|
||||||
// ... It should be formatted as an update script
|
// ... It should be formatted as an update script
|
||||||
Regex r = new Regex(@"UPDATE .+ SET (.*) WHERE");
|
var m = GetUpdateRegex().Match(ru.GetScript());
|
||||||
var m = r.Match(ru.GetScript());
|
|
||||||
|
|
||||||
// ... It should have 2 updates
|
// ... It should have 2 updates
|
||||||
string updates = m.Groups[1].Value;
|
string updates = m.Groups[1].Value;
|
||||||
@@ -102,7 +101,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
|
|
||||||
// If:
|
// If:
|
||||||
// ... I add updates to one cell in the row
|
// ... I add updates to one cell in the row
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
ru.SetCell(1, "qqq");
|
ru.SetCell(1, "qqq");
|
||||||
|
|
||||||
// ... Then I update the cell to its original value
|
// ... Then I update the cell to its original value
|
||||||
@@ -149,7 +148,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var etm = Common.GetCustomEditTableMetadata(cols);
|
var etm = Common.GetCustomEditTableMetadata(cols);
|
||||||
|
|
||||||
// ... Create the row update
|
// ... Create the row update
|
||||||
RowUpdate ru = new RowUpdate(0, rs, etm);
|
var ru = new RowUpdate(0, rs, etm);
|
||||||
|
|
||||||
// If: I set a cell in the newly created row to something that will be corrected
|
// If: I set a cell in the newly created row to something that will be corrected
|
||||||
EditUpdateCellResult eucr = ru.SetCell(0, "1000");
|
EditUpdateCellResult eucr = ru.SetCell(0, "1000");
|
||||||
@@ -214,7 +213,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
|
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
|
||||||
|
|
||||||
// If: I ask for a script to be generated for update
|
// If: I ask for a script to be generated for update
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
Common.AddCells(ru, 1);
|
Common.AddCells(ru, 1);
|
||||||
string script = ru.GetScript();
|
string script = ru.GetScript();
|
||||||
|
|
||||||
@@ -226,7 +225,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
string regexString = isMemoryOptimized
|
string regexString = isMemoryOptimized
|
||||||
? @"UPDATE (.+) WITH \(SNAPSHOT\) SET (.*) WHERE .+"
|
? @"UPDATE (.+) WITH \(SNAPSHOT\) SET (.*) WHERE .+"
|
||||||
: @"UPDATE (.+) SET (.*) WHERE .+";
|
: @"UPDATE (.+) SET (.*) WHERE .+";
|
||||||
Regex r = new Regex(regexString);
|
var r = new Regex(regexString);
|
||||||
var m = r.Match(script);
|
var m = r.Match(script);
|
||||||
Assert.True(m.Success);
|
Assert.True(m.Success);
|
||||||
|
|
||||||
@@ -248,7 +247,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update with cell updates
|
// ... Create a row update with cell updates
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
Common.AddCells(ru, includeIdentity ? 1 : 0);
|
Common.AddCells(ru, includeIdentity ? 1 : 0);
|
||||||
|
|
||||||
// ... Mock db connection for building the command
|
// ... Mock db connection for building the command
|
||||||
@@ -267,8 +266,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
Assert.True(splitSql.Length >= 3);
|
Assert.True(splitSql.Length >= 3);
|
||||||
|
|
||||||
// Check the declare statement first
|
// Check the declare statement first
|
||||||
Regex declareRegex = new Regex(@"^DECLARE @(.+) TABLE \((.+)\)$");
|
Match declareMatch = GetDeclareTableRegex().Match(splitSql[0]);
|
||||||
Match declareMatch = declareRegex.Match(splitSql[0]);
|
|
||||||
Assert.True(declareMatch.Success);
|
Assert.True(declareMatch.Success);
|
||||||
|
|
||||||
// Declared table name matches
|
// Declared table name matches
|
||||||
@@ -283,7 +281,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
string regex = isMemoryOptimized
|
string regex = isMemoryOptimized
|
||||||
? @"^UPDATE (.+) WITH \(SNAPSHOT\) SET (.+) OUTPUT (.+) INTO @(.+) WHERE .+$"
|
? @"^UPDATE (.+) WITH \(SNAPSHOT\) SET (.+) OUTPUT (.+) INTO @(.+) WHERE .+$"
|
||||||
: @"^UPDATE (.+) SET (.+) OUTPUT (.+) INTO @(.+) WHERE .+$";
|
: @"^UPDATE (.+) SET (.+) OUTPUT (.+) INTO @(.+) WHERE .+$";
|
||||||
Regex updateRegex = new Regex(regex);
|
var updateRegex = new Regex(regex);
|
||||||
Match updateMatch = updateRegex.Match(splitSql[10]);
|
Match updateMatch = updateRegex.Match(splitSql[10]);
|
||||||
Assert.True(updateMatch.Success);
|
Assert.True(updateMatch.Success);
|
||||||
|
|
||||||
@@ -304,8 +302,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
Assert.That(updateMatch.Groups[4].Value, Does.EndWith("Output"));
|
Assert.That(updateMatch.Groups[4].Value, Does.EndWith("Output"));
|
||||||
|
|
||||||
// Check the select statement last
|
// Check the select statement last
|
||||||
Regex selectRegex = new Regex(@"^SELECT (.+) FROM @(.+)$");
|
Match selectMatch = GetSelectRegex().Match(splitSql[11]);
|
||||||
Match selectMatch = selectRegex.Match(splitSql[11]);
|
|
||||||
Assert.True(selectMatch.Success);
|
Assert.True(selectMatch.Success);
|
||||||
|
|
||||||
// Correct number of columns in select statement
|
// Correct number of columns in select statement
|
||||||
@@ -343,7 +340,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// Setup: Create a row update with a cell set
|
// Setup: Create a row update with a cell set
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
ru.SetCell(0, "foo");
|
ru.SetCell(0, "foo");
|
||||||
|
|
||||||
// If: I attempt to get an edit row
|
// If: I attempt to get an edit row
|
||||||
@@ -399,7 +396,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update (no cell updates needed)
|
// ... Create a row update (no cell updates needed)
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
long oldBytesWritten = rs.totalBytesWritten;
|
long oldBytesWritten = rs.totalBytesWritten;
|
||||||
|
|
||||||
// ... Setup a db reader for the result of an update
|
// ... Setup a db reader for the result of an update
|
||||||
@@ -421,7 +418,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update (no cell updates needed)
|
// ... Create a row update (no cell updates needed)
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, true);
|
var rs = await Common.GetResultSet(data.DbColumns, true);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I ask for the changes to be applied with a null db reader
|
// If: I ask for the changes to be applied with a null db reader
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -439,7 +436,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update (no cell updates needed)
|
// ... Create a row update (no cell updates needed)
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I attempt to revert a cell that is out of range
|
// If: I attempt to revert a cell that is out of range
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -453,7 +450,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update (no cell updates needed)
|
// ... Create a row update (no cell updates needed)
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, true);
|
var rs = await Common.GetResultSet(data.DbColumns, true);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
|
|
||||||
// If: I attempt to revert a cell that has not been set
|
// If: I attempt to revert a cell that has not been set
|
||||||
EditRevertCellResult result = ru.RevertCell(0);
|
EditRevertCellResult result = ru.RevertCell(0);
|
||||||
@@ -480,7 +477,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update
|
// ... Create a row update
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
ru.SetCell(0, "qqq");
|
ru.SetCell(0, "qqq");
|
||||||
ru.SetCell(1, "qqq");
|
ru.SetCell(1, "qqq");
|
||||||
|
|
||||||
@@ -509,7 +506,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a row update
|
// ... Create a row update
|
||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
|
var ru = new RowUpdate(0, rs, data.TableMetadata);
|
||||||
ru.SetCell(0, "qqq");
|
ru.SetCell(0, "qqq");
|
||||||
|
|
||||||
// If: I attempt to revert a cell that was set
|
// If: I attempt to revert a cell that was set
|
||||||
@@ -538,5 +535,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var rs = await Common.GetResultSet(data.DbColumns, false);
|
var rs = await Common.GetResultSet(data.DbColumns, false);
|
||||||
return new RowUpdate(0, rs, data.TableMetadata);
|
return new RowUpdate(0, rs, data.TableMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("^DECLARE @(.+) TABLE \\((.+)\\)$")]
|
||||||
|
private static partial Regex GetDeclareTableRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^SELECT (.+) FROM @(.+)$")]
|
||||||
|
private static partial Regex GetSelectRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("UPDATE .+ SET (.*) WHERE")]
|
||||||
|
private static partial Regex GetUpdateRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
||||||
{
|
{
|
||||||
public class SessionTests
|
public partial class SessionTests
|
||||||
{
|
{
|
||||||
#region Construction Tests
|
#region Construction Tests
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
public void SessionConstructionValid()
|
public void SessionConstructionValid()
|
||||||
{
|
{
|
||||||
// If: I create a session object with a proper arguments
|
// If: I create a session object with a proper arguments
|
||||||
Mock<IEditMetadataFactory> mockFactory = new Mock<IEditMetadataFactory>();
|
var mockFactory = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(mockFactory.Object);
|
var s = new EditSession(mockFactory.Object);
|
||||||
|
|
||||||
// Then:
|
// Then:
|
||||||
// ... The edit cache should not exist
|
// ... The edit cache should not exist
|
||||||
@@ -87,7 +87,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
ConnectionService.Instance.OwnerToConnectionMap[ci.OwnerUri] = ci;
|
ConnectionService.Instance.OwnerToConnectionMap[ci.OwnerUri] = ci;
|
||||||
|
|
||||||
var fsf = MemoryFileSystem.GetFileStreamFactory();
|
var fsf = MemoryFileSystem.GetFileStreamFactory();
|
||||||
Query query = new Query(Constants.StandardQuery, ci, new QueryExecutionSettings(), fsf);
|
var query = new Query(Constants.StandardQuery, ci, new QueryExecutionSettings(), fsf);
|
||||||
query.Execute();
|
query.Execute();
|
||||||
query.ExecutionTask.Wait();
|
query.ExecutionTask.Wait();
|
||||||
|
|
||||||
@@ -116,8 +116,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to create a row without initializing
|
// If: I ask to create a row without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -292,8 +292,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session and fake that it has been initialized
|
// ... Create a session and fake that it has been initialized
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object) {IsInitialized = true};
|
var s = new EditSession(emf.Object) {IsInitialized = true};
|
||||||
|
|
||||||
// If: I initialize it
|
// If: I initialize it
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -305,8 +305,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session and fake that it is in progress of initializing
|
// ... Create a session and fake that it is in progress of initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object) {InitializeTask = new Task(() => {})};
|
var s = new EditSession(emf.Object) {InitializeTask = new Task(() => {})};
|
||||||
|
|
||||||
// If: I initialize it
|
// If: I initialize it
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -320,8 +320,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session that hasn't been initialized
|
// ... Create a session that hasn't been initialized
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
Assert.Catch<ArgumentException>(() => s.Initialize(initParams, c, qr, sh, fh), "I initialize it with a missing parameter. It should throw an exception");
|
Assert.Catch<ArgumentException>(() => s.Initialize(initParams, c, qr, sh, fh), "I initialize it with a missing parameter. It should throw an exception");
|
||||||
}
|
}
|
||||||
@@ -381,12 +381,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a metadata factory that throws
|
// ... Create a metadata factory that throws
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
||||||
.Throws<Exception>();
|
.Throws<Exception>();
|
||||||
|
|
||||||
// ... Create a session that hasn't been initialized
|
// ... Create a session that hasn't been initialized
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// ... Create a mock for verifying the failure handler will be called
|
// ... Create a mock for verifying the failure handler will be called
|
||||||
var successHandler = DoNothingSuccessMock;
|
var successHandler = DoNothingSuccessMock;
|
||||||
@@ -414,15 +414,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a metadata factory that will return some generic column information
|
// ... Create a metadata factory that will return some generic column information
|
||||||
var b = QueryExecution.Common.GetBasicExecutedBatch();
|
var b = QueryExecution.Common.GetBasicExecutedBatch();
|
||||||
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
|
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
||||||
.Returns(etm);
|
.Returns(etm);
|
||||||
|
|
||||||
// ... Create a session that hasn't been initialized
|
// ... Create a session that hasn't been initialized
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// ... Create a query runner that will fail via exception
|
// ... Create a query runner that will fail via exception
|
||||||
Mock<EditSession.QueryRunner> qr = new Mock<EditSession.QueryRunner>();
|
var qr = new Mock<EditSession.QueryRunner>();
|
||||||
qr.Setup(r => r(It.IsAny<string>())).Throws(new Exception("qqq"));
|
qr.Setup(r => r(It.IsAny<string>())).Throws(new Exception("qqq"));
|
||||||
|
|
||||||
// ... Create a mock for verifying the failure handler will be called
|
// ... Create a mock for verifying the failure handler will be called
|
||||||
@@ -451,15 +451,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
// ... Create a metadata factory that will return some generic column information
|
// ... Create a metadata factory that will return some generic column information
|
||||||
var b = QueryExecution.Common.GetBasicExecutedBatch();
|
var b = QueryExecution.Common.GetBasicExecutedBatch();
|
||||||
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
|
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
||||||
.Returns(etm);
|
.Returns(etm);
|
||||||
|
|
||||||
// ... Create a session that hasn't been initialized
|
// ... Create a session that hasn't been initialized
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// ... Create a query runner that will fail via returning a null query
|
// ... Create a query runner that will fail via returning a null query
|
||||||
Mock<EditSession.QueryRunner> qr = new Mock<EditSession.QueryRunner>();
|
var qr = new Mock<EditSession.QueryRunner>();
|
||||||
qr.Setup(r => r(It.IsAny<string>()))
|
qr.Setup(r => r(It.IsAny<string>()))
|
||||||
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(null, message)));
|
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(null, message)));
|
||||||
|
|
||||||
@@ -490,15 +490,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var q = QueryExecution.Common.GetBasicExecutedQuery();
|
var q = QueryExecution.Common.GetBasicExecutedQuery();
|
||||||
var rs = q.Batches[0].ResultSets[0];
|
var rs = q.Batches[0].ResultSets[0];
|
||||||
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
|
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
|
||||||
.Returns(etm);
|
.Returns(etm);
|
||||||
|
|
||||||
// ... Create a session that hasn't been initialized
|
// ... Create a session that hasn't been initialized
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// ... Create a query runner that will return a successful query
|
// ... Create a query runner that will return a successful query
|
||||||
Mock<EditSession.QueryRunner> qr = new Mock<EditSession.QueryRunner>();
|
var qr = new Mock<EditSession.QueryRunner>();
|
||||||
qr.Setup(r => r(It.IsAny<string>()))
|
qr.Setup(r => r(It.IsAny<string>()))
|
||||||
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q)));
|
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q)));
|
||||||
|
|
||||||
@@ -533,8 +533,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to delete a row without initializing
|
// If: I ask to delete a row without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -583,8 +583,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to revert a row without initializing
|
// If: I ask to revert a row without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -683,8 +683,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to revert a cell without initializing
|
// If: I ask to revert a cell without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -724,8 +724,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to update a cell without initializing
|
// If: I ask to update a cell without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -807,8 +807,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to update a cell without initializing
|
// If: I ask to update a cell without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -974,8 +974,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to script edits without initializing
|
// If: I ask to script edits without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -1001,12 +1001,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
EditSession s = await GetBasicSession();
|
EditSession s = await GetBasicSession();
|
||||||
|
|
||||||
// ... Add two mock edits that will generate a script
|
// ... Add two mock edits that will generate a script
|
||||||
Mock<RowEditBase> edit = new Mock<RowEditBase>();
|
var edit = new Mock<RowEditBase>();
|
||||||
edit.Setup(e => e.GetScript()).Returns("test");
|
edit.Setup(e => e.GetScript()).Returns("test");
|
||||||
s.EditCache[0] = edit.Object;
|
s.EditCache[0] = edit.Object;
|
||||||
s.EditCache[1] = edit.Object;
|
s.EditCache[1] = edit.Object;
|
||||||
|
|
||||||
using (SelfCleaningTempFile file = new SelfCleaningTempFile())
|
using (var file = new SelfCleaningTempFile())
|
||||||
{
|
{
|
||||||
// If: I script the edit cache to a local output path
|
// If: I script the edit cache to a local output path
|
||||||
string outputPath = s.ScriptEdits(file.FilePath);
|
string outputPath = s.ScriptEdits(file.FilePath);
|
||||||
@@ -1029,8 +1029,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Create a session without initializing
|
// ... Create a session without initializing
|
||||||
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
|
var emf = new Mock<IEditMetadataFactory>();
|
||||||
EditSession s = new EditSession(emf.Object);
|
var s = new EditSession(emf.Object);
|
||||||
|
|
||||||
// If: I ask to script edits without initializing
|
// If: I ask to script edits without initializing
|
||||||
// Then: I should get an exception
|
// Then: I should get an exception
|
||||||
@@ -1088,7 +1088,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
DbConnection conn = new TestSqlConnection(null);
|
DbConnection conn = new TestSqlConnection(null);
|
||||||
|
|
||||||
// ... Mock a task that has not completed
|
// ... Mock a task that has not completed
|
||||||
Task notCompleted = new Task(() => {});
|
var notCompleted = new Task(() => {});
|
||||||
s.CommitTask = notCompleted;
|
s.CommitTask = notCompleted;
|
||||||
|
|
||||||
// If: I attempt to commit while a task is in progress
|
// If: I attempt to commit while a task is in progress
|
||||||
@@ -1106,7 +1106,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
DbConnection conn = new TestSqlConnection(null);
|
DbConnection conn = new TestSqlConnection(null);
|
||||||
|
|
||||||
// ... Add a mock commands for fun
|
// ... Add a mock commands for fun
|
||||||
Mock<RowEditBase> edit = new Mock<RowEditBase>();
|
var edit = new Mock<RowEditBase>();
|
||||||
edit.Setup(e => e.GetCommand(It.IsAny<DbConnection>())).Returns<DbConnection>(dbc => dbc.CreateCommand());
|
edit.Setup(e => e.GetCommand(It.IsAny<DbConnection>())).Returns<DbConnection>(dbc => dbc.CreateCommand());
|
||||||
edit.Setup(e => e.ApplyChanges(It.IsAny<DbDataReader>())).Returns(Task.FromResult(0));
|
edit.Setup(e => e.ApplyChanges(It.IsAny<DbDataReader>())).Returns(Task.FromResult(0));
|
||||||
s.EditCache[0] = edit.Object;
|
s.EditCache[0] = edit.Object;
|
||||||
@@ -1150,7 +1150,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
DbConnection conn = new TestSqlConnection(null);
|
DbConnection conn = new TestSqlConnection(null);
|
||||||
|
|
||||||
// ... Add a mock edit that will explode on generating a command
|
// ... Add a mock edit that will explode on generating a command
|
||||||
Mock<RowEditBase> edit = new Mock<RowEditBase>();
|
var edit = new Mock<RowEditBase>();
|
||||||
edit.Setup(e => e.GetCommand(It.IsAny<DbConnection>())).Throws<Exception>();
|
edit.Setup(e => e.GetCommand(It.IsAny<DbConnection>())).Throws<Exception>();
|
||||||
s.EditCache[0] = edit.Object;
|
s.EditCache[0] = edit.Object;
|
||||||
|
|
||||||
@@ -1194,7 +1194,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
|
|
||||||
// If: I generate a query for selecting rows without a limit
|
// If: I generate a query for selecting rows without a limit
|
||||||
EditInitializeFiltering eif = new EditInitializeFiltering
|
var eif = new EditInitializeFiltering
|
||||||
{
|
{
|
||||||
LimitResults = null
|
LimitResults = null
|
||||||
};
|
};
|
||||||
@@ -1202,7 +1202,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
|
|
||||||
// Then:
|
// Then:
|
||||||
// ... The query should look like a select statement
|
// ... The query should look like a select statement
|
||||||
Regex selectRegex = new Regex("SELECT (.+) FROM (.+)", RegexOptions.IgnoreCase);
|
Regex selectRegex = GetSelectRegex();
|
||||||
var match = selectRegex.Match(query);
|
var match = selectRegex.Match(query);
|
||||||
Assert.True(match.Success);
|
Assert.True(match.Success);
|
||||||
|
|
||||||
@@ -1223,7 +1223,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
|
|
||||||
// If: I generate a query for selecting rows with a negative limit
|
// If: I generate a query for selecting rows with a negative limit
|
||||||
// Then: An exception should be thrown
|
// Then: An exception should be thrown
|
||||||
EditInitializeFiltering eif = new EditInitializeFiltering
|
var eif = new EditInitializeFiltering
|
||||||
{
|
{
|
||||||
LimitResults = -1
|
LimitResults = -1
|
||||||
};
|
};
|
||||||
@@ -1237,7 +1237,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
|
||||||
|
|
||||||
// If: I generate a query for selecting rows without a limit
|
// If: I generate a query for selecting rows without a limit
|
||||||
EditInitializeFiltering eif = new EditInitializeFiltering
|
var eif = new EditInitializeFiltering
|
||||||
{
|
{
|
||||||
LimitResults = limit
|
LimitResults = limit
|
||||||
};
|
};
|
||||||
@@ -1245,7 +1245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
|
|
||||||
// Then:
|
// Then:
|
||||||
// ... The query should look like a select statement
|
// ... The query should look like a select statement
|
||||||
Regex selectRegex = new Regex(@"SELECT TOP (\d+) (.+) FROM (.+)", RegexOptions.IgnoreCase);
|
var selectRegex = GetSelectTopRegex();
|
||||||
var match = selectRegex.Match(query);
|
var match = selectRegex.Match(query);
|
||||||
Assert.True(match.Success);
|
Assert.True(match.Success);
|
||||||
|
|
||||||
@@ -1286,7 +1286,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
private static Mock<Func<Task>> DoNothingSuccessMock
|
private static Mock<Func<Task>> DoNothingSuccessMock
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
Mock<Func<Task>> successHandler = new Mock<Func<Task>>();
|
var successHandler = new Mock<Func<Task>>();
|
||||||
successHandler.Setup(f => f()).Returns(Task.FromResult(0));
|
successHandler.Setup(f => f()).Returns(Task.FromResult(0));
|
||||||
return successHandler;
|
return successHandler;
|
||||||
}
|
}
|
||||||
@@ -1296,7 +1296,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Mock<Func<Exception, Task>> failureHandler = new Mock<Func<Exception, Task>>();
|
var failureHandler = new Mock<Func<Exception, Task>>();
|
||||||
failureHandler.Setup(f => f(It.IsAny<Exception>())).Returns(Task.FromResult(0));
|
failureHandler.Setup(f => f(It.IsAny<Exception>())).Returns(Task.FromResult(0));
|
||||||
return failureHandler;
|
return failureHandler;
|
||||||
}
|
}
|
||||||
@@ -1309,5 +1309,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
|
|||||||
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
|
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
|
||||||
return await Common.GetCustomSession(q, etm);
|
return await Common.GetCustomSession(q, etm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("SELECT (.+) FROM (.+)", RegexOptions.IgnoreCase)]
|
||||||
|
private static partial Regex GetSelectRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("SELECT TOP (\\d+) (.+) FROM (.+)", RegexOptions.IgnoreCase)]
|
||||||
|
private static partial Regex GetSelectTopRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
|
|||||||
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
|
||||||
{
|
{
|
||||||
Uri = textDocument.TextDocument.Uri,
|
Uri = textDocument.TextDocument.Uri,
|
||||||
Language = LanguageService.SQL_LANG.ToLower(),
|
Language = LanguageService.SQL_LANG.ToLower(System.Globalization.CultureInfo.InvariantCulture),
|
||||||
Flavor = "NotMSSQL"
|
Flavor = "NotMSSQL"
|
||||||
}, null);
|
}, null);
|
||||||
await langService.HandleSignatureHelpRequest(textDocument, signatureRequestContext.Object);
|
await langService.HandleSignatureHelpRequest(textDocument, signatureRequestContext.Object);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
|
|||||||
Assert.AreEqual(0, AutoCompleteHelper.EmptyCompletionList.Length);
|
Assert.AreEqual(0, AutoCompleteHelper.EmptyCompletionList.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestScriptDocumentInfo : ScriptDocumentInfo
|
internal sealed class TestScriptDocumentInfo : ScriptDocumentInfo
|
||||||
{
|
{
|
||||||
public TestScriptDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ScriptParseInfo scriptParseInfo,
|
public TestScriptDocumentInfo(TextDocumentPosition textDocumentPosition, ScriptFile scriptFile, ScriptParseInfo scriptParseInfo,
|
||||||
string tokenText = null)
|
string tokenText = null)
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
inputStream.Flush();
|
inputStream.Flush();
|
||||||
inputStream.Seek(0, SeekOrigin.Begin);
|
inputStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
Assert.ThrowsAsync<ArgumentException>(() => messageReader.ReadMessage(), "An exception should be thrown while reading");
|
Assert.ThrowsAsync<ArgumentException>(messageReader.ReadMessage, "An exception should be thrown while reading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
inputStream.Flush();
|
inputStream.Flush();
|
||||||
inputStream.Seek(0, SeekOrigin.Begin);
|
inputStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
Assert.ThrowsAsync<MessageParseException>(() => messageReader.ReadMessage(), "An exception should be thrown while reading") ;
|
Assert.ThrowsAsync<MessageParseException>(messageReader.ReadMessage, "An exception should be thrown while reading") ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
inputStream.Flush();
|
inputStream.Flush();
|
||||||
inputStream.Seek(0, SeekOrigin.Begin);
|
inputStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
Assert.ThrowsAsync<MessageParseException>(() => messageReader.ReadMessage(), "An exception should be thrown while reading");
|
Assert.ThrowsAsync<MessageParseException>(messageReader.ReadMessage, "An exception should be thrown while reading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,9 +153,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
inputStream.Flush();
|
inputStream.Flush();
|
||||||
inputStream.Seek(0, SeekOrigin.Begin);
|
inputStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
Assert.ThrowsAsync<JsonReaderException>(() => messageReader.ReadMessage(), "The first read should fail with an exception while deserializing");
|
Assert.ThrowsAsync<JsonReaderException>(messageReader.ReadMessage, "The first read should fail with an exception while deserializing");
|
||||||
|
|
||||||
Assert.ThrowsAsync<MessageParseException>(() => messageReader.ReadMessage(), "The second read should fail with an exception while reading headers");
|
Assert.ThrowsAsync<MessageParseException>(messageReader.ReadMessage, "The second read should fail with an exception while reading headers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
inputStream.Flush();
|
inputStream.Flush();
|
||||||
inputStream.Seek(0, SeekOrigin.Begin);
|
inputStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
Assert.ThrowsAsync<ArgumentException>(() => messageReader.ReadMessage(), "An exception should be thrown while reading the first one");
|
Assert.ThrowsAsync<ArgumentException>(messageReader.ReadMessage, "An exception should be thrown while reading the first one");
|
||||||
|
|
||||||
// ... A test event should be successfully read from the second one
|
// ... A test event should be successfully read from the second one
|
||||||
Message messageResult = messageReader.ReadMessage().Result;
|
Message messageResult = messageReader.ReadMessage().Result;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
{
|
{
|
||||||
#region Request Types
|
#region Request Types
|
||||||
|
|
||||||
internal class TestRequest
|
internal sealed class TestRequest
|
||||||
{
|
{
|
||||||
public Task ProcessMessage(MessageWriter messageWriter)
|
public Task ProcessMessage(MessageWriter messageWriter)
|
||||||
{
|
{
|
||||||
@@ -20,7 +20,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestRequestArguments
|
internal sealed class TestRequestArguments
|
||||||
{
|
{
|
||||||
public string SomeString { get; set; }
|
public string SomeString { get; set; }
|
||||||
}
|
}
|
||||||
@@ -29,11 +29,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
|
|
||||||
#region Response Types
|
#region Response Types
|
||||||
|
|
||||||
internal class TestResponse
|
internal sealed class TestResponse
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestResponseBody
|
internal sealed class TestResponseBody
|
||||||
{
|
{
|
||||||
public string SomeString { get; set; }
|
public string SomeString { get; set; }
|
||||||
}
|
}
|
||||||
@@ -42,11 +42,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Messaging
|
|||||||
|
|
||||||
#region Event Types
|
#region Event Types
|
||||||
|
|
||||||
internal class TestEvent
|
internal sealed class TestEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestEventBody
|
internal sealed class TestEventBody
|
||||||
{
|
{
|
||||||
public string SomeString { get; set; }
|
public string SomeString { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<!-- TODO FIX THESE WARNINGS ASAP -->
|
<!-- False alerts, disabled due to issue: https://github.com/dotnet/roslyn/issues/65850 -->
|
||||||
<NoWarn>$(NoWarn);SYSLIB1045;IDE0200;IDE0230;CA1311;CA1852;CA1854</NoWarn>
|
<NoWarn>$(NoWarn);CS8795</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" />
|
<PackageReference Include="System.Text.Encoding.CodePages" />
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer
|
||||||
{
|
{
|
||||||
class GroupBySchemaTests
|
internal sealed class GroupBySchemaTests
|
||||||
{
|
{
|
||||||
Mock<DatabaseChildFactory> factory;
|
Mock<DatabaseChildFactory> factory;
|
||||||
Mock<TreeNode> node;
|
Mock<TreeNode> node;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution
|
|||||||
{
|
{
|
||||||
await service.HandleExecuteRequest(qeParams, requestContext);
|
await service.HandleExecuteRequest(qeParams, requestContext);
|
||||||
await service.WorkTask;
|
await service.WorkTask;
|
||||||
if (service.ActiveQueries.ContainsKey(qeParams.OwnerUri) && service.ActiveQueries[qeParams.OwnerUri].ExecutionTask != null)
|
if (service.ActiveQueries.TryGetValue(qeParams.OwnerUri, out Query? query) && query.ExecutionTask != null)
|
||||||
{
|
{
|
||||||
await service.ActiveQueries[qeParams.OwnerUri].ExecutionTask;
|
await service.ActiveQueries[qeParams.OwnerUri].ExecutionTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
||||||
{
|
{
|
||||||
public class SaveAsCsvFileStreamWriterTests
|
public partial class SaveAsCsvFileStreamWriterTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void Constructor_NullStream()
|
public void Constructor_NullStream()
|
||||||
@@ -148,7 +148,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
string output = writer.EncodeCsvField(field);
|
string output = writer.EncodeCsvField(field);
|
||||||
|
|
||||||
// Then: It should wrap it in quotes
|
// Then: It should wrap it in quotes
|
||||||
Assert.True(Regex.IsMatch(output, "^\".*\"$", RegexOptions.Singleline));
|
Assert.True(GetCsvRegexSingleLine().IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Something\rElse")] // Contains carriage return [TODO: Don't support this]
|
[TestCase("Something\rElse")] // Contains carriage return [TODO: Don't support this]
|
||||||
@@ -165,7 +165,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
string output = writer.EncodeCsvField(field);
|
string output = writer.EncodeCsvField(field);
|
||||||
|
|
||||||
// Then: It should wrap it in quotes
|
// Then: It should wrap it in quotes
|
||||||
Assert.True(Regex.IsMatch(output, @"^\[.*\[$", RegexOptions.Singleline));
|
Assert.True(GetCsvBracketRegex().IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("\tSomething")] // Starts with tab
|
[TestCase("\tSomething")] // Starts with tab
|
||||||
@@ -186,7 +186,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
string output = writer.EncodeCsvField(field);
|
string output = writer.EncodeCsvField(field);
|
||||||
|
|
||||||
// Then: It should wrap it in quotes
|
// Then: It should wrap it in quotes
|
||||||
Assert.True(Regex.IsMatch(output, "^\".*\"$", RegexOptions.Singleline));
|
Assert.True(GetCsvRegexSingleLine().IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Something")]
|
[TestCase("Something")]
|
||||||
@@ -201,7 +201,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
string output = writer.EncodeCsvField(field);
|
string output = writer.EncodeCsvField(field);
|
||||||
|
|
||||||
// Then: It should not wrap it in quotes
|
// Then: It should not wrap it in quotes
|
||||||
Assert.False(Regex.IsMatch(output, "^\".*\"$"));
|
Assert.False(GetCsvRegex().IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(null, "Some\"thing", "\"Some\"\"thing\"")] // Default identifier
|
[TestCase(null, "Some\"thing", "\"Some\"\"thing\"")] // Default identifier
|
||||||
@@ -277,7 +277,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
byte[] output = new byte[8192];
|
byte[] output = new byte[8192];
|
||||||
|
|
||||||
// If: I write a row
|
// If: I write a row
|
||||||
SaveAsCsvFileStreamWriter writer = new SaveAsCsvFileStreamWriter(new MemoryStream(output), requestParams, columns);
|
var writer = new SaveAsCsvFileStreamWriter(new MemoryStream(output), requestParams, columns);
|
||||||
using (writer)
|
using (writer)
|
||||||
{
|
{
|
||||||
writer.WriteRow(data, columns);
|
writer.WriteRow(data, columns);
|
||||||
@@ -425,5 +425,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
Assert.IsEmpty(lines[lines.Length - 1]);
|
Assert.IsEmpty(lines[lines.Length - 1]);
|
||||||
return lines.Take(lines.Length - 1).ToArray();
|
return lines.Take(lines.Length - 1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("^\\[.*\\[$", RegexOptions.Singleline)]
|
||||||
|
private static partial Regex GetCsvBracketRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^\".*\"$")]
|
||||||
|
private static partial Regex GetCsvRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^\".*\"$", RegexOptions.Singleline)]
|
||||||
|
private static partial Regex GetCsvRegexSingleLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
||||||
{
|
{
|
||||||
public class SaveAsExcelFileStreamWriterHelperTests : IDisposable
|
public partial class SaveAsExcelFileStreamWriterHelperTests : IDisposable
|
||||||
{
|
{
|
||||||
private Stream _stream;
|
private Stream _stream;
|
||||||
public SaveAsExcelFileStreamWriterHelperTests()
|
public SaveAsExcelFileStreamWriterHelperTests()
|
||||||
@@ -25,7 +25,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
using (var helper = new SaveAsExcelFileStreamWriterHelper(_stream, true))
|
using (var helper = new SaveAsExcelFileStreamWriterHelper(_stream, true))
|
||||||
using (var sheet = helper.AddSheet())
|
using (var sheet = helper.AddSheet())
|
||||||
{
|
{
|
||||||
DbCellValue value = new DbCellValue();
|
var value = new DbCellValue();
|
||||||
sheet.AddRow();
|
sheet.AddRow();
|
||||||
|
|
||||||
value.IsNull = true;
|
value.IsNull = true;
|
||||||
@@ -71,7 +71,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
sheet.AddCell(value);
|
sheet.AddCell(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Regex contentRemoveLinebreakLeadingSpace = new Regex(@"\r?\n\s*");
|
|
||||||
|
[GeneratedRegex("\\r?\\n\\s*")]
|
||||||
|
private static partial Regex GetContentRemoveLinebreakLeadingSpaceRegex();
|
||||||
|
|
||||||
private void ContentMatch(string fileName)
|
private void ContentMatch(string fileName)
|
||||||
{
|
{
|
||||||
string referencePath = Path.Combine(RunEnvironmentInfo.GetTestDataLocation(),
|
string referencePath = Path.Combine(RunEnvironmentInfo.GetTestDataLocation(),
|
||||||
@@ -79,11 +82,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
"SaveAsExcelFileStreamWriterHelperTests",
|
"SaveAsExcelFileStreamWriterHelperTests",
|
||||||
fileName);
|
fileName);
|
||||||
string referenceContent = File.ReadAllText(referencePath);
|
string referenceContent = File.ReadAllText(referencePath);
|
||||||
referenceContent = contentRemoveLinebreakLeadingSpace.Replace(referenceContent, "");
|
referenceContent = GetContentRemoveLinebreakLeadingSpaceRegex().Replace(referenceContent, "");
|
||||||
|
|
||||||
using (ZipArchive zip = new ZipArchive(_stream, ZipArchiveMode.Read, true))
|
using (var zip = new ZipArchive(_stream, ZipArchiveMode.Read, true))
|
||||||
{
|
{
|
||||||
using (var reader = new StreamReader(zip.GetEntry(fileName).Open()))
|
using (var reader = new StreamReader(zip?.GetEntry(fileName)?.Open()!))
|
||||||
{
|
{
|
||||||
string realContent = reader.ReadToEnd();
|
string realContent = reader.ReadToEnd();
|
||||||
Assert.AreEqual(referenceContent, realContent);
|
Assert.AreEqual(referenceContent, realContent);
|
||||||
@@ -130,7 +133,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
public class SaveAsExcelFileStreamWriterHelperReferenceManagerTests
|
public class SaveAsExcelFileStreamWriterHelperReferenceManagerTests
|
||||||
{
|
{
|
||||||
private Mock<XmlWriter> _xmlWriterMock;
|
private Mock<XmlWriter> _xmlWriterMock;
|
||||||
private string LastWrittenReference { get; set; }
|
private string? LastWrittenReference { get; set; }
|
||||||
private int LastWrittenRow { get; set; }
|
private int LastWrittenRow { get; set; }
|
||||||
|
|
||||||
public SaveAsExcelFileStreamWriterHelperReferenceManagerTests()
|
public SaveAsExcelFileStreamWriterHelperReferenceManagerTests()
|
||||||
@@ -145,7 +148,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
_xmlWriterMock.Setup(a => a.WriteEndAttribute());
|
_xmlWriterMock.Setup(a => a.WriteEndAttribute());
|
||||||
_xmlWriterMock.Setup(a => a.WriteValue(It.IsAny<int>()))
|
_xmlWriterMock.Setup(a => a.WriteValue(It.IsAny<int>()))
|
||||||
.Callback<int>(row => LastWrittenRow = row);
|
.Callback<int>(row => LastWrittenRow = row);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -203,8 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
manager.AssureColumnReference();
|
manager.AssureColumnReference();
|
||||||
manager.WriteAndIncreaseColumnReference();
|
manager.WriteAndIncreaseColumnReference();
|
||||||
Assert.AreEqual("XFD1", LastWrittenReference);
|
Assert.AreEqual("XFD1", LastWrittenReference);
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<InvalidOperationException>(manager.AssureColumnReference);
|
||||||
() => manager.AssureColumnReference());
|
|
||||||
Assert.That(ex.Message, Does.Contain("max column number is 16384"));
|
Assert.That(ex.Message, Does.Contain("max column number is 16384"));
|
||||||
}
|
}
|
||||||
[Test]
|
[Test]
|
||||||
@@ -232,8 +233,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
var xmlWriter = _xmlWriterMock.Object;
|
var xmlWriter = _xmlWriterMock.Object;
|
||||||
var manager = new SaveAsExcelFileStreamWriterHelper.ReferenceManager(xmlWriter);
|
var manager = new SaveAsExcelFileStreamWriterHelper.ReferenceManager(xmlWriter);
|
||||||
|
|
||||||
var ex = Assert.Throws<InvalidOperationException>(
|
var ex = Assert.Throws<InvalidOperationException>(manager.AssureColumnReference);
|
||||||
() => manager.AssureColumnReference());
|
|
||||||
Assert.That(ex.Message, Does.Contain("AddRow must be called before AddCell"));
|
Assert.That(ex.Message, Does.Contain("AddRow must be called before AddCell"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
||||||
{
|
{
|
||||||
public class SaveAsMarkdownFileStreamWriterTests
|
public partial class SaveAsMarkdownFileStreamWriterTests
|
||||||
{
|
{
|
||||||
// Regex: Matches '|' not preceded by a '\'
|
// Regex: Matches '|' not preceded by a '\'
|
||||||
private static readonly Regex UnescapedPipe = new Regex(@"(?<!\\)\|", RegexOptions.Compiled);
|
[GeneratedRegex("(?<!\\\\)\\|", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex GetUnescapedPipeRegex();
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Constructor_NullStream()
|
public void Constructor_NullStream()
|
||||||
@@ -362,7 +363,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
|
|
||||||
private static void ValidateLine(string line, IEnumerable<string> expectedCells)
|
private static void ValidateLine(string line, IEnumerable<string> expectedCells)
|
||||||
{
|
{
|
||||||
string[] cells = UnescapedPipe.Split(line);
|
string[] cells = GetUnescapedPipeRegex().Split(line);
|
||||||
string[] expectedCellsArray = expectedCells as string[] ?? expectedCells.ToArray();
|
string[] expectedCellsArray = expectedCells as string[] ?? expectedCells.ToArray();
|
||||||
Assert.That(cells.Length - 2, Is.EqualTo(expectedCellsArray.Length), "Wrong number of cells in output");
|
Assert.That(cells.Length - 2, Is.EqualTo(expectedCellsArray.Length), "Wrong number of cells in output");
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
||||||
{
|
{
|
||||||
public class ServiceBufferReaderWriterTests
|
public partial class ServiceBufferReaderWriterTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void ReaderStreamNull()
|
public void ReaderStreamNull()
|
||||||
@@ -49,7 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
|
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
|
||||||
Assert.Throws<InvalidOperationException>(() =>
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
{
|
{
|
||||||
ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
|
var obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
|
||||||
obj.Dispose();
|
obj.Dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
|
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
|
||||||
Assert.Throws<InvalidOperationException>(() =>
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
{
|
{
|
||||||
ServiceBufferFileStreamReader obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
|
var obj = new ServiceBufferFileStreamReader(invalidStream.Object, new QueryExecutionSettings());
|
||||||
obj.Dispose();
|
obj.Dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
|
invalidStream.SetupGet(s => s.CanSeek).Returns(true);
|
||||||
Assert.Throws<InvalidOperationException>(() =>
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
{
|
{
|
||||||
ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
|
var obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
|
||||||
obj.Dispose();
|
obj.Dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
|
invalidStream.SetupGet(s => s.CanSeek).Returns(false);
|
||||||
Assert.Throws<InvalidOperationException>(() =>
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
{
|
{
|
||||||
ServiceBufferFileStreamWriter obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
|
var obj = new ServiceBufferFileStreamWriter(invalidStream.Object, new QueryExecutionSettings());
|
||||||
obj.Dispose();
|
obj.Dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
|
|
||||||
// If:
|
// If:
|
||||||
// ... I write a type T to the writer
|
// ... I write a type T to the writer
|
||||||
using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(new MemoryStream(storage), overrideSettings))
|
using (var writer = new ServiceBufferFileStreamWriter(new MemoryStream(storage), overrideSettings))
|
||||||
{
|
{
|
||||||
int writtenBytes = writeFunc(writer, value);
|
int writtenBytes = writeFunc(writer, value);
|
||||||
Assert.AreEqual(valueLength, writtenBytes);
|
Assert.AreEqual(valueLength, writtenBytes);
|
||||||
@@ -136,7 +136,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
|
|
||||||
// ... And read the type T back
|
// ... And read the type T back
|
||||||
FileStreamReadResult outValue;
|
FileStreamReadResult outValue;
|
||||||
using (ServiceBufferFileStreamReader reader = new ServiceBufferFileStreamReader(new MemoryStream(storage), overrideSettings))
|
using (var reader = new ServiceBufferFileStreamReader(new MemoryStream(storage), overrideSettings))
|
||||||
{
|
{
|
||||||
outValue = readFunc(reader, rowId);
|
outValue = readFunc(reader, rowId);
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATE column
|
// Setup: Create a DATE column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTe"});
|
var col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTe"});
|
||||||
|
|
||||||
foreach (DateTime value in testValues)
|
foreach (DateTime value in testValues)
|
||||||
{
|
{
|
||||||
@@ -320,7 +320,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value does not have a time string
|
// Make sure the display value does not have a time string
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2}$"));
|
Assert.True(GetDateRegex().IsMatch(displayValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIME column
|
// Setup: Create a DATETIME column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe"});
|
var col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe"});
|
||||||
|
|
||||||
foreach (DateTime value in testValues)
|
foreach (DateTime value in testValues)
|
||||||
{
|
{
|
||||||
@@ -343,7 +343,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with 3 milliseconds
|
// Make sure the display value has a time string with 3 milliseconds
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}\.[\d]{3}$"));
|
Assert.True(GetDateTimeRegex().IsMatch(displayValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIME column
|
// Setup: Create a DATETIME column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn
|
var col = new DbColumnWrapper(new TestDbColumn
|
||||||
{
|
{
|
||||||
DataTypeName = "DaTeTiMe2",
|
DataTypeName = "DaTeTiMe2",
|
||||||
NumericScale = precision
|
NumericScale = precision
|
||||||
@@ -370,7 +370,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with variable number of milliseconds
|
// Make sure the display value has a time string with variable number of milliseconds
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}"));
|
Assert.True(GetTimeRegex().IsMatch(displayValue));
|
||||||
if (precision > 0)
|
if (precision > 0)
|
||||||
{
|
{
|
||||||
Assert.True(Regex.IsMatch(displayValue, $@"\.[\d]{{{precision}}}$"));
|
Assert.True(Regex.IsMatch(displayValue, $@"\.[\d]{{{precision}}}$"));
|
||||||
@@ -389,7 +389,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIME2 column
|
// Setup: Create a DATETIME2 column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 0});
|
var col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 0});
|
||||||
|
|
||||||
foreach (DateTime value in testValues)
|
foreach (DateTime value in testValues)
|
||||||
{
|
{
|
||||||
@@ -397,7 +397,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with 0 milliseconds
|
// Make sure the display value has a time string with 0 milliseconds
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}$"));
|
Assert.True(GetTimeRegex().IsMatch(displayValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIME2 column
|
// Setup: Create a DATETIME2 column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 255});
|
var col = new DbColumnWrapper(new TestDbColumn {DataTypeName = "DaTeTiMe2", NumericScale = 255});
|
||||||
|
|
||||||
foreach (DateTime value in testValues)
|
foreach (DateTime value in testValues)
|
||||||
{
|
{
|
||||||
@@ -420,7 +420,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTime(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with 7 milliseconds
|
// Make sure the display value has a time string with 7 milliseconds
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}\.[\d]{7}$"));
|
Assert.True(GetDateTime2Regex().IsMatch(displayValue));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,7 +436,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIMEOFFSET column
|
// Setup: Create a DATETIMEOFFSET column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 6 });
|
var col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 6 });
|
||||||
|
|
||||||
foreach (DateTimeOffset value in testValues)
|
foreach (DateTimeOffset value in testValues)
|
||||||
{
|
{
|
||||||
@@ -444,7 +444,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with 6 milliseconds and a time zone
|
// Make sure the display value has a time string with 6 milliseconds and a time zone
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}\.[\d]{6} [+-][01][\d]:[\d]{2}$"));
|
Assert.True(GetDateTimeOffset6Regex().IsMatch(displayValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,7 +458,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup: Create a DATETIMEOFFSET column
|
// Setup: Create a DATETIMEOFFSET column
|
||||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 0 });
|
var col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 0 });
|
||||||
|
|
||||||
foreach (DateTimeOffset value in testValues)
|
foreach (DateTimeOffset value in testValues)
|
||||||
{
|
{
|
||||||
@@ -466,7 +466,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
||||||
|
|
||||||
// Make sure the display value has a time string with no millisecond and a time zone
|
// Make sure the display value has a time string with no millisecond and a time zone
|
||||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2} [+-][01][\d]:[\d]{2}$"));
|
Assert.True(GetDateTimeOffset0Regex().IsMatch(displayValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,11 +490,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
public void StringNullTest()
|
public void StringNullTest()
|
||||||
{
|
{
|
||||||
// Setup: Create a mock file stream
|
// Setup: Create a mock file stream
|
||||||
using (MemoryStream stream = new MemoryStream(new byte[8192]))
|
using (var stream = new MemoryStream(new byte[8192]))
|
||||||
{
|
{
|
||||||
// If:
|
// If:
|
||||||
// ... I write null as a string to the writer
|
// ... I write null as a string to the writer
|
||||||
using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
|
using (var writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
|
||||||
{
|
{
|
||||||
// Then:
|
// Then:
|
||||||
// ... I should get an argument null exception
|
// ... I should get an argument null exception
|
||||||
@@ -514,7 +514,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the test value
|
// ... Generate the test value
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
sb.Append(values[i%values.Length]);
|
sb.Append(values[i%values.Length]);
|
||||||
@@ -529,11 +529,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
public void BytesNullTest()
|
public void BytesNullTest()
|
||||||
{
|
{
|
||||||
// Setup: Create a mock file stream wrapper
|
// Setup: Create a mock file stream wrapper
|
||||||
using (MemoryStream stream = new MemoryStream(new byte[8192]))
|
using (var stream = new MemoryStream(new byte[8192]))
|
||||||
{
|
{
|
||||||
// If:
|
// If:
|
||||||
// ... I write null as a string to the writer
|
// ... I write null as a string to the writer
|
||||||
using (ServiceBufferFileStreamWriter writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
|
using (var writer = new ServiceBufferFileStreamWriter(stream, new QueryExecutionSettings()))
|
||||||
{
|
{
|
||||||
// Then:
|
// Then:
|
||||||
// ... I should get an argument null exception
|
// ... I should get an argument null exception
|
||||||
@@ -554,7 +554,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
{
|
{
|
||||||
// Setup:
|
// Setup:
|
||||||
// ... Generate the test value
|
// ... Generate the test value
|
||||||
List<byte> sb = new List<byte>();
|
var sb = new List<byte>();
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
sb.Add(values[i % values.Length]);
|
sb.Add(values[i % values.Length]);
|
||||||
@@ -602,5 +602,22 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|||||||
(reader, rowId) => reader.ReadMoney(0, rowId));
|
(reader, rowId) => reader.ReadMoney(0, rowId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2}$")]
|
||||||
|
private static partial Regex GetDateRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")]
|
||||||
|
private static partial Regex GetTimeRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}\\.[\\d]{3}$")]
|
||||||
|
private static partial Regex GetDateTimeRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}\\.[\\d]{7}$")]
|
||||||
|
private static partial Regex GetDateTime2Regex();
|
||||||
|
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}\\.[\\d]{6} [+-][01][\\d]:[\\d]{2}$")]
|
||||||
|
private static partial Regex GetDateTimeOffset6Regex();
|
||||||
|
[GeneratedRegex("^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2} [+-][01][\\d]:[\\d]{2}$")]
|
||||||
|
private static partial Regex GetDateTimeOffset0Regex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => resultSetCalls++);
|
r => resultSetCalls++);
|
||||||
await batch.Execute(GetConnection(Common.CreateTestConnectionInfo(null, false, false)), CancellationToken.None);
|
await batch.Execute(GetConnection(Common.CreateTestConnectionInfo(null, false, false)), CancellationToken.None);
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => resultSetCalls++);
|
r => resultSetCalls++);
|
||||||
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => resultSetCalls++);
|
r => resultSetCalls++);
|
||||||
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => resultSetCalls++);
|
r => resultSetCalls++);
|
||||||
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => { throw new Exception("ResultSet callback was called when it should not have been."); });
|
r => { throw new Exception("ResultSet callback was called when it should not have been."); });
|
||||||
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(batch,
|
BatchCallbackHelper(batch,
|
||||||
b => batchStartCalls++,
|
b => batchStartCalls++,
|
||||||
b => batchEndCalls++,
|
b => batchEndCalls++,
|
||||||
m => messages.Add(m),
|
messages.Add,
|
||||||
r => { throw new Exception("ResultSet callback was called when it should not have been."); });
|
r => { throw new Exception("ResultSet callback was called when it should not have been."); });
|
||||||
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
await batch.Execute(GetConnection(ci), CancellationToken.None);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test DbColumn derived class
|
/// Test DbColumn derived class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private class TestColumn : DbColumn
|
private sealed class TestColumn : DbColumn
|
||||||
{
|
{
|
||||||
public TestColumn(
|
public TestColumn(
|
||||||
string dataTypeName = null,
|
string dataTypeName = null,
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(query,
|
BatchCallbackHelper(query,
|
||||||
b => { throw new Exception("Batch startup callback should not have been called."); },
|
b => { throw new Exception("Batch startup callback should not have been called."); },
|
||||||
b => { throw new Exception("Batch completion callback was called"); },
|
b => { throw new Exception("Batch completion callback was called"); },
|
||||||
m => messages.Add(m));
|
messages.Add);
|
||||||
|
|
||||||
// If:
|
// If:
|
||||||
// ... I Then execute the query
|
// ... I Then execute the query
|
||||||
@@ -235,7 +235,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(query,
|
BatchCallbackHelper(query,
|
||||||
b => { throw new Exception("Batch start handler was called"); },
|
b => { throw new Exception("Batch start handler was called"); },
|
||||||
b => { throw new Exception("Batch completed handler was called"); },
|
b => { throw new Exception("Batch completed handler was called"); },
|
||||||
m => messages.Add(m));
|
messages.Add);
|
||||||
|
|
||||||
// .. I then execute the query
|
// .. I then execute the query
|
||||||
query.Execute();
|
query.Execute();
|
||||||
@@ -271,7 +271,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.Execution
|
|||||||
BatchCallbackHelper(query,
|
BatchCallbackHelper(query,
|
||||||
b => batchStartCallbacksReceived++,
|
b => batchStartCallbacksReceived++,
|
||||||
b => batchCompletionCallbacksReceived++,
|
b => batchCompletionCallbacksReceived++,
|
||||||
m => messages.Add(m));
|
messages.Add);
|
||||||
|
|
||||||
// ... I then execute the query
|
// ... I then execute the query
|
||||||
query.Execute();
|
query.Execute();
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution
|
|||||||
|
|
||||||
// Then:
|
// Then:
|
||||||
// ... It should throw an exception
|
// ... It should throw an exception
|
||||||
Assert.ThrowsAsync<Exception>(() => planResultSet.GetExecutionPlan());
|
Assert.ThrowsAsync<Exception>(planResultSet.GetExecutionPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -375,11 +375,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.SaveResults
|
|||||||
}
|
}
|
||||||
else if (column.DataTypeName == "Int")
|
else if (column.DataTypeName == "Int")
|
||||||
{
|
{
|
||||||
return Int64.Parse(value.DisplayValue.ToLower());
|
return Int64.Parse(value.DisplayValue.ToLower(System.Globalization.CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
else if (column.DataTypeName == "Bit")
|
else if (column.DataTypeName == "Bit")
|
||||||
{
|
{
|
||||||
return Boolean.Parse(value.DisplayValue.ToLower());
|
return Boolean.Parse(value.DisplayValue.ToLower(System.Globalization.CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
return value.DisplayValue;
|
return value.DisplayValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider.Azure
|
|||||||
var currentUserAccount = CreateAccount();
|
var currentUserAccount = CreateAccount();
|
||||||
currentUserAccount.Account.IsStale = true;
|
currentUserAccount.Account.IsStale = true;
|
||||||
IAzureAuthenticationManager accountManager = await CreateAccountManager(currentUserAccount, null);
|
IAzureAuthenticationManager accountManager = await CreateAccountManager(currentUserAccount, null);
|
||||||
Assert.ThrowsAsync<ExpiredTokenException>(() => accountManager.GetSelectedSubscriptionsAsync());
|
Assert.ThrowsAsync<ExpiredTokenException>(accountManager.GetSelectedSubscriptionsAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -61,7 +61,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider.Azure
|
|||||||
{
|
{
|
||||||
var currentUserAccount = CreateAccount();
|
var currentUserAccount = CreateAccount();
|
||||||
IAzureAuthenticationManager accountManager = await CreateAccountManager(currentUserAccount, null, true);
|
IAzureAuthenticationManager accountManager = await CreateAccountManager(currentUserAccount, null, true);
|
||||||
Assert.ThrowsAsync<ServiceFailedException>(() => accountManager.GetSelectedSubscriptionsAsync());
|
Assert.ThrowsAsync<ServiceFailedException>(accountManager.GetSelectedSubscriptionsAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider.Azure
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container to create test data and mock classes to test azure services and providers
|
/// A container to create test data and mock classes to test azure services and providers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class AzureTestContext
|
internal sealed class AzureTestContext
|
||||||
{
|
{
|
||||||
public AzureTestContext(Dictionary<string, List<string>> subscriptionToDatabaseMap)
|
public AzureTestContext(Dictionary<string, List<string>> subscriptionToDatabaseMap)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ServiceTestContext
|
internal sealed class ServiceTestContext
|
||||||
{
|
{
|
||||||
private string _validServerName = "validServerName.database.windows.net";
|
private string _validServerName = "validServerName.database.windows.net";
|
||||||
private string _startIpAddressValue = "1.2.3.6";
|
private string _startIpAddressValue = "1.2.3.6";
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.SqlProjects
|
|||||||
DatabaseVariable = "$(DatabaseVariable)"
|
DatabaseVariable = "$(DatabaseVariable)"
|
||||||
};
|
};
|
||||||
|
|
||||||
Assert.Throws<ArgumentException>(() => reference.Validate(), $"Validate() for a reference with both {nameof(reference.DatabaseLiteral)} and {nameof(reference.DatabaseVariable)} should have failed");
|
Assert.Throws<ArgumentException>(reference.Validate, $"Validate() for a reference with both {nameof(reference.DatabaseLiteral)} and {nameof(reference.DatabaseVariable)} should have failed");
|
||||||
|
|
||||||
// Verify that Validate() passes any other time
|
// Verify that Validate() passes any other time
|
||||||
reference = new AddDacpacReferenceParams() { DatabaseLiteral = "DatabaseName" };
|
reference = new AddDacpacReferenceParams() { DatabaseLiteral = "DatabaseName" };
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using NUnit.Framework;
|
|||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
||||||
{
|
{
|
||||||
public class ToSqlScriptTests
|
public partial class ToSqlScriptTests
|
||||||
{
|
{
|
||||||
#region FormatValue Tests
|
#region FormatValue Tests
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the integer type column
|
// Setup: Build a column and cell for the integer type column
|
||||||
DbColumn column = new FormatterTestDbColumn(dataType);
|
DbColumn column = new FormatterTestDbColumn(dataType);
|
||||||
DbCellValue cell = new DbCellValue { RawObject = (long)123 };
|
var cell = new DbCellValue { RawObject = (long)123 };
|
||||||
|
|
||||||
// If: I attempt to format an integer type column
|
// If: I attempt to format an integer type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
@@ -82,13 +82,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the decimal type column
|
// Setup: Build a column and cell for the decimal type column
|
||||||
DbColumn column = new FormatterTestDbColumn(dataType, precision, scale);
|
DbColumn column = new FormatterTestDbColumn(dataType, precision, scale);
|
||||||
DbCellValue cell = new DbCellValue { RawObject = 123.45m };
|
var cell = new DbCellValue { RawObject = 123.45m };
|
||||||
|
|
||||||
// If: I attempt to format a decimal type column
|
// If: I attempt to format a decimal type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: It should match a something like CAST(123.45 AS MONEY)
|
// Then: It should match a something like CAST(123.45 AS MONEY)
|
||||||
Regex castRegex = new Regex($@"CAST\([\d\.]+ AS {regex}", RegexOptions.IgnoreCase);
|
var castRegex = new Regex($@"CAST\([\d\.]+ AS {regex}", RegexOptions.IgnoreCase);
|
||||||
Assert.True(castRegex.IsMatch(output));
|
Assert.True(castRegex.IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the approx numeric type column
|
// Setup: Build a column and cell for the approx numeric type column
|
||||||
DbColumn column = new FormatterTestDbColumn("FLOAT");
|
DbColumn column = new FormatterTestDbColumn("FLOAT");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = 3.14159d };
|
var cell = new DbCellValue { RawObject = 3.14159d };
|
||||||
|
|
||||||
// If: I attempt to format a approx numeric type column
|
// If: I attempt to format a approx numeric type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
@@ -111,7 +111,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the approx numeric type column
|
// Setup: Build a column and cell for the approx numeric type column
|
||||||
DbColumn column = new FormatterTestDbColumn("REAL");
|
DbColumn column = new FormatterTestDbColumn("REAL");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = (float)3.14159 };
|
var cell = new DbCellValue { RawObject = (float)3.14159 };
|
||||||
|
|
||||||
// If: I attempt to format a approx numeric type column
|
// If: I attempt to format a approx numeric type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
@@ -129,15 +129,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the datetime type column
|
// Setup: Build a column and cell for the datetime type column
|
||||||
DbColumn column = new FormatterTestDbColumn(dataType);
|
DbColumn column = new FormatterTestDbColumn(dataType);
|
||||||
DbCellValue cell = new DbCellValue { RawObject = DateTime.Now };
|
var cell = new DbCellValue { RawObject = DateTime.Now };
|
||||||
|
|
||||||
// If: I attempt to format a datetime type column
|
// If: I attempt to format a datetime type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: The output string should be able to be converted back into a datetime
|
// Then: The output string should be able to be converted back into a datetime
|
||||||
Regex dateTimeRegex = new Regex("N'(.*)'");
|
|
||||||
DateTime outputDateTime;
|
DateTime outputDateTime;
|
||||||
Assert.True(DateTime.TryParse(dateTimeRegex.Match(output).Groups[1].Value, out outputDateTime));
|
Assert.True(DateTime.TryParse(GetDateTimeRegex().Match(output).Groups[1].Value, out outputDateTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -145,15 +144,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the datetime offset type column
|
// Setup: Build a column and cell for the datetime offset type column
|
||||||
DbColumn column = new FormatterTestDbColumn("DATETIMEOFFSET");
|
DbColumn column = new FormatterTestDbColumn("DATETIMEOFFSET");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = DateTimeOffset.Now };
|
var cell = new DbCellValue { RawObject = DateTimeOffset.Now };
|
||||||
|
|
||||||
// If: I attempt to format a datetime offset type column
|
// If: I attempt to format a datetime offset type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: The output string should be able to be converted back into a datetime offset
|
// Then: The output string should be able to be converted back into a datetime offset
|
||||||
Regex dateTimeRegex = new Regex("N'(.*)'");
|
|
||||||
DateTimeOffset outputDateTime;
|
DateTimeOffset outputDateTime;
|
||||||
Assert.True(DateTimeOffset.TryParse(dateTimeRegex.Match(output).Groups[1].Value, out outputDateTime));
|
Assert.True(DateTimeOffset.TryParse(GetDateTimeRegex().Match(output).Groups[1].Value, out outputDateTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -161,15 +159,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the time type column
|
// Setup: Build a column and cell for the time type column
|
||||||
DbColumn column = new FormatterTestDbColumn("TIME");
|
DbColumn column = new FormatterTestDbColumn("TIME");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = TimeSpan.FromHours(12) };
|
var cell = new DbCellValue { RawObject = TimeSpan.FromHours(12) };
|
||||||
|
|
||||||
// If: I attempt to format a time type column
|
// If: I attempt to format a time type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: The output string should be able to be converted back into a timespan
|
// Then: The output string should be able to be converted back into a timespan
|
||||||
Regex dateTimeRegex = new Regex("N'(.*)'");
|
|
||||||
TimeSpan outputDateTime;
|
TimeSpan outputDateTime;
|
||||||
Assert.True(TimeSpan.TryParse(dateTimeRegex.Match(output).Groups[1].Value, out outputDateTime));
|
Assert.True(TimeSpan.TryParse(GetDateTimeRegex().Match(output).Groups[1].Value, out outputDateTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly object[] stringFormats =
|
private static readonly object[] stringFormats =
|
||||||
@@ -186,7 +183,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
// Setup: Build a column and cell for the string type column
|
// Setup: Build a column and cell for the string type column
|
||||||
// NOTE: We're using VARCHAR because it's very general purpose.
|
// NOTE: We're using VARCHAR because it's very general purpose.
|
||||||
DbColumn column = new FormatterTestDbColumn("VARCHAR");
|
DbColumn column = new FormatterTestDbColumn("VARCHAR");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = input };
|
var cell = new DbCellValue { RawObject = input };
|
||||||
|
|
||||||
// If: I attempt to format a string type column
|
// If: I attempt to format a string type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
@@ -208,7 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the string type column
|
// Setup: Build a column and cell for the string type column
|
||||||
DbColumn column = new FormatterTestDbColumn(datatype);
|
DbColumn column = new FormatterTestDbColumn(datatype);
|
||||||
DbCellValue cell = new DbCellValue { RawObject = "test string" };
|
var cell = new DbCellValue { RawObject = "test string" };
|
||||||
|
|
||||||
// If: I attempt to format a string type column
|
// If: I attempt to format a string type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
@@ -222,17 +219,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the string type column
|
// Setup: Build a column and cell for the string type column
|
||||||
DbColumn column = new FormatterTestDbColumn(datatype);
|
DbColumn column = new FormatterTestDbColumn(datatype);
|
||||||
DbCellValue cell = new DbCellValue
|
var cell = new DbCellValue
|
||||||
{
|
{
|
||||||
RawObject = new byte[] { 0x42, 0x45, 0x4e, 0x49, 0x53, 0x43, 0x4f, 0x4f, 0x4c }
|
RawObject = "BENISCOOL"u8.ToArray()
|
||||||
};
|
};
|
||||||
|
|
||||||
// If: I attempt to format a string type column
|
// If: I attempt to format a string type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: The output string should match the output string
|
// Then: The output string should match the output string
|
||||||
Regex regex = new Regex("0x[0-9A-F]+", RegexOptions.IgnoreCase);
|
Assert.True(GetOuputRegex().IsMatch(output));
|
||||||
Assert.True(regex.IsMatch(output));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -240,13 +236,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
{
|
{
|
||||||
// Setup: Build a column and cell for the string type column
|
// Setup: Build a column and cell for the string type column
|
||||||
DbColumn column = new FormatterTestDbColumn("UNIQUEIDENTIFIER");
|
DbColumn column = new FormatterTestDbColumn("UNIQUEIDENTIFIER");
|
||||||
DbCellValue cell = new DbCellValue { RawObject = Guid.NewGuid() };
|
var cell = new DbCellValue { RawObject = Guid.NewGuid() };
|
||||||
|
|
||||||
// If: I attempt to format a string type column
|
// If: I attempt to format a string type column
|
||||||
string output = ToSqlScript.FormatValue(cell, column);
|
string output = ToSqlScript.FormatValue(cell, column);
|
||||||
|
|
||||||
// Then: The output string should match the output string
|
// Then: The output string should match the output string
|
||||||
Regex regex = new Regex(@"N'[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}'", RegexOptions.IgnoreCase);
|
var regex = GetGuidRegex();
|
||||||
Assert.True(regex.IsMatch(output));
|
Assert.True(regex.IsMatch(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,7 +387,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private class FormatterTestDbColumn : DbColumn
|
private sealed class FormatterTestDbColumn : DbColumn
|
||||||
{
|
{
|
||||||
public FormatterTestDbColumn(string dataType, int? precision = null, int? scale = null, int? size = null)
|
public FormatterTestDbColumn(string dataType, int? precision = null, int? scale = null, int? size = null)
|
||||||
{
|
{
|
||||||
@@ -401,5 +397,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.UtilityTests
|
|||||||
ColumnSize = size;
|
ColumnSize = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex("0x[0-9A-F]+", RegexOptions.IgnoreCase, "en-CA")]
|
||||||
|
private static partial Regex GetOuputRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("N'[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}'", RegexOptions.IgnoreCase, "en-CA")]
|
||||||
|
private static partial Regex GetGuidRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("N'(.*)'")]
|
||||||
|
private static partial Regex GetDateTimeRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user