Edit Data: Better errors for possible truncation (#514)

* Fix to make sql exceptions surface properly to user (with important notes!)

* Adding support for detecting column size issues when updating a cell

* Adding unit tests for the exception on read scenario
This commit is contained in:
Benjamin Russell
2017-10-21 11:08:40 -07:00
committed by Karl Burtram
parent 9499d73cec
commit e9bc97e290
37 changed files with 445 additions and 343 deletions

View File

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.Credentials
Keys.Culture = value;
}
}
public static string CredentialsServiceInvalidCriticalHandle
{
@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.Credentials
{
return Keys.GetString(Keys.CredentialsServiceInvalidCriticalHandle);
}
}
}
public static string CredentialsServicePasswordLengthExceeded
{
@@ -43,7 +43,7 @@ namespace Microsoft.SqlTools.Credentials
{
return Keys.GetString(Keys.CredentialsServicePasswordLengthExceeded);
}
}
}
public static string CredentialsServiceTargetForDelete
{
@@ -51,7 +51,7 @@ namespace Microsoft.SqlTools.Credentials
{
return Keys.GetString(Keys.CredentialsServiceTargetForDelete);
}
}
}
public static string CredentialsServiceTargetForLookup
{
@@ -59,7 +59,7 @@ namespace Microsoft.SqlTools.Credentials
{
return Keys.GetString(Keys.CredentialsServiceTargetForLookup);
}
}
}
public static string CredentialServiceWin32CredentialDisposed
{
@@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.Credentials
{
return Keys.GetString(Keys.CredentialServiceWin32CredentialDisposed);
}
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
@@ -75,22 +75,22 @@ namespace Microsoft.SqlTools.Credentials
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.Credentials.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public const string CredentialsServiceInvalidCriticalHandle = "CredentialsServiceInvalidCriticalHandle";
public const string CredentialsServicePasswordLengthExceeded = "CredentialsServicePasswordLengthExceeded";
public const string CredentialsServiceTargetForDelete = "CredentialsServiceTargetForDelete";
public const string CredentialsServiceTargetForLookup = "CredentialsServiceTargetForLookup";
public const string CredentialServiceWin32CredentialDisposed = "CredentialServiceWin32CredentialDisposed";
public const string CredentialsServiceInvalidCriticalHandle = "CredentialsServiceInvalidCriticalHandle";
public const string CredentialsServicePasswordLengthExceeded = "CredentialsServicePasswordLengthExceeded";
public const string CredentialsServiceTargetForDelete = "CredentialsServiceTargetForDelete";
public const string CredentialsServiceTargetForLookup = "CredentialsServiceTargetForLookup";
public const string CredentialServiceWin32CredentialDisposed = "CredentialServiceWin32CredentialDisposed";
private Keys()
{ }
@@ -111,7 +111,7 @@ namespace Microsoft.SqlTools.Credentials
{
return resourceManager.GetString(key, _culture);
}
}
}
}
}
}
}

View File

@@ -120,21 +120,21 @@
<data name="CredentialsServiceInvalidCriticalHandle" xml:space="preserve">
<value>Invalid CriticalHandle!</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServicePasswordLengthExceeded" xml:space="preserve">
<value>The password has exceeded 512 bytes</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServiceTargetForDelete" xml:space="preserve">
<value>Target must be specified to delete a credential</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServiceTargetForLookup" xml:space="preserve">
<value>Target must be specified to check existance of a credential</value>
<comment></comment>
</data>
</data>
<data name="CredentialServiceWin32CredentialDisposed" xml:space="preserve">
<value>Win32Credential object is already disposed</value>
<comment></comment>
</data>
</root>
</data>
</root>

View File

@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en">
<body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target>
<note></note>
</trans-unit>
</body>
</file>
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en">
<body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.Hosting
Keys.Culture = value;
}
}
public static string CredentialsServiceInvalidCriticalHandle
{
@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.CredentialsServiceInvalidCriticalHandle);
}
}
}
public static string CredentialsServicePasswordLengthExceeded
{
@@ -43,7 +43,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.CredentialsServicePasswordLengthExceeded);
}
}
}
public static string CredentialsServiceTargetForDelete
{
@@ -51,7 +51,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.CredentialsServiceTargetForDelete);
}
}
}
public static string CredentialsServiceTargetForLookup
{
@@ -59,7 +59,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.CredentialsServiceTargetForLookup);
}
}
}
public static string CredentialServiceWin32CredentialDisposed
{
@@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.CredentialServiceWin32CredentialDisposed);
}
}
}
public static string ServiceAlreadyRegistered
{
@@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.ServiceAlreadyRegistered);
}
}
}
public static string MultipleServicesFound
{
@@ -83,7 +83,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.MultipleServicesFound);
}
}
}
public static string IncompatibleServiceForExtensionLoader
{
@@ -91,7 +91,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.IncompatibleServiceForExtensionLoader);
}
}
}
public static string ServiceProviderNotSet
{
@@ -99,7 +99,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.ServiceProviderNotSet);
}
}
}
public static string ServiceNotFound
{
@@ -107,7 +107,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.ServiceNotFound);
}
}
}
public static string ServiceNotOfExpectedType
{
@@ -115,7 +115,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.ServiceNotOfExpectedType);
}
}
}
public static string HostingUnexpectedEndOfStream
{
@@ -123,7 +123,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.HostingUnexpectedEndOfStream);
}
}
}
public static string HostingHeaderMissingColon
{
@@ -131,7 +131,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.HostingHeaderMissingColon);
}
}
}
public static string HostingHeaderMissingContentLengthHeader
{
@@ -139,7 +139,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.HostingHeaderMissingContentLengthHeader);
}
}
}
public static string HostingHeaderMissingContentLengthValue
{
@@ -147,7 +147,7 @@ namespace Microsoft.SqlTools.Hosting
{
return Keys.GetString(Keys.HostingHeaderMissingContentLengthValue);
}
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
@@ -155,52 +155,52 @@ namespace Microsoft.SqlTools.Hosting
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.Hosting.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public const string CredentialsServiceInvalidCriticalHandle = "CredentialsServiceInvalidCriticalHandle";
public const string CredentialsServicePasswordLengthExceeded = "CredentialsServicePasswordLengthExceeded";
public const string CredentialsServiceTargetForDelete = "CredentialsServiceTargetForDelete";
public const string CredentialsServiceTargetForLookup = "CredentialsServiceTargetForLookup";
public const string CredentialServiceWin32CredentialDisposed = "CredentialServiceWin32CredentialDisposed";
public const string ServiceAlreadyRegistered = "ServiceAlreadyRegistered";
public const string MultipleServicesFound = "MultipleServicesFound";
public const string IncompatibleServiceForExtensionLoader = "IncompatibleServiceForExtensionLoader";
public const string ServiceProviderNotSet = "ServiceProviderNotSet";
public const string ServiceNotFound = "ServiceNotFound";
public const string ServiceNotOfExpectedType = "ServiceNotOfExpectedType";
public const string HostingUnexpectedEndOfStream = "HostingUnexpectedEndOfStream";
public const string HostingHeaderMissingColon = "HostingHeaderMissingColon";
public const string HostingHeaderMissingContentLengthHeader = "HostingHeaderMissingContentLengthHeader";
public const string HostingHeaderMissingContentLengthValue = "HostingHeaderMissingContentLengthValue";
public const string CredentialsServiceInvalidCriticalHandle = "CredentialsServiceInvalidCriticalHandle";
public const string CredentialsServicePasswordLengthExceeded = "CredentialsServicePasswordLengthExceeded";
public const string CredentialsServiceTargetForDelete = "CredentialsServiceTargetForDelete";
public const string CredentialsServiceTargetForLookup = "CredentialsServiceTargetForLookup";
public const string CredentialServiceWin32CredentialDisposed = "CredentialServiceWin32CredentialDisposed";
public const string ServiceAlreadyRegistered = "ServiceAlreadyRegistered";
public const string MultipleServicesFound = "MultipleServicesFound";
public const string IncompatibleServiceForExtensionLoader = "IncompatibleServiceForExtensionLoader";
public const string ServiceProviderNotSet = "ServiceProviderNotSet";
public const string ServiceNotFound = "ServiceNotFound";
public const string ServiceNotOfExpectedType = "ServiceNotOfExpectedType";
public const string HostingUnexpectedEndOfStream = "HostingUnexpectedEndOfStream";
public const string HostingHeaderMissingColon = "HostingHeaderMissingColon";
public const string HostingHeaderMissingContentLengthHeader = "HostingHeaderMissingContentLengthHeader";
public const string HostingHeaderMissingContentLengthValue = "HostingHeaderMissingContentLengthValue";
private Keys()
{ }
@@ -221,7 +221,7 @@ namespace Microsoft.SqlTools.Hosting
{
return resourceManager.GetString(key, _culture);
}
}
}
}
}
}
}

View File

@@ -120,61 +120,61 @@
<data name="CredentialsServiceInvalidCriticalHandle" xml:space="preserve">
<value>Invalid CriticalHandle!</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServicePasswordLengthExceeded" xml:space="preserve">
<value>The password has exceeded 512 bytes</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServiceTargetForDelete" xml:space="preserve">
<value>Target must be specified to delete a credential</value>
<comment></comment>
</data>
</data>
<data name="CredentialsServiceTargetForLookup" xml:space="preserve">
<value>Target must be specified to check existance of a credential</value>
<comment></comment>
</data>
</data>
<data name="CredentialServiceWin32CredentialDisposed" xml:space="preserve">
<value>Win32Credential object is already disposed</value>
<comment></comment>
</data>
</data>
<data name="ServiceAlreadyRegistered" xml:space="preserve">
<value>Cannot register service for type {0}, one or more services already registered</value>
<comment></comment>
</data>
</data>
<data name="MultipleServicesFound" xml:space="preserve">
<value>Multiple services found for type {0}, expected only 1</value>
<comment></comment>
</data>
</data>
<data name="IncompatibleServiceForExtensionLoader" xml:space="preserve">
<value>Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</value>
<comment></comment>
</data>
</data>
<data name="ServiceProviderNotSet" xml:space="preserve">
<value>SetServiceProvider() was not called to establish the required service provider</value>
<comment></comment>
</data>
</data>
<data name="ServiceNotFound" xml:space="preserve">
<value>Service {0} was not found in the service provider</value>
<comment></comment>
</data>
</data>
<data name="ServiceNotOfExpectedType" xml:space="preserve">
<value>Service of Type {0} is not compatible with registered Type {1}</value>
<comment></comment>
</data>
</data>
<data name="HostingUnexpectedEndOfStream" xml:space="preserve">
<value>MessageReader's input stream ended unexpectedly, terminating</value>
<comment></comment>
</data>
</data>
<data name="HostingHeaderMissingColon" xml:space="preserve">
<value>Message header must separate key and value using ':'</value>
<comment></comment>
</data>
</data>
<data name="HostingHeaderMissingContentLengthHeader" xml:space="preserve">
<value>Fatal error: Content-Length header must be provided</value>
<comment></comment>
</data>
</data>
<data name="HostingHeaderMissingContentLengthValue" xml:space="preserve">
<value>Fatal error: Content-Length value is not an integer</value>
<comment></comment>
</data>
</root>
</data>
</root>

View File

@@ -1,82 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en">
<body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target>
<note></note>
</trans-unit>
<trans-unit id="HostingUnexpectedEndOfStream">
<source>MessageReader's input stream ended unexpectedly, terminating</source>
<target state="new">MessageReader's input stream ended unexpectedly, terminating</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingColon">
<source>Message header must separate key and value using ':'</source>
<target state="new">Message header must separate key and value using ':'</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthHeader">
<source>Fatal error: Content-Length header must be provided</source>
<target state="new">Fatal error: Content-Length header must be provided</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthValue">
<source>Fatal error: Content-Length value is not an integer</source>
<target state="new">Fatal error: Content-Length value is not an integer</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceAlreadyRegistered">
<source>Cannot register service for type {0}, one or more services already registered</source>
<target state="new">Cannot register service for type {0}, one or more services already registered</target>
<note></note>
</trans-unit>
<trans-unit id="MultipleServicesFound">
<source>Multiple services found for type {0}, expected only 1</source>
<target state="new">Multiple services found for type {0}, expected only 1</target>
<note></note>
</trans-unit>
<trans-unit id="IncompatibleServiceForExtensionLoader">
<source>Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</source>
<target state="new">Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceProviderNotSet">
<source>SetServiceProvider() was not called to establish the required service provider</source>
<target state="new">SetServiceProvider() was not called to establish the required service provider</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceNotFound">
<source>Service {0} was not found in the service provider</source>
<target state="new">Service {0} was not found in the service provider</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceNotOfExpectedType">
<source>Service of Type {0} is not compatible with registered Type {1}</source>
<target state="new">Service of Type {0} is not compatible with registered Type {1}</target>
<note></note>
</trans-unit>
</body>
</file>
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" original="sr.resx" source-language="en">
<body>
<trans-unit id="CredentialsServiceInvalidCriticalHandle">
<source>Invalid CriticalHandle!</source>
<target state="new">Invalid CriticalHandle!</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServicePasswordLengthExceeded">
<source>The password has exceeded 512 bytes</source>
<target state="new">The password has exceeded 512 bytes</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForDelete">
<source>Target must be specified to delete a credential</source>
<target state="new">Target must be specified to delete a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialsServiceTargetForLookup">
<source>Target must be specified to check existance of a credential</source>
<target state="new">Target must be specified to check existance of a credential</target>
<note></note>
</trans-unit>
<trans-unit id="CredentialServiceWin32CredentialDisposed">
<source>Win32Credential object is already disposed</source>
<target state="new">Win32Credential object is already disposed</target>
<note></note>
</trans-unit>
<trans-unit id="HostingUnexpectedEndOfStream">
<source>MessageReader's input stream ended unexpectedly, terminating</source>
<target state="new">MessageReader's input stream ended unexpectedly, terminating</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingColon">
<source>Message header must separate key and value using ':'</source>
<target state="new">Message header must separate key and value using ':'</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthHeader">
<source>Fatal error: Content-Length header must be provided</source>
<target state="new">Fatal error: Content-Length header must be provided</target>
<note></note>
</trans-unit>
<trans-unit id="HostingHeaderMissingContentLengthValue">
<source>Fatal error: Content-Length value is not an integer</source>
<target state="new">Fatal error: Content-Length value is not an integer</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceAlreadyRegistered">
<source>Cannot register service for type {0}, one or more services already registered</source>
<target state="new">Cannot register service for type {0}, one or more services already registered</target>
<note></note>
</trans-unit>
<trans-unit id="MultipleServicesFound">
<source>Multiple services found for type {0}, expected only 1</source>
<target state="new">Multiple services found for type {0}, expected only 1</target>
<note></note>
</trans-unit>
<trans-unit id="IncompatibleServiceForExtensionLoader">
<source>Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</source>
<target state="new">Service of type {0} cannot be created by ExtensionLoader&lt;{1}&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceProviderNotSet">
<source>SetServiceProvider() was not called to establish the required service provider</source>
<target state="new">SetServiceProvider() was not called to establish the required service provider</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceNotFound">
<source>Service {0} was not found in the service provider</source>
<target state="new">Service {0} was not found in the service provider</target>
<note></note>
</trans-unit>
<trans-unit id="ServiceNotOfExpectedType">
<source>Service of Type {0} is not compatible with registered Type {1}</source>
<target state="new">Service of Type {0} is not compatible with registered Type {1}</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

View File

View File

@@ -49,10 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
}
else if (columnType == typeof(string))
{
// Special case for strings because the string value should stay the same as provided
// If user typed 'NULL' they mean NULL as text
Value = valueAsString == TextNullString ? NullString : valueAsString;
ValueAsString = valueAsString;
ProcessTextCell(valueAsString);
}
else if (columnType == typeof(Guid))
{
@@ -245,6 +242,23 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
ValueAsString = NullString;
}
private void ProcessTextCell(string valueAsString)
{
// Special case for strings because the string value should stay the same as provided
// If user typed 'NULL' they mean NULL as text
Value = valueAsString == TextNullString ? NullString : valueAsString;
// Make sure that the value fits inside the size of the column
if (Column.ColumnSize.HasValue && valueAsString.Length > Column.ColumnSize)
{
string columnSizeString = $"({Column.ColumnSize.Value})";
string columnTypeString = Column.DataTypeName.ToUpperInvariant() + columnSizeString;
throw new FormatException(SR.EditDataValueTooLarge(valueAsString, columnTypeString));
}
ValueAsString = valueAsString;
}
#endregion
}
}

View File

@@ -3651,6 +3651,11 @@ namespace Microsoft.SqlTools.ServiceLayer
return Keys.GetString(Keys.EditDataUnsupportedObjectType, typeName);
}
public static string EditDataValueTooLarge(string value, string columnType)
{
return Keys.GetString(Keys.EditDataValueTooLarge, value, columnType);
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
{
@@ -3932,6 +3937,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string EditDataNullNotAllowed = "EditDataNullNotAllowed";
public const string EditDataValueTooLarge = "EditDataValueTooLarge";
public const string EE_BatchSqlMessageNoProcedureInfo = "EE_BatchSqlMessageNoProcedureInfo";

View File

@@ -495,6 +495,11 @@
<value>NULL is not allowed for this column</value>
<comment></comment>
</data>
<data name="EditDataValueTooLarge" xml:space="preserve">
<value>Value {0} is too large to fit in column of type {1}</value>
<comment>.
Parameters: 0 - value (string), 1 - columnType (string) </comment>
</data>
<data name="EE_BatchSqlMessageNoProcedureInfo" xml:space="preserve">
<value>Msg {0}, Level {1}, State {2}, Line {3}</value>
<comment></comment>

View File

@@ -232,6 +232,8 @@ EditDataTimeOver24Hrs = TIME column values must be between 00:00:00.0000000 and
EditDataNullNotAllowed = NULL is not allowed for this column
EditDataValueTooLarge(string value, string columnType) = Value {0} is too large to fit in column of type {1}
############################################################################
# DacFx Resources

View File

@@ -2305,6 +2305,12 @@
<target state="new">For directory {0} a file with name {1} already exists</target>
<note></note>
</trans-unit>
<trans-unit id="EditDataValueTooLarge">
<source>Value {0} is too large to fit in column of type {1}</source>
<target state="new">Value {0} is too large to fit in column of type {1}</target>
<note>.
Parameters: 0 - value (string), 1 - columnType (string) </note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -616,19 +616,23 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
{
throw new InvalidOperationException(SR.QueryServiceResultSetNotRead);
}
if (!dbDataReader.HasRows)
// NOTE: We are no longer checking to see if the data reader has rows before reading
// b/c of a quirk in SqlClient. In some scenarios, a SqlException isn't thrown until we
// read. In order to get appropriate errors back to the user, we'll read first.
// 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);
if (!await dataReader.ReadAsync(CancellationToken.None))
{
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
}
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
using (IFileStreamWriter writer = fileStreamFactory.GetWriter(outputFileName))
{
// Write the row to the end of the file
long currentFileOffset = totalBytesWritten;
writer.Seek(currentFileOffset);
await dataReader.ReadAsync(CancellationToken.None);
totalBytesWritten += writer.WriteRow(dataReader);
return currentFileOffset;
}