mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-30 01:25:45 -05:00
Address warnings and (some) nullables (#2013)
This commit is contained in:
@@ -3,8 +3,6 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -51,9 +49,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
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)
|
||||
@@ -82,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
var azureEdition =
|
||||
AzureServiceObjectiveInfo.Keys.FirstOrDefault(
|
||||
key => key.Name.ToLowerInvariant().Equals(edition.ToLowerInvariant()));
|
||||
if (azureEdition != null)
|
||||
if (azureEdition! != null)
|
||||
{
|
||||
return azureEdition;
|
||||
}
|
||||
@@ -358,9 +356,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
||||
/// <returns>StorageAccountType string value for the current storageType</returns>
|
||||
public static string GetStorageAccountTypeFromString(string storageAccountType)
|
||||
{
|
||||
if (bsrAPIToUIValueMapping.ContainsKey(storageAccountType))
|
||||
if (bsrAPIToUIValueMapping.TryGetValue(storageAccountType, out string? value))
|
||||
{
|
||||
return bsrAPIToUIValueMapping[storageAccountType];
|
||||
return value;
|
||||
}
|
||||
return storageAccountType;
|
||||
}
|
||||
|
||||
@@ -1100,7 +1100,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
STParameters param = new STParameters(dataContainer.Document);
|
||||
@@ -1132,7 +1132,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
||||
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);
|
||||
|
||||
STParameters param = new STParameters(dataContainer.Document);
|
||||
@@ -1487,9 +1487,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
string jobRuntime = jobHistory.RunDate.ToString("yyyyMMddHHmmss");
|
||||
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.MaterializedNotebookName = notebookHistoriesDict[jobRuntime]["notebook_name"] as string;
|
||||
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.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -32,54 +30,56 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
this.data = data;
|
||||
var availableSystems =
|
||||
dataContainer.Server.JobServer.EnumSubSystems()
|
||||
dataContainer.Server?.JobServer.EnumSubSystems()
|
||||
.Rows.OfType<DataRow>()
|
||||
.Select(r => (AgentSubSystem)Convert.ToInt32(r["subsystem_id"]));
|
||||
|
||||
foreach (var agentSubSystemId in availableSystems)
|
||||
if (availableSystems != null)
|
||||
{
|
||||
var agentSubSystem = CreateJobStepSubSystem(agentSubSystemId, dataContainer, data);
|
||||
// The server might have some new subsystem we don't know about, just ignore it.
|
||||
if (agentSubSystem != null)
|
||||
foreach (var agentSubSystemId in availableSystems)
|
||||
{
|
||||
subSystems[agentSubSystemId] = agentSubSystem;
|
||||
var agentSubSystem = CreateJobStepSubSystem(agentSubSystemId, dataContainer, data);
|
||||
// The server might have some new subsystem we don't know about, just ignore it.
|
||||
if (agentSubSystem != null)
|
||||
{
|
||||
subSystems[agentSubSystemId] = agentSubSystem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
JobStepSubSystem rv = null;
|
||||
if (this.subSystems.ContainsKey(key))
|
||||
if (this.subSystems.TryGetValue(key, out JobStepSubSystem? value))
|
||||
{
|
||||
return this.subSystems[key];
|
||||
return value;
|
||||
}
|
||||
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
|
||||
public static string LookupFriendlyName(AgentSubSystem key)
|
||||
{
|
||||
return (string)typeConverter.ConvertToString((Enum)key);
|
||||
}
|
||||
|
||||
|
||||
// Returns name of the subsystem for a given enum value
|
||||
public static string LookupName(AgentSubSystem key)
|
||||
{
|
||||
// Have to subtract first enum value to bring the
|
||||
// index to 0-based index
|
||||
return typeConverter.ConvertToInvariantString((Enum) key);
|
||||
return typeConverter.ConvertToInvariantString((Enum)key);
|
||||
}
|
||||
|
||||
private static JobStepSubSystem CreateJobStepSubSystem(
|
||||
AgentSubSystem agentSubSystem,
|
||||
CDataContainer dataContainer,
|
||||
AgentSubSystem agentSubSystem,
|
||||
CDataContainer dataContainer,
|
||||
JobStepData data)
|
||||
{
|
||||
switch (agentSubSystem)
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
if (jobData.Job != null)
|
||||
{
|
||||
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);
|
||||
jobStep = jobData.Job.Parent.Parent.GetSmoObject(urn) as JobStep;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
/// simple job schedule structure.
|
||||
/// </summary>
|
||||
|
||||
public struct SimpleJobSchedule
|
||||
public partial struct SimpleJobSchedule
|
||||
{
|
||||
#region consts
|
||||
private const int EndOfDay = 235959;
|
||||
@@ -44,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
private FrequencyTypes frequencyTypes;
|
||||
private FrequencySubDayTypes frequencySubDayTypes;
|
||||
private FrequencyRelativeIntervals frequencyRelativeIntervals;
|
||||
private System.Boolean isEnabled;
|
||||
private bool isEnabled;
|
||||
#endregion
|
||||
|
||||
#region Init
|
||||
@@ -100,7 +100,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
public static DateTime ConvertIntToDateTime(int source)
|
||||
{
|
||||
return new DateTime(source / 10000
|
||||
, (source / 100) % 100
|
||||
, source / 100 % 100
|
||||
, source % 100);
|
||||
}
|
||||
/// <summary>
|
||||
@@ -126,7 +126,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
public static TimeSpan ConvertIntToTimeSpan(int source)
|
||||
{
|
||||
return new TimeSpan(source / 10000
|
||||
, (source / 100) % 100
|
||||
, source / 100 % 100
|
||||
, source % 100);
|
||||
}
|
||||
/// <summary>
|
||||
@@ -150,13 +150,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
/// <returns>JobScheduleData object</returns>
|
||||
public JobScheduleData ToJobScheduleData()
|
||||
{
|
||||
JobScheduleData data = new JobScheduleData();
|
||||
var data = new JobScheduleData();
|
||||
data.Name = this.Name;
|
||||
data.Enabled = this.IsEnabled;
|
||||
data.ActiveStartDate = SimpleJobSchedule.ConvertIntToDateLocalized(this.ActiveStartDate);
|
||||
data.ActiveStartTime = SimpleJobSchedule.ConvertIntToTimeSpan(this.ActiveStartTimeOfDay);
|
||||
data.ActiveEndDate = SimpleJobSchedule.ConvertIntToDateLocalized(this.ActiveEndDate);
|
||||
data.ActiveEndTime = SimpleJobSchedule.ConvertIntToTimeSpan(this.ActiveEndTimeOfDay);
|
||||
data.ActiveStartDate = ConvertIntToDateLocalized(this.ActiveStartDate);
|
||||
data.ActiveStartTime = ConvertIntToTimeSpan(this.ActiveStartTimeOfDay);
|
||||
data.ActiveEndDate = ConvertIntToDateLocalized(this.ActiveEndDate);
|
||||
data.ActiveEndTime = ConvertIntToTimeSpan(this.ActiveEndTimeOfDay);
|
||||
data.FrequencyTypes = this.FrequencyTypes;
|
||||
data.FrequencyInterval = this.FrequencyInterval;
|
||||
data.FrequencyRecurranceFactor = this.FrequencyRecurrenceFactor;
|
||||
@@ -173,15 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
/// <returns>new SimpleJobSchedule</returns>
|
||||
public static SimpleJobSchedule FromJobScheduleData(JobScheduleData source)
|
||||
{
|
||||
SimpleJobSchedule schedule = new SimpleJobSchedule();
|
||||
var schedule = new SimpleJobSchedule();
|
||||
|
||||
schedule.Name = source.Name;
|
||||
schedule.ID = source.ID;
|
||||
schedule.IsEnabled = source.Enabled;
|
||||
schedule.ActiveStartDate = SimpleJobSchedule.ConvertDateTimeToInt(source.ActiveStartDate);
|
||||
schedule.ActiveStartTimeOfDay = SimpleJobSchedule.ConvertTimeSpanToInt(source.ActiveStartTime);
|
||||
schedule.ActiveEndDate = SimpleJobSchedule.ConvertDateTimeToInt(source.ActiveEndDate);
|
||||
schedule.ActiveEndTimeOfDay = SimpleJobSchedule.ConvertTimeSpanToInt(source.ActiveEndTime);
|
||||
schedule.ActiveStartDate = ConvertDateTimeToInt(source.ActiveStartDate);
|
||||
schedule.ActiveStartTimeOfDay = ConvertTimeSpanToInt(source.ActiveStartTime);
|
||||
schedule.ActiveEndDate = ConvertDateTimeToInt(source.ActiveEndDate);
|
||||
schedule.ActiveEndTimeOfDay = ConvertTimeSpanToInt(source.ActiveEndTime);
|
||||
schedule.FrequencyTypes = source.FrequencyTypes;
|
||||
schedule.FrequencyInterval = source.FrequencyInterval;
|
||||
schedule.FrequencyRecurrenceFactor = source.FrequencyRecurranceFactor;
|
||||
@@ -293,7 +293,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
StringBuilder daysOfWeek = new StringBuilder();
|
||||
var daysOfWeek = new StringBuilder();
|
||||
// Start matching with Monday. GetLocalizedDaysOfWeek() must start with Monday too.
|
||||
WeekDays dayOfWeek = WeekDays.Monday;
|
||||
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
|
||||
// it's a bitfield mask we do a left shift ourselves.
|
||||
int nextDay = ((int)dayOfWeek) << 1;
|
||||
int nextDay = (int)dayOfWeek << 1;
|
||||
dayOfWeek = (WeekDays)nextDay;
|
||||
if (dayOfWeek > WeekDays.Saturday)
|
||||
{
|
||||
@@ -449,7 +449,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
get
|
||||
{
|
||||
MonthlyRelativeWeekDays relativeDays = (MonthlyRelativeWeekDays) this.FrequencyInterval;
|
||||
var relativeDays = (MonthlyRelativeWeekDays) this.FrequencyInterval;
|
||||
|
||||
switch (relativeDays)
|
||||
{
|
||||
@@ -671,10 +671,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
/// <returns></returns>
|
||||
string ExpandFormatString(string format)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
var stringBuilder = new StringBuilder();
|
||||
int lastIndex = 0;
|
||||
|
||||
MatchCollection matches = Regex.Matches(format, @"\{(?<property>\w+)\}");
|
||||
MatchCollection matches = GetPropertyDescriptorRegex().Matches(format);
|
||||
|
||||
if (matches.Count > 0)
|
||||
{
|
||||
@@ -687,7 +687,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
if (property != null)
|
||||
{
|
||||
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(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" };
|
||||
}
|
||||
|
||||
[GeneratedRegex("\\{(?<property>\\w+)\\}")]
|
||||
private static partial Regex GetPropertyDescriptorRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Microsoft.SqlTools.ServiceLayer.AzureFunctions
|
||||
return a.ArgumentList
|
||||
?.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)
|
||||
.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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1420,7 +1420,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
{
|
||||
// Secure Enclaves is not mapped to SqlConnection, it's only used for throwing validation errors
|
||||
// when Enclave Attestation Protocol is missing.
|
||||
switch (connectionDetails.SecureEnclaves.ToUpper())
|
||||
switch (connectionDetails.SecureEnclaves.ToUpper(CultureInfo.InvariantCulture))
|
||||
{
|
||||
case "ENABLED":
|
||||
if (string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
||||
@@ -1437,7 +1437,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -1454,7 +1454,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
||||
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationUrl))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
||||
/// </summary>
|
||||
public static ModelTypeClass MapType(string type)
|
||||
{
|
||||
switch (type.ToLower())
|
||||
switch (type.ToLower(System.Globalization.CultureInfo.InvariantCulture))
|
||||
{
|
||||
case "table":
|
||||
return ModelSchema.Table;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -49,9 +47,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
/// <returns></returns>
|
||||
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
|
||||
{
|
||||
@@ -68,9 +66,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
/// <param name="optionInfo"></param>
|
||||
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 defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
||||
var validateResult = builder.ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
||||
@@ -102,9 +100,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
{
|
||||
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))
|
||||
{
|
||||
try
|
||||
@@ -149,15 +146,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
public string ValidateOption(string optionKey, IRestoreDatabaseTaskDataObject restoreDataObject)
|
||||
{
|
||||
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 defaultValue = builder.DefaultValueFunction(restoreDataObject);
|
||||
OptionValidationResult result = optionBuilders[optionKey].ValidateFunction(restoreDataObject, currentValue, defaultValue);
|
||||
if (result.IsReadOnly)
|
||||
{
|
||||
if(!ValueEqualsDefault(currentValue, defaultValue))
|
||||
if (!ValueEqualsDefault(currentValue, defaultValue))
|
||||
{
|
||||
builder.SetValueFunction(restoreDataObject, defaultValue);
|
||||
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)
|
||||
{
|
||||
if(currentValue == null && defaultValue == null)
|
||||
if (currentValue == null)
|
||||
{
|
||||
return true;
|
||||
return defaultValue == null;
|
||||
}
|
||||
if(currentValue == null && defaultValue != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (currentValue != null && defaultValue == null)
|
||||
else if (defaultValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -200,311 +192,311 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
{
|
||||
Register(RestoreOptionsHelper.RelocateDbFiles,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return false;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RelocateAllFiles;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult
|
||||
{
|
||||
IsReadOnly = restoreDataObject.DbFiles.Count == 0
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RelocateAllFiles = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.RelocateDbFiles);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.DataFileFolder,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DefaultDataFileFolder;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DataFilesFolder;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.DataFilesFolder = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.LogFileFolder,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DefaultLogFileFolder;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.LogFilesFolder;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.RelocateAllFiles
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.LogFilesFolder = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.ReplaceDatabase,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return false;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RestoreOptions.ReplaceDatabase;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult();
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RestoreOptions.ReplaceDatabase = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.KeepReplication,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return false;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RestoreOptions.KeepReplication;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState == DatabaseRecoveryState.WithNoRecovery
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RestoreOptions.KeepReplication = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.SetRestrictedUser,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return false;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RestoreOptions.SetRestrictedUser;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RestoreOptions.SetRestrictedUser = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.RecoveryState,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return DatabaseRecoveryState.WithRecovery.ToString();
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RestoreOptions.RecoveryState.ToString();
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RestoreOptions.RecoveryState = GetValueAs<DatabaseRecoveryState>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.StandbyFile,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DefaultStandbyFile;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.RestoreOptions.StandByFile;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = restoreDataObject.RestoreOptions.RecoveryState != DatabaseRecoveryState.WithStandBy
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.RestoreOptions.StandByFile = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.BackupTailLog,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.IsTailLogBackupPossible;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.BackupTailLog;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.IsTailLogBackupPossible
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.BackupTailLog = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.TailLogBackupFile,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DefaultTailLogbackupFile;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.TailLogBackupFile;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupPossible
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.TailLogBackupFile = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.TailLogWithNoRecovery,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.IsTailLogBackupWithNoRecoveryPossible;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.TailLogWithNoRecovery;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.BackupTailLog | !restoreDataObject.IsTailLogBackupWithNoRecoveryPossible
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.TailLogWithNoRecovery = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.CloseExistingConnections,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return false;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.CloseExistingConnections;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = !restoreDataObject.CanDropExistingConnections
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.CloseExistingConnections = GetValueAs<bool>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.SourceDatabaseName,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.DefaultSourceDbName;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.SourceDatabaseName;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
string errorMessage = string.Empty;
|
||||
var sourceDbNames = restoreDataObject.SourceDbNames;
|
||||
@@ -514,41 +506,41 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
}
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
ErrorMessage = errorMessage
|
||||
ErrorMessage = errorMessage
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.SourceDatabaseName = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
Register(RestoreOptionsHelper.TargetDatabaseName,
|
||||
new OptionBuilder
|
||||
{
|
||||
DefaultValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
(
|
||||
defaultValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.OverwriteTargetDatabase ? restoreDataObject.DefaultSourceDbName : restoreDataObject.DefaultTargetDbName;
|
||||
},
|
||||
CurrentValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
currentValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject) =>
|
||||
{
|
||||
return restoreDataObject.TargetDatabaseName;
|
||||
},
|
||||
ValidateFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
validateFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object currentValue, object defaultValue) =>
|
||||
{
|
||||
return new OptionValidationResult()
|
||||
{
|
||||
IsReadOnly = false
|
||||
};
|
||||
},
|
||||
SetValueFunction = (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
setValueFunction: (IRestoreDatabaseTaskDataObject restoreDataObject, object value) =>
|
||||
{
|
||||
|
||||
restoreDataObject.TargetDatabaseName = GetValueAs<string>(value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
internal T GetValueAs<T>(object value)
|
||||
@@ -562,7 +554,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
}
|
||||
|
||||
private RestorePlanDetailInfo Create(
|
||||
string optionKey,
|
||||
string optionKey,
|
||||
IRestoreDatabaseTaskDataObject restoreDataObject,
|
||||
OptionBuilder optionBuilder)
|
||||
{
|
||||
@@ -587,6 +579,14 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
|
||||
public Func<IRestoreDatabaseTaskDataObject, object, object, OptionValidationResult> ValidateFunction { get; set; }
|
||||
public Func<IRestoreDatabaseTaskDataObject, object> CurrentValueFunction { 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
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
/// <summary>
|
||||
/// Representation of a cell that should have a value inserted or updated
|
||||
/// </summary>
|
||||
public sealed class CellUpdate
|
||||
public sealed partial class CellUpdate
|
||||
{
|
||||
private const string NullString = @"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);
|
||||
|
||||
/// <summary>
|
||||
@@ -231,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
|
||||
private void ProcessTimespanColumn(string valueAsString)
|
||||
{
|
||||
TimeSpan ts = TimeSpan.Parse(valueAsString, CultureInfo.CurrentCulture);
|
||||
var ts = TimeSpan.Parse(valueAsString, CultureInfo.CurrentCulture);
|
||||
if (ts >= MaxTimespan)
|
||||
{
|
||||
throw new InvalidOperationException(SR.EditDataTimeOver24Hrs);
|
||||
@@ -270,6 +270,9 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
ValueAsString = valueAsString;
|
||||
}
|
||||
|
||||
[GeneratedRegex("0x[0-9A-F]+", RegexOptions.IgnoreCase | RegexOptions.Compiled)]
|
||||
private static partial Regex GetCharacterRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
/// <summary>
|
||||
/// Base class for building hierarchy of Graph objects from ShowPlan Record Set
|
||||
/// </summary>
|
||||
internal abstract class DataReaderNodeBuilder: INodeBuilder
|
||||
internal abstract partial class DataReaderNodeBuilder: INodeBuilder
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
/// <returns>An array of AnalysisServices Graph objects.</returns>
|
||||
public ShowPlanGraph[] Execute(object dataSource)
|
||||
{
|
||||
IDataReader reader = dataSource as IDataReader;
|
||||
var reader = dataSource as IDataReader;
|
||||
|
||||
if (reader == null)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
throw new ArgumentException(SR.Keys.UnknownShowPlanSource);
|
||||
}
|
||||
|
||||
List<ShowPlanGraph> graphs = new List<ShowPlanGraph>();
|
||||
var graphs = new List<ShowPlanGraph>();
|
||||
Dictionary<int, Node> currentGraphNodes = null;
|
||||
NodeBuilderContext context = null;
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
|
||||
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];
|
||||
}
|
||||
@@ -220,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
string argument = node["Argument"] as string;
|
||||
if (argument != null)
|
||||
{
|
||||
Match match = argumentObjectExpression.Match(argument);
|
||||
Match match = GetargumentObjectExpressionRegex().Match(argument);
|
||||
if (match != Match.Empty)
|
||||
{
|
||||
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
|
||||
physicalOpType = operatorReplaceExpression.Replace(physicalOpType, "");
|
||||
logicalOpType = operatorReplaceExpression.Replace(logicalOpType, "");
|
||||
physicalOpType = GetOperatorReplaceExpressionRegex().Replace(physicalOpType, "");
|
||||
logicalOpType = GetOperatorReplaceExpressionRegex().Replace(logicalOpType, "");
|
||||
|
||||
Operation physicalOp = OperationTable.GetPhysicalOperation(physicalOpType);
|
||||
Operation logicalOp = OperationTable.GetLogicalOperation(logicalOpType);
|
||||
@@ -290,8 +290,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
|
||||
|
||||
#region Private members
|
||||
|
||||
private static Regex operatorReplaceExpression = new Regex(@"[ \-]", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
private static Regex argumentObjectExpression = new Regex(@"OBJECT:\((?<Object>[^\)]*)\)", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
[GeneratedRegex("[ \\-]", RegexOptions.Compiled | RegexOptions.CultureInvariant)]
|
||||
private static partial Regex GetOperatorReplaceExpressionRegex();
|
||||
|
||||
[GeneratedRegex("OBJECT:\\((?<Object>[^\\)]*)\\)", RegexOptions.Compiled | RegexOptions.CultureInvariant)]
|
||||
private static partial Regex GetargumentObjectExpressionRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -191,10 +191,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
||||
{
|
||||
lock (this.bindingContextLock)
|
||||
{
|
||||
if (this.BindingContextMap.ContainsKey(key))
|
||||
if (this.BindingContextMap.TryGetValue(key, out IBindingContext? bindingContext))
|
||||
{
|
||||
// disconnect existing connection
|
||||
var bindingContext = this.BindingContextMap[key];
|
||||
if (bindingContext.ServerConnection != null && bindingContext.ServerConnection.IsOpen)
|
||||
{
|
||||
// Disconnecting can take some time so run it in a separate task so that it doesn't block removal
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
||||
/// <summary>
|
||||
/// Creates a completion item from SQL parser declaration item
|
||||
/// </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 FunctionPostfix = new DelimitedIdentifier { Start = "", End = "()" };
|
||||
private static DelimitedIdentifier[] DelimitedIdentifiers =
|
||||
@@ -79,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
||||
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 [)
|
||||
// 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);
|
||||
}
|
||||
@@ -197,7 +198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion
|
||||
int startColumn,
|
||||
int endColumn)
|
||||
{
|
||||
CompletionItem item = new CompletionItem()
|
||||
var item = new CompletionItem()
|
||||
{
|
||||
Label = label,
|
||||
Kind = kind,
|
||||
|
||||
@@ -1869,10 +1869,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
||||
{
|
||||
lock (this.parseMapLock)
|
||||
{
|
||||
if (this.ScriptParseInfoMap.ContainsKey(uri))
|
||||
if (this.ScriptParseInfoMap.TryGetValue(uri, out ScriptParseInfo value))
|
||||
{
|
||||
Logger.Verbose($"Found ScriptParseInfo for uri {uri}");
|
||||
return this.ScriptParseInfoMap[uri];
|
||||
return value;
|
||||
}
|
||||
else if (createIfNotExists)
|
||||
{
|
||||
|
||||
@@ -1191,7 +1191,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
||||
<urn>Server[@Name='{0}']</urn>
|
||||
<itemtype>Database</itemtype>
|
||||
</params></formdescription> ",
|
||||
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
||||
connInfo.ConnectionDetails.ServerName.ToUpper(CultureInfo.InvariantCulture),
|
||||
connInfo.ConnectionDetails.UserName);
|
||||
}
|
||||
else
|
||||
@@ -1205,7 +1205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
||||
<urn>Server[@Name='{0}']</urn>
|
||||
<database>{2}</database>
|
||||
</params></formdescription> ",
|
||||
connInfo.ConnectionDetails.ServerName.ToUpper(),
|
||||
connInfo.ConnectionDetails.ServerName.ToUpper(CultureInfo.InvariantCulture),
|
||||
connInfo.ConnectionDetails.UserName,
|
||||
connInfo.ConnectionDetails.DatabaseName);
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
@@ -114,9 +114,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
|
||||
if ((currentEvent.Name.Equals("sql_batch_completed")
|
||||
|| 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");
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// <summary>
|
||||
/// Writer for exporting results to a Markdown table.
|
||||
/// </summary>
|
||||
public class SaveAsMarkdownFileStreamWriter : SaveAsStreamWriter
|
||||
public partial class SaveAsMarkdownFileStreamWriter : SaveAsStreamWriter
|
||||
{
|
||||
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 string _lineSeparator;
|
||||
@@ -72,7 +74,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
this.WriteLine($"{Delimiter}{rowLine}{Delimiter}");
|
||||
}
|
||||
|
||||
internal static string EncodeMarkdownField(string? field)
|
||||
internal static string EncodeMarkdownField(string field)
|
||||
{
|
||||
// Special case for nulls
|
||||
if (field == null)
|
||||
@@ -89,7 +91,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
// @TODO: Allow option to encode multiple whitespace characters as
|
||||
|
||||
// Replace newlines with br tags, since cell values must be single line
|
||||
field = NewlineRegex.Replace(field, @"<br />");
|
||||
field = GetNewLineRegex().Replace(field, @"<br />");
|
||||
|
||||
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
|
||||
/// storing and retrieving results. Is contained by a Batch class.
|
||||
/// </summary>
|
||||
public class ResultSet : IDisposable
|
||||
public partial class ResultSet : IDisposable
|
||||
{
|
||||
#region Constants
|
||||
|
||||
@@ -279,7 +279,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
// 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);
|
||||
string singleString = string.Join(string.Empty, rowValues);
|
||||
DbCellValue cellValue = new DbCellValue
|
||||
var cellValue = new DbCellValue
|
||||
{
|
||||
DisplayValue = singleString,
|
||||
IsNull = false,
|
||||
@@ -369,7 +369,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
// Verify the request hasn't been cancelled
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
||||
var dataReader = new StorageDataReader(dbDataReader);
|
||||
|
||||
// Open a writer for the file
|
||||
//
|
||||
@@ -514,7 +514,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
}
|
||||
|
||||
// Create the new task
|
||||
Task saveAsTask = new Task(async () =>
|
||||
var saveAsTask = new Task(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -638,7 +638,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
//
|
||||
sendResultsSemphore.Wait();
|
||||
|
||||
ResultSet currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
||||
var currentResultSetSnapshot = (ResultSet) MemberwiseClone();
|
||||
if (LastUpdatedSummary == null) // We need to send results available message.
|
||||
{
|
||||
// Fire off results Available task and await it
|
||||
@@ -739,13 +739,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
if (Columns?.Length > 0 && RowCount != 0)
|
||||
{
|
||||
Regex regex = new Regex(@"({.*?})");
|
||||
var row = GetRow(0);
|
||||
for (int i = 0; i < Columns.Length; i++)
|
||||
{
|
||||
if (Columns[i].DataTypeName.Equals("nvarchar"))
|
||||
{
|
||||
if (regex.IsMatch(row[i].DisplayValue))
|
||||
if (GetJsonRegex().IsMatch(row[i].DisplayValue))
|
||||
{
|
||||
Columns[i].IsJson = true;
|
||||
}
|
||||
@@ -788,7 +787,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
// Returning false from .ReadAsync means there aren't any rows.
|
||||
|
||||
// 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))
|
||||
{
|
||||
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
||||
@@ -804,6 +803,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
}
|
||||
}
|
||||
|
||||
[GeneratedRegex("({.*?})")]
|
||||
private static partial Regex GetJsonRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
/// <summary>
|
||||
/// Internal class for utilities shared between multiple schema compare operations
|
||||
/// </summary>
|
||||
internal static class SchemaCompareUtils
|
||||
internal static partial class SchemaCompareUtils
|
||||
{
|
||||
internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
|
||||
{
|
||||
@@ -31,7 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
return null;
|
||||
}
|
||||
|
||||
DiffEntry diffEntry = new DiffEntry();
|
||||
var diffEntry = new DiffEntry();
|
||||
diffEntry.UpdateAction = difference.UpdateAction;
|
||||
diffEntry.DifferenceType = difference.DifferenceType;
|
||||
diffEntry.Name = difference.Name;
|
||||
@@ -86,8 +86,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ObjectIdentifier id = new ObjectIdentifier(sourceObj.NameParts);
|
||||
SchemaComparisonExcludedObjectId excludedObjId = new SchemaComparisonExcludedObjectId(sourceObj.SqlObjectType, id);
|
||||
var id = new ObjectIdentifier(sourceObj.NameParts);
|
||||
var excludedObjId = new SchemaComparisonExcludedObjectId(sourceObj.SqlObjectType, id);
|
||||
return excludedObjId;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
@@ -145,7 +145,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
// remove leading and trailing whitespace
|
||||
script = script.Trim();
|
||||
// replace all multiple spaces with single space
|
||||
script = Regex.Replace(script, " {2,}", " ");
|
||||
script = GetScriptRegex().Replace(script, " ");
|
||||
}
|
||||
return script;
|
||||
}
|
||||
@@ -159,5 +159,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
[GeneratedRegex(" {2,}")]
|
||||
private static partial Regex GetScriptRegex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
string tokenType = GetTokenTypeFromQuickInfo(quickInfoText, tokenText, caseSensitivity);
|
||||
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.
|
||||
// This workaround ensures that a schema name is present by attempting
|
||||
@@ -203,8 +203,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
Location[] locations = GetSqlObjectDefinition(
|
||||
tokenText,
|
||||
schemaName,
|
||||
sqlObjectTypesFromQuickInfo[tokenType.ToLowerInvariant()]
|
||||
);
|
||||
sqlObjectType);
|
||||
DefinitionResult result = new DefinitionResult
|
||||
{
|
||||
IsErrorResult = this.error,
|
||||
@@ -232,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
/// <returns></returns>
|
||||
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.
|
||||
// This workaround ensures that a schema name is present by attempting
|
||||
@@ -246,8 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
Location[] locations = GetSqlObjectDefinition(
|
||||
tokenText,
|
||||
schemaName,
|
||||
sqlObjectTypes[type]
|
||||
);
|
||||
sqlObjectType);
|
||||
DefinitionResult result = new DefinitionResult
|
||||
{
|
||||
IsErrorResult = this.error,
|
||||
@@ -288,7 +286,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Scripting
|
||||
string[] lines = File.ReadAllLines(tempFileName);
|
||||
int lineCount = 0;
|
||||
string createSyntax = null;
|
||||
if (objectScriptMap.ContainsKey(objectType.ToLower()))
|
||||
if (objectScriptMap.ContainsKey(objectType.ToLower(System.Globalization.CultureInfo.InvariantCulture)))
|
||||
{
|
||||
createSyntax = string.Format("CREATE");
|
||||
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.
|
||||
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));
|
||||
|
||||
bool hasParentObject = !string.IsNullOrWhiteSpace(scriptingObject.ParentName)
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility
|
||||
{
|
||||
get
|
||||
{
|
||||
return ClientUri?.ToLower();
|
||||
return ClientUri?.ToLower(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
||||
/// <summary>
|
||||
/// Provides utilities for converting from SQL script syntax into POCOs.
|
||||
/// </summary>
|
||||
public static class FromSqlScript
|
||||
public static partial class FromSqlScript
|
||||
{
|
||||
// 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 BracketRegex = new Regex(@"^\[(.*)\]$", RegexOptions.Compiled);
|
||||
[GeneratedRegex("^N?'(.*)'$", RegexOptions.Compiled)]
|
||||
private static partial Regex GetStringRegex();
|
||||
|
||||
[GeneratedRegex("^\\[(.*)\\]$", RegexOptions.Compiled)]
|
||||
private static partial Regex GetBracketRegex();
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public static string[] DecodeMultipartIdentifier(string multipartIdentifier)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<string> namedParts = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
var namedParts = new List<string>();
|
||||
bool insideBrackets = false;
|
||||
bool bracketsClosed = false;
|
||||
for (int i = 0; i < multipartIdentifier.Length; i++)
|
||||
@@ -122,7 +125,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
||||
literal = literal.Trim('(', ')');
|
||||
|
||||
// Attempt to unwrap inverted commas around a string
|
||||
Match match = StringRegex.Match(literal);
|
||||
Match match = GetStringRegex().Match(literal);
|
||||
if (match.Success)
|
||||
{
|
||||
// Like: N'stuff' or 'stuff'
|
||||
@@ -136,7 +139,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters
|
||||
/// </summary>
|
||||
/// <param name="identifer">Identifier to check.</param>
|
||||
/// <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
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace.Contracts
|
||||
/// </summary>
|
||||
public string Id
|
||||
{
|
||||
get { return this.ClientUri.ToLower(); }
|
||||
get { return this.ClientUri.ToLower(System.Globalization.CultureInfo.InvariantCulture); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
||||
/// Manages a "workspace" of script files that are open for a particular
|
||||
/// editing session. Also helps to navigate references between ScriptFiles.
|
||||
/// </summary>
|
||||
public class Workspace : IDisposable
|
||||
public partial class Workspace : IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
@@ -117,8 +117,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
||||
}
|
||||
// This method allows FileNotFoundException to bubble up
|
||||
// if the file isn't found.
|
||||
using (FileStream fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
||||
using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||
using (var fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read))
|
||||
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
|
||||
{
|
||||
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
|
||||
// any extraneous slashes
|
||||
Uri fileUri = new Uri(clientUri);
|
||||
var fileUri = new Uri(clientUri);
|
||||
filePath = fileUri.LocalPath;
|
||||
if (filePath.StartsWith("//") || filePath.StartsWith("\\\\") || filePath.StartsWith("/"))
|
||||
{
|
||||
@@ -208,7 +208,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
||||
return path;
|
||||
}
|
||||
|
||||
return Regex.Replace(path, @"`(?=[ \[\]])", "");
|
||||
return GetEscapeRegex().Replace(path, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -363,6 +363,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
|
||||
{
|
||||
}
|
||||
|
||||
[GeneratedRegex("`(?=[ \\[\\]])")]
|
||||
private static partial Regex GetEscapeRegex();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user