mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-19 01:25:40 -05:00
Edit Data: Better Formatting Errors (#562)
* Refactoring sql script formatting helpers into To and From helpers * Updates to make error messages for formatting errors more useful * Fixing dumb breaks in unit tests * Addressing comments from PR * Updates to the SR files...
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
@@ -34,50 +35,60 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
Validate.IsNotNull(nameof(valueAsString), valueAsString);
|
||||
|
||||
// Store the state that won't be changed
|
||||
Column = column;
|
||||
Type columnType = column.DataType;
|
||||
try
|
||||
{
|
||||
Column = column;
|
||||
Type columnType = column.DataType;
|
||||
|
||||
// Check for null
|
||||
if (valueAsString == NullString)
|
||||
{
|
||||
ProcessNullValue();
|
||||
// Check for null
|
||||
if (valueAsString == NullString)
|
||||
{
|
||||
ProcessNullValue();
|
||||
}
|
||||
else if (columnType == typeof(byte[]))
|
||||
{
|
||||
// Binary columns need special attention
|
||||
ProcessBinaryCell(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(string))
|
||||
{
|
||||
ProcessTextCell(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(Guid))
|
||||
{
|
||||
Value = Guid.Parse(valueAsString);
|
||||
ValueAsString = Value.ToString();
|
||||
}
|
||||
else if (columnType == typeof(TimeSpan))
|
||||
{
|
||||
ProcessTimespanColumn(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(DateTimeOffset))
|
||||
{
|
||||
Value = DateTimeOffset.Parse(valueAsString, CultureInfo.CurrentCulture);
|
||||
ValueAsString = Value.ToString();
|
||||
}
|
||||
else if (columnType == typeof(bool))
|
||||
{
|
||||
ProcessBooleanCell(valueAsString);
|
||||
}
|
||||
// @TODO: Microsoft.SqlServer.Types.SqlHierarchyId
|
||||
else
|
||||
{
|
||||
// Attempt to go straight to the destination type, if we know what it is, otherwise
|
||||
// leave it as a string
|
||||
Value = columnType != null
|
||||
? Convert.ChangeType(valueAsString, columnType, CultureInfo.CurrentCulture)
|
||||
: valueAsString;
|
||||
ValueAsString = Value.ToString();
|
||||
}
|
||||
}
|
||||
else if (columnType == typeof(byte[]))
|
||||
catch (FormatException fe)
|
||||
{
|
||||
// Binary columns need special attention
|
||||
ProcessBinaryCell(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(string))
|
||||
{
|
||||
ProcessTextCell(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(Guid))
|
||||
{
|
||||
Value = Guid.Parse(valueAsString);
|
||||
ValueAsString = Value.ToString();
|
||||
}
|
||||
else if (columnType == typeof(TimeSpan))
|
||||
{
|
||||
ProcessTimespanColumn(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(DateTimeOffset))
|
||||
{
|
||||
Value = DateTimeOffset.Parse(valueAsString, CultureInfo.CurrentCulture);
|
||||
ValueAsString = Value.ToString();
|
||||
}
|
||||
else if (columnType == typeof(bool))
|
||||
{
|
||||
ProcessBooleanCell(valueAsString);
|
||||
}
|
||||
// @TODO: Microsoft.SqlServer.Types.SqlHierarchyId
|
||||
else
|
||||
{
|
||||
// Attempt to go straight to the destination type, if we know what it is, otherwise
|
||||
// leave it as a string
|
||||
Value = columnType != null
|
||||
? Convert.ChangeType(valueAsString, columnType, CultureInfo.CurrentCulture)
|
||||
: valueAsString;
|
||||
ValueAsString = Value.ToString();
|
||||
// Pretty up the exception so the user can learn a bit from it
|
||||
// NOTE: Other formatting errors raised by helpers are InvalidOperationException to
|
||||
// avoid being prettied here
|
||||
throw new FormatException(SR.EditDataInvalidFormat(column.ColumnName, ToSqlScript.FormatColumnType(column)), fe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +192,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid format
|
||||
throw new FormatException(SR.EditDataInvalidFormatBinary);
|
||||
throw new InvalidOperationException(SR.EditDataInvalidFormatBinary);
|
||||
}
|
||||
|
||||
// Generate the hex string as the return value
|
||||
@@ -205,8 +215,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
Value = false;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(valueAsString),
|
||||
SR.EditDataInvalidFormatBoolean);
|
||||
throw new InvalidOperationException(SR.EditDataInvalidFormatBoolean);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -253,7 +262,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
{
|
||||
string columnSizeString = $"({Column.ColumnSize.Value})";
|
||||
string columnTypeString = Column.DataTypeName.ToUpperInvariant() + columnSizeString;
|
||||
throw new FormatException(SR.EditDataValueTooLarge(valueAsString, columnTypeString));
|
||||
throw new InvalidOperationException(SR.EditDataValueTooLarge(valueAsString, columnTypeString));
|
||||
}
|
||||
|
||||
ValueAsString = valueAsString;
|
||||
|
||||
@@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
@@ -202,7 +202,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
// Add an out column if we're doing this for a command
|
||||
if (forCommand)
|
||||
{
|
||||
outColumns.Add($"inserted.{SqlScriptFormatter.FormatIdentifier(column.ColumnName)}");
|
||||
outColumns.Add($"inserted.{ToSqlScript.FormatIdentifier(column.ColumnName)}");
|
||||
}
|
||||
|
||||
// Skip columns that cannot be updated
|
||||
@@ -237,11 +237,11 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
else
|
||||
{
|
||||
// This script isn't for command use, add the value, formatted for insertion
|
||||
inValues.Add(SqlScriptFormatter.FormatValue(cell.Value, column));
|
||||
inValues.Add(ToSqlScript.FormatValue(cell.Value, column));
|
||||
}
|
||||
|
||||
// Add the column to the in columns
|
||||
inColumns.Add(SqlScriptFormatter.FormatIdentifier(column.ColumnName));
|
||||
inColumns.Add(ToSqlScript.FormatIdentifier(column.ColumnName));
|
||||
}
|
||||
|
||||
// Begin the script (ie, INSERT INTO blah)
|
||||
|
||||
@@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
{
|
||||
@@ -27,6 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
/// <summary>
|
||||
/// Internal parameterless constructor, required for mocking
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
protected internal RowEditBase() { }
|
||||
|
||||
/// <summary>
|
||||
@@ -204,7 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
else
|
||||
{
|
||||
// Add the clause component with the formatted value
|
||||
cellDataClause = $"= {SqlScriptFormatter.FormatValue(cellData, col.DbColumn)}";
|
||||
cellDataClause = $"= {ToSqlScript.FormatValue(cellData, col.DbColumn)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility.SqlScriptFormatters;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
@@ -81,7 +81,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
List<string> setComponents = new List<string>();
|
||||
foreach (var updateElement in cellUpdates)
|
||||
{
|
||||
string formattedColumnName = SqlScriptFormatter.FormatIdentifier(updateElement.Value.Column.ColumnName);
|
||||
string formattedColumnName = ToSqlScript.FormatIdentifier(updateElement.Value.Column.ColumnName);
|
||||
string paramName = $"@Value{RowId}_{updateElement.Key}";
|
||||
setComponents.Add($"{formattedColumnName} = {paramName}");
|
||||
SqlParameter parameter = new SqlParameter(paramName, updateElement.Value.Column.SqlDbType)
|
||||
@@ -94,7 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
|
||||
// Build the "OUTPUT" portion of the statement
|
||||
var outColumns = from c in AssociatedResultSet.Columns
|
||||
let formatted = SqlScriptFormatter.FormatIdentifier(c.ColumnName)
|
||||
let formatted = ToSqlScript.FormatIdentifier(c.ColumnName)
|
||||
select $"inserted.{formatted}";
|
||||
string outColumnsJoined = string.Join(", ", outColumns);
|
||||
|
||||
@@ -148,8 +148,8 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
// Build the "SET" portion of the statement
|
||||
var setComponents = cellUpdates.Values.Select(cellUpdate =>
|
||||
{
|
||||
string formattedColumnName = SqlScriptFormatter.FormatIdentifier(cellUpdate.Column.ColumnName);
|
||||
string formattedValue = SqlScriptFormatter.FormatValue(cellUpdate.Value, cellUpdate.Column);
|
||||
string formattedColumnName = ToSqlScript.FormatIdentifier(cellUpdate.Column.ColumnName);
|
||||
string formattedValue = ToSqlScript.FormatValue(cellUpdate.Value, cellUpdate.Column);
|
||||
return $"{formattedColumnName} = {formattedValue}";
|
||||
});
|
||||
string setClause = string.Join(", ", setComponents);
|
||||
|
||||
Reference in New Issue
Block a user