Edit Data: Create Row with Nullable Columns (#553)

* WIP

* All the new RowCreate tests are working

* Fixing a couple bugs with the row delete and row update tests

* Regenerating localization files

* Fixing multiple iteration in tests
This commit is contained in:
Benjamin Russell
2017-11-28 14:59:48 -08:00
committed by GitHub
parent bc8aef6a15
commit 2190039df2
33 changed files with 17699 additions and 7445 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

@@ -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

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
Keys.Culture = value;
}
}
public static string NoSubscriptionsFound
{
@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.NoSubscriptionsFound);
}
}
}
public static string AzureServerNotFound
{
@@ -43,7 +43,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.AzureServerNotFound);
}
}
}
public static string AzureSubscriptionFailedErrorMessage
{
@@ -51,7 +51,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.AzureSubscriptionFailedErrorMessage);
}
}
}
public static string DatabaseDiscoveryFailedErrorMessage
{
@@ -59,7 +59,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.DatabaseDiscoveryFailedErrorMessage);
}
}
}
public static string FirewallRuleAccessForbidden
{
@@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.FirewallRuleAccessForbidden);
}
}
}
public static string FirewallRuleCreationFailed
{
@@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.FirewallRuleCreationFailed);
}
}
}
public static string FirewallRuleCreationFailedWithError
{
@@ -83,7 +83,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.FirewallRuleCreationFailedWithError);
}
}
}
public static string InvalidIpAddress
{
@@ -91,7 +91,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.InvalidIpAddress);
}
}
}
public static string InvalidServerTypeErrorMessage
{
@@ -99,7 +99,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.InvalidServerTypeErrorMessage);
}
}
}
public static string LoadingExportableFailedGeneralErrorMessage
{
@@ -107,7 +107,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.LoadingExportableFailedGeneralErrorMessage);
}
}
}
public static string FirewallRuleUnsupportedConnectionType
{
@@ -115,7 +115,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return Keys.GetString(Keys.FirewallRuleUnsupportedConnectionType);
}
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
@@ -123,40 +123,40 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ResourceProvider.Core.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public const string NoSubscriptionsFound = "NoSubscriptionsFound";
public const string AzureServerNotFound = "AzureServerNotFound";
public const string AzureSubscriptionFailedErrorMessage = "AzureSubscriptionFailedErrorMessage";
public const string DatabaseDiscoveryFailedErrorMessage = "DatabaseDiscoveryFailedErrorMessage";
public const string FirewallRuleAccessForbidden = "FirewallRuleAccessForbidden";
public const string FirewallRuleCreationFailed = "FirewallRuleCreationFailed";
public const string FirewallRuleCreationFailedWithError = "FirewallRuleCreationFailedWithError";
public const string InvalidIpAddress = "InvalidIpAddress";
public const string InvalidServerTypeErrorMessage = "InvalidServerTypeErrorMessage";
public const string LoadingExportableFailedGeneralErrorMessage = "LoadingExportableFailedGeneralErrorMessage";
public const string FirewallRuleUnsupportedConnectionType = "FirewallRuleUnsupportedConnectionType";
public const string NoSubscriptionsFound = "NoSubscriptionsFound";
public const string AzureServerNotFound = "AzureServerNotFound";
public const string AzureSubscriptionFailedErrorMessage = "AzureSubscriptionFailedErrorMessage";
public const string DatabaseDiscoveryFailedErrorMessage = "DatabaseDiscoveryFailedErrorMessage";
public const string FirewallRuleAccessForbidden = "FirewallRuleAccessForbidden";
public const string FirewallRuleCreationFailed = "FirewallRuleCreationFailed";
public const string FirewallRuleCreationFailedWithError = "FirewallRuleCreationFailedWithError";
public const string InvalidIpAddress = "InvalidIpAddress";
public const string InvalidServerTypeErrorMessage = "InvalidServerTypeErrorMessage";
public const string LoadingExportableFailedGeneralErrorMessage = "LoadingExportableFailedGeneralErrorMessage";
public const string FirewallRuleUnsupportedConnectionType = "FirewallRuleUnsupportedConnectionType";
private Keys()
{ }
@@ -177,7 +177,7 @@ namespace Microsoft.SqlTools.ResourceProvider.Core
{
return resourceManager.GetString(key, _culture);
}
}
}
}
}
}
}

View File

@@ -120,45 +120,45 @@
<data name="NoSubscriptionsFound" xml:space="preserve">
<value>No subscriptions were found for the currently logged in user account.</value>
<comment></comment>
</data>
</data>
<data name="AzureServerNotFound" xml:space="preserve">
<value>The server you specified {0} does not exist in any subscription in {1}. Either you have signed in with an incorrect account or your server was removed from subscription(s) in this account. Please check your account and try again.</value>
<comment></comment>
</data>
</data>
<data name="AzureSubscriptionFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure subscriptions: {0}</value>
<comment></comment>
</data>
</data>
<data name="DatabaseDiscoveryFailedErrorMessage" xml:space="preserve">
<value>An error occurred while getting databases from servers of type {0} from {1}</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleAccessForbidden" xml:space="preserve">
<value>{0} does not have permission to change the server firewall rule. Try again with a different account that is an Owner or Contributor of the Azure subscription or the server.</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleCreationFailed" xml:space="preserve">
<value>An error occurred while creating a new firewall rule.</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleCreationFailedWithError" xml:space="preserve">
<value>An error occurred while creating a new firewall rule: '{0}'</value>
<comment></comment>
</data>
</data>
<data name="InvalidIpAddress" xml:space="preserve">
<value>Invalid IP address</value>
<comment></comment>
</data>
</data>
<data name="InvalidServerTypeErrorMessage" xml:space="preserve">
<value>Server Type is invalid.</value>
<comment></comment>
</data>
</data>
<data name="LoadingExportableFailedGeneralErrorMessage" xml:space="preserve">
<value>A required dll cannot be loaded. Please repair your application.</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleUnsupportedConnectionType" xml:space="preserve">
<value>Cannot open a firewall rule for the specified connection type</value>
<comment></comment>
</data>
</root>
</data>
</root>

View File

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
Keys.Culture = value;
}
}
public static string FailedToGetAzureDatabasesErrorMessage
{
@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FailedToGetAzureDatabasesErrorMessage);
}
}
}
public static string FailedToGetAzureSubscriptionsErrorMessage
{
@@ -43,7 +43,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FailedToGetAzureSubscriptionsErrorMessage);
}
}
}
public static string FailedToGetAzureResourceGroupsErrorMessage
{
@@ -51,7 +51,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FailedToGetAzureResourceGroupsErrorMessage);
}
}
}
public static string FailedToGetAzureSqlServersErrorMessage
{
@@ -59,7 +59,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FailedToGetAzureSqlServersErrorMessage);
}
}
}
public static string FailedToGetAzureSqlServersWithError
{
@@ -67,7 +67,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FailedToGetAzureSqlServersWithError);
}
}
}
public static string FirewallRuleCreationFailed
{
@@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FirewallRuleCreationFailed);
}
}
}
public static string FirewallRuleCreationFailedWithError
{
@@ -83,7 +83,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.FirewallRuleCreationFailedWithError);
}
}
}
public static string UnsupportedAuthType
{
@@ -91,7 +91,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.UnsupportedAuthType);
}
}
}
public static string UserNotFoundError
{
@@ -99,7 +99,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.UserNotFoundError);
}
}
}
public static string UserNeedsAuthenticationError
{
@@ -107,7 +107,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return Keys.GetString(Keys.UserNeedsAuthenticationError);
}
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
@@ -115,37 +115,37 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ResourceProvider.DefaultImpl.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
public const string FailedToGetAzureDatabasesErrorMessage = "FailedToGetAzureDatabasesErrorMessage";
public const string FailedToGetAzureSubscriptionsErrorMessage = "FailedToGetAzureSubscriptionsErrorMessage";
public const string FailedToGetAzureResourceGroupsErrorMessage = "FailedToGetAzureResourceGroupsErrorMessage";
public const string FailedToGetAzureSqlServersErrorMessage = "FailedToGetAzureSqlServersErrorMessage";
public const string FailedToGetAzureSqlServersWithError = "FailedToGetAzureSqlServersWithError";
public const string FirewallRuleCreationFailed = "FirewallRuleCreationFailed";
public const string FirewallRuleCreationFailedWithError = "FirewallRuleCreationFailedWithError";
public const string UnsupportedAuthType = "UnsupportedAuthType";
public const string UserNotFoundError = "UserNotFoundError";
public const string UserNeedsAuthenticationError = "UserNeedsAuthenticationError";
public const string FailedToGetAzureDatabasesErrorMessage = "FailedToGetAzureDatabasesErrorMessage";
public const string FailedToGetAzureSubscriptionsErrorMessage = "FailedToGetAzureSubscriptionsErrorMessage";
public const string FailedToGetAzureResourceGroupsErrorMessage = "FailedToGetAzureResourceGroupsErrorMessage";
public const string FailedToGetAzureSqlServersErrorMessage = "FailedToGetAzureSqlServersErrorMessage";
public const string FailedToGetAzureSqlServersWithError = "FailedToGetAzureSqlServersWithError";
public const string FirewallRuleCreationFailed = "FirewallRuleCreationFailed";
public const string FirewallRuleCreationFailedWithError = "FirewallRuleCreationFailedWithError";
public const string UnsupportedAuthType = "UnsupportedAuthType";
public const string UserNotFoundError = "UserNotFoundError";
public const string UserNeedsAuthenticationError = "UserNeedsAuthenticationError";
private Keys()
{ }
@@ -166,7 +166,7 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
return resourceManager.GetString(key, _culture);
}
}
}
}
}
}
}

View File

@@ -120,41 +120,41 @@
<data name="FailedToGetAzureDatabasesErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure databases</value>
<comment></comment>
</data>
</data>
<data name="FailedToGetAzureSubscriptionsErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure subscriptions: {0}</value>
<comment></comment>
</data>
</data>
<data name="FailedToGetAzureResourceGroupsErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure resource groups: {0}</value>
<comment></comment>
</data>
</data>
<data name="FailedToGetAzureSqlServersErrorMessage" xml:space="preserve">
<value>An error occurred while getting Azure Sql Servers</value>
<comment></comment>
</data>
</data>
<data name="FailedToGetAzureSqlServersWithError" xml:space="preserve">
<value>An error occurred while getting Azure Sql Servers: '{0}'</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleCreationFailed" xml:space="preserve">
<value>An error occurred while creating a new firewall rule.</value>
<comment></comment>
</data>
</data>
<data name="FirewallRuleCreationFailedWithError" xml:space="preserve">
<value>An error occurred while creating a new firewall rule: '{0}'</value>
<comment></comment>
</data>
</data>
<data name="UnsupportedAuthType" xml:space="preserve">
<value>Unsupported account type '{0}' for this provider</value>
<comment></comment>
</data>
</data>
<data name="UserNotFoundError" xml:space="preserve">
<value>No user was found, cannot execute the operation</value>
<comment></comment>
</data>
</data>
<data name="UserNeedsAuthenticationError" xml:space="preserve">
<value>The current user must be reauthenticated before executing this operation </value>
<comment></comment>
</data>
</root>
</data>
</root>

View File

@@ -27,7 +27,7 @@ namespace Microsoft.SqlTools.ResourceProvider
Keys.Culture = value;
}
}
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Keys
@@ -35,7 +35,7 @@ namespace Microsoft.SqlTools.ResourceProvider
static ResourceManager resourceManager = new ResourceManager("Microsoft.SqlTools.ResourceProvider.Localization.SR", typeof(SR).GetTypeInfo().Assembly);
static CultureInfo _culture = null;
private Keys()
{ }
@@ -56,7 +56,7 @@ namespace Microsoft.SqlTools.ResourceProvider
{
return resourceManager.GetString(key, _culture);
}
}
}
}
}
}
}

View File

@@ -117,4 +117,4 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
</root>

View File

@@ -214,13 +214,13 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
// Make sure a value was provided for the cell
if (cell == null)
{
// If there isn't a default, then fail
if (DefaultValues[i] == null)
// If the column is not nullable and there is no default defined, then fail
if (!column.AllowDBNull.HasTrue() && DefaultValues[i] == null)
{
throw new InvalidOperationException(SR.EditDataCreateScriptMissingValue);
throw new InvalidOperationException(SR.EditDataCreateScriptMissingValue(column.ColumnName));
}
// There is a default value, so trust the db will apply it
// There is a default value (or omitting the value is fine), so trust the db will apply it correctly
continue;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -212,7 +212,7 @@ EditDataInvalidFormatBinary = Invalid format for binary column
EditDataInvalidFormatBoolean = Allowed values for boolean columns are 0, 1, "true", or "false"
EditDataCreateScriptMissingValue = A required cell value is missing
EditDataCreateScriptMissingValue(string colName) = The column '{0}' is defined as NOT NULL but was not given a value
EditDataDeleteSetCell = A delete is pending for this row, a cell update cannot be applied.

View File

@@ -475,9 +475,10 @@
<note></note>
</trans-unit>
<trans-unit id="EditDataCreateScriptMissingValue">
<source>A required cell value is missing</source>
<source>The column '{0}' is defined as NOT NULL but was not given a value</source>
<target state="new">A required cell value is missing</target>
<note></note>
<note>.
Parameters: 0 - colName (string) </note>
</trans-unit>
<trans-unit id="EditDataDeleteSetCell">
<source>A delete is pending for this row, a cell update cannot be applied.</source>

View File

@@ -8,7 +8,6 @@ using System.Data.Common;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
@@ -50,7 +49,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
EditSession session = new EditSession(metaFactory.Object);
// Step 2) Initialize the Session
// Mock connector that does nothing
EditSession.Connector connector = () => Task.FromResult<DbConnection>(null);
@@ -65,46 +63,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
return session;
}
public static EditTableMetadata GetStandardMetadata(DbColumn[] columns, bool isMemoryOptimized = false, int defaultColumns = 0)
{
// Create column metadata providers
var columnMetas = columns.Select((c, i) => new EditColumnMetadata
{
EscapedName = c.ColumnName,
Ordinal = i,
DefaultValue = i < defaultColumns ? DefaultValue : null
}).ToArray();
// Create column wrappers
var columnWrappers = columns.Select(c => new DbColumnWrapper(c)).ToArray();
// Create the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetas,
EscapedMultipartName = TableName,
IsMemoryOptimized = isMemoryOptimized
};
editTableMetadata.Extend(columnWrappers);
return editTableMetadata;
}
public static DbColumn[] GetColumns(bool includeIdentity)
{
List<DbColumn> columns = new List<DbColumn>();
if (includeIdentity)
{
columns.Add(new TestDbColumn("id") {IsKey = true, IsIdentity = true, IsAutoIncrement = true});
}
for (int i = 0; i < 3; i++)
{
columns.Add(new TestDbColumn($"col{i}"));
}
return columns.ToArray();
}
public static async Task<Query> GetQuery(DbColumn[] columns, bool includIdentity, int rowCount = 1)
{
Query q = QueryExecution.Common.GetBasicExecutedQuery();
@@ -133,6 +91,32 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
return new TestDbDataReader(new [] {testResultSet}, false);
}
public static EditTableMetadata GetCustomEditTableMetadata(DbColumn[] columns)
{
// Create column metadata providers and column wrappers
var columnMetas = new List<EditColumnMetadata>();
var columnWrappers = new List<DbColumnWrapper>();
for (int i = 0; i < columns.Length; i++)
{
columnMetas.Add(new EditColumnMetadata
{
EscapedName = columns[i].ColumnName,
Ordinal = i
});
columnWrappers.Add(new DbColumnWrapper(columns[i]));
}
// Create the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetas.ToArray(),
EscapedMultipartName = TableName,
IsMemoryOptimized = false
};
editTableMetadata.Extend(columnWrappers.ToArray());
return editTableMetadata;
}
public static void AddCells(RowEditBase rc, int colsToSkip)
{
// Skip the first column since if identity, since identity columns can't be updated
@@ -141,5 +125,101 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
rc.SetCell(i, "123");
}
}
public class TestDbColumnsWithTableMetadata
{
public TestDbColumnsWithTableMetadata(bool isMemoryOptimized, bool identityCol, int defaultCols, int nullableCols)
{
List<DbColumn> dbColumns = new List<DbColumn>();
List<DbColumnWrapper> columnWrappers = new List<DbColumnWrapper>();
List<EditColumnMetadata> columnMetadatas = new List<EditColumnMetadata>();
int startingOrdinal = 0;
// Add the identity column at the front of the table
if (identityCol)
{
const string colName = "id";
DbColumn dbColumn = new TestDbColumn(colName)
{
IsKey = true,
IsIdentity = true,
IsAutoIncrement = true
};
EditColumnMetadata columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = startingOrdinal,
DefaultValue = null
};
dbColumns.Add(dbColumn);
columnWrappers.Add(new DbColumnWrapper(dbColumn));
columnMetadatas.Add(columnMetadata);
startingOrdinal++;
}
// Add each column to the table
for (int i = startingOrdinal; i < 3 + startingOrdinal; i++)
{
string colName = $"col{i}";
DbColumn dbColumn;
EditColumnMetadata columnMetadata;
if (i < defaultCols + startingOrdinal)
{
// This column will have a default value
dbColumn = new TestDbColumn(colName) {AllowDBNull = false};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = DefaultValue
};
}
else if (i < nullableCols + defaultCols + startingOrdinal)
{
// This column will be nullable
dbColumn = new TestDbColumn(colName) {AllowDBNull = true};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = null
};
}
else
{
// This column doesn't have a default value or is nullable
dbColumn = new TestDbColumn(colName) {AllowDBNull = false};
columnMetadata = new EditColumnMetadata
{
EscapedName = colName,
Ordinal = i,
DefaultValue = null
};
}
dbColumns.Add(dbColumn);
columnWrappers.Add(new DbColumnWrapper(dbColumn));
columnMetadatas.Add(columnMetadata);
}
// Put together the table metadata
EditTableMetadata editTableMetadata = new EditTableMetadata
{
Columns = columnMetadatas.ToArray(),
EscapedMultipartName = TableName,
IsMemoryOptimized = isMemoryOptimized
};
editTableMetadata.Extend(columnWrappers.ToArray());
DbColumns = dbColumns.ToArray();
TableMetadata = editTableMetadata;
}
public DbColumn[] DbColumns { get; }
public EditTableMetadata TableMetadata { get; }
}
}
}

View File

@@ -10,7 +10,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -27,26 +26,46 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Create the values to store
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
// If: I create a RowCreate instance
RowCreate rc = new RowCreate(rowId, rs, etm);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(rowId, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
#region GetScript Tests
[Fact]
public async Task GetScriptMissingCell()
public static IEnumerable<object[]> GetScriptMissingCellsData
{
get
{
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 2}; // 02
yield return new object[] {true, 0, 0, 4}; // 03
yield return new object[] {true, 0, 1, 4}; // 06
yield return new object[] {true, 1, 0, 4}; // 12
yield return new object[] {true, 1, 1, 4}; // 16
yield return new object[] {false, 0, 0, 1}; // 21
yield return new object[] {false, 0, 0, 3}; // 22
yield return new object[] {false, 0, 1, 3}; // 25
yield return new object[] {false, 1, 0, 3}; // 31
yield return new object[] {false, 1, 1, 3}; // 35
}
}
[Theory]
[MemberData(nameof(GetScriptMissingCellsData))]
public async Task GetScriptMissingCell(bool includeIdentity, int defaultCols, int nullableCols, int valuesToSkipSetting)
{
// Setup: Generate the parameters for the row create
RowCreate rc = await GetStandardRowCreate();
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
@@ -57,31 +76,49 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
get
{
yield return new object[] {true, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, no defaults, all values set
yield return new object[] {true, 2, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, some defaults, all values set
yield return new object[] {true, 2, 2, new RegexExpectedOutput(2, 2, 0)}; // Has identity, some defaults, defaults not set
yield return new object[] {true, 4, 1, new RegexExpectedOutput(3, 3, 0)}; // Has identity, all defaults, all values set
yield return new object[] {true, 4, 4, null}; // Has identity, all defaults, defaults not set
yield return new object[] {false, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, no defaults, all values set
yield return new object[] {false, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, some defaults, all values set
yield return new object[] {false, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // No identity, some defaults, defaults not set
yield return new object[] {false, 3, 0, new RegexExpectedOutput(3, 3, 0)}; // No identity, all defaults, all values set
yield return new object[] {false, 3, 3, null}; // No identity, all defaults, defaults not set
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 01
yield return new object[] {true, 0, 1, 1, new RegexExpectedOutput(3, 3, 0)}; // 04
yield return new object[] {true, 0, 1, 2, new RegexExpectedOutput(2, 2, 0)}; // 05
yield return new object[] {true, 0, 3, 1, new RegexExpectedOutput(3, 3, 0)}; // 07
yield return new object[] {true, 0, 3, 2, new RegexExpectedOutput(2, 2, 0)}; // 08
yield return new object[] {true, 0, 3, 4, null}; // 09
yield return new object[] {true, 1, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 10
yield return new object[] {true, 1, 0, 2, new RegexExpectedOutput(2, 2, 0)}; // 11
yield return new object[] {true, 1, 1, 1, new RegexExpectedOutput(3, 3, 0)}; // 13
yield return new object[] {true, 1, 1, 2, new RegexExpectedOutput(2, 2, 0)}; // 14
yield return new object[] {true, 1, 1, 3, new RegexExpectedOutput(1, 1, 0)}; // 15
yield return new object[] {true, 3, 0, 1, new RegexExpectedOutput(3, 3, 0)}; // 17
yield return new object[] {true, 3, 0, 2, new RegexExpectedOutput(2, 2, 0)}; // 18
yield return new object[] {true, 3, 0, 4, null}; // 19
yield return new object[] {false, 0, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 20
yield return new object[] {false, 0, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // 23
yield return new object[] {false, 0, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // 24
yield return new object[] {false, 0, 3, 0, new RegexExpectedOutput(3, 3, 0)}; // 26
yield return new object[] {false, 0, 3, 1, new RegexExpectedOutput(2, 2, 0)}; // 27
yield return new object[] {false, 0, 3, 3, null}; // 28
yield return new object[] {false, 1, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 29
yield return new object[] {false, 1, 0, 1, new RegexExpectedOutput(2, 2, 0)}; // 30
yield return new object[] {false, 1, 1, 0, new RegexExpectedOutput(3, 3, 0)}; // 32
yield return new object[] {false, 1, 1, 1, new RegexExpectedOutput(2, 2, 0)}; // 33
yield return new object[] {false, 1, 1, 2, new RegexExpectedOutput(1, 1, 0)}; // 34
yield return new object[] {false, 3, 0, 0, new RegexExpectedOutput(3, 3, 0)}; // 36
yield return new object[] {false, 3, 0, 1, new RegexExpectedOutput(2, 2, 0)}; // 37
yield return new object[] {false, 3, 0, 3, null}; // 38
}
}
[Theory]
[MemberData(nameof(GetScriptData))]
public async Task GetScript(bool includeIdentity, int defaultCols, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
public async Task GetScript(bool includeIdentity, int colsWithDefaultConstraints, int colsThatAllowNull, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity, defaultCols);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, colsWithDefaultConstraints, colsThatAllowNull);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Create a row create and set the appropriate number of cells
RowCreate rc = new RowCreate(100, rs, etm);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
Common.AddCells(rc, valuesToSkipSetting);
// If: I ask for the script for the row insert
@@ -137,15 +174,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup:
// ... Generate the parameters for the row create
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Setup a db reader for the result of an insert
var newRowReader = Common.GetNewRowDataReader(columns, includeIdentity);
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
// If: I ask for the change to be applied
RowCreate rc = new RowCreate(rowId, rs, etm);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
await rc.ApplyChanges(newRowReader);
// Then: The result set should have an additional row in it
@@ -164,16 +200,41 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Then: It should throw an exception
Assert.Throws<ArgumentNullException>(() => rc.GetCommand(null));
}
[Fact]
public async Task GetCommandMissingCellNoDefault()
{
// Setup: Generate the parameters for the row create
RowCreate rc = await GetStandardRowCreate();
var mockConn = new TestSqlConnection(null);
// If: I ask for a script to be generated without setting any values
// Then: An exception should be thrown for missing cells
public static IEnumerable<object[]> GetCommandMissingCellsData
{
get
{
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 2}; // 02
yield return new object[] {true, 0, 0, 4}; // 03
yield return new object[] {true, 0, 1, 4}; // 06
yield return new object[] {true, 1, 0, 4}; // 12
yield return new object[] {true, 1, 1, 4}; // 16
yield return new object[] {false, 0, 0, 1}; // 21
yield return new object[] {false, 0, 0, 3}; // 22
yield return new object[] {false, 0, 1, 3}; // 25
yield return new object[] {false, 1, 0, 3}; // 31
yield return new object[] {false, 1, 1, 3}; // 35
}
}
[Theory]
[MemberData(nameof(GetCommandMissingCellsData))]
public async Task GetCommandMissingCellNoDefault(bool includeIdentity, int defaultCols, int nullableCols,
int valuesToSkip)
{
// Setup:
// ... Generate the row create object
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// ... Create a mock db connection for building the command
var mockConn = new TestSqlConnection();
// If: I ask for a script to be generated without setting all the required values
// Then: An exception should be thrown for the missing cells
Assert.Throws<InvalidOperationException>(() => rc.GetCommand(mockConn));
}
@@ -181,35 +242,53 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
get
{
yield return new object[] {true, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, no defaults, all values set
yield return new object[] {true, 2, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, some defaults, all values set
yield return new object[] {true, 2, 2, new RegexExpectedOutput(2, 2, 4)}; // Has identity, some defaults, defaults not set
yield return new object[] {true, 4, 1, new RegexExpectedOutput(3, 3, 4)}; // Has identity, all defaults, all values set
yield return new object[] {true, 4, 4, new RegexExpectedOutput(0, 0, 4)}; // Has identity, all defaults, defaults not set
yield return new object[] {false, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, no defaults, all values set
yield return new object[] {false, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, some defaults, all values set
yield return new object[] {false, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // No identity, some defaults, defaults not set
yield return new object[] {false, 3, 0, new RegexExpectedOutput(3, 3, 3)}; // No identity, all defaults, all values set
yield return new object[] {false, 3, 3, new RegexExpectedOutput(0, 0, 3)}; // No identity, all defaults, defaults not set
// NOTE: Test matrix is defined in TableTestMatrix.txt, test cases here are identified by test ID
yield return new object[] {true, 0, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 01
yield return new object[] {true, 0, 1, 1, new RegexExpectedOutput(3, 3, 4)}; // 04
yield return new object[] {true, 0, 1, 2, new RegexExpectedOutput(2, 2, 4)}; // 05
yield return new object[] {true, 0, 3, 1, new RegexExpectedOutput(3, 3, 4)}; // 07
yield return new object[] {true, 0, 3, 2, new RegexExpectedOutput(2, 2, 4)}; // 08
yield return new object[] {true, 0, 3, 4, new RegexExpectedOutput(0, 0, 4)}; // 09
yield return new object[] {true, 1, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 10
yield return new object[] {true, 1, 0, 2, new RegexExpectedOutput(2, 2, 4)}; // 11
yield return new object[] {true, 1, 1, 1, new RegexExpectedOutput(3, 3, 4)}; // 13
yield return new object[] {true, 1, 1, 2, new RegexExpectedOutput(2, 2, 4)}; // 14
yield return new object[] {true, 1, 1, 3, new RegexExpectedOutput(1, 1, 4)}; // 15
yield return new object[] {true, 3, 0, 1, new RegexExpectedOutput(3, 3, 4)}; // 17
yield return new object[] {true, 3, 0, 2, new RegexExpectedOutput(2, 2, 4)}; // 18
yield return new object[] {true, 3, 0, 4, new RegexExpectedOutput(0, 0, 4)}; // 19
yield return new object[] {false, 0, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 20
yield return new object[] {false, 0, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // 23
yield return new object[] {false, 0, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // 24
yield return new object[] {false, 0, 3, 0, new RegexExpectedOutput(3, 3, 3)}; // 26
yield return new object[] {false, 0, 3, 1, new RegexExpectedOutput(2, 2, 3)}; // 27
yield return new object[] {false, 0, 3, 3, new RegexExpectedOutput(0, 0, 3)}; // 28
yield return new object[] {false, 1, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 29
yield return new object[] {false, 1, 0, 1, new RegexExpectedOutput(2, 2, 3)}; // 30
yield return new object[] {false, 1, 1, 0, new RegexExpectedOutput(3, 3, 3)}; // 32
yield return new object[] {false, 1, 1, 1, new RegexExpectedOutput(2, 2, 3)}; // 33
yield return new object[] {false, 1, 1, 2, new RegexExpectedOutput(1, 1, 3)}; // 34
yield return new object[] {false, 3, 0, 0, new RegexExpectedOutput(3, 3, 3)}; // 36
yield return new object[] {false, 3, 0, 1, new RegexExpectedOutput(2, 2, 3)}; // 37
yield return new object[] {false, 3, 0, 3, new RegexExpectedOutput(0, 0, 3)}; // 38
}
}
[Theory]
[MemberData(nameof(GetCommandData))]
public async Task GetCommand(bool includeIdentity, int defaultCols, int valuesToSkipSetting, RegexExpectedOutput expectedOutput)
public async Task GetCommand(bool includeIdentity, int defaultCols, int nullableCols, int valuesToSkip, RegexExpectedOutput expectedOutput)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(includeIdentity);
ResultSet rs = await Common.GetResultSet(columns, includeIdentity);
EditTableMetadata etm = Common.GetStandardMetadata(columns, includeIdentity, defaultCols);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, defaultCols, nullableCols);
ResultSet rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(null);
// ... Create a row create and set the appropriate number of cells
RowCreate rc = new RowCreate(100, rs, etm);
Common.AddCells(rc, valuesToSkipSetting);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
Common.AddCells(rc, valuesToSkip);
// If: I ask for the command for the row insert
DbCommand cmd = rc.GetCommand(mockConn);
@@ -304,10 +383,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Generate a row create with default values
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, columns.Length);
RowCreate rc = new RowCreate(rowId, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 3, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// If: I request an edit row from the row create
EditRow er = rc.GetEditRow(null);
@@ -335,10 +413,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup: Generate a row create with an identity column
const long rowId = 100;
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, true);
RowCreate rc = new RowCreate(rowId, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
RowCreate rc = new RowCreate(rowId, rs, data.TableMetadata);
// If: I request an edit row from the row created
EditRow er = rc.GetEditRow(null);
@@ -463,7 +540,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
await rs.ReadResultToEnd(testReader, CancellationToken.None);
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
var etm = Common.GetCustomEditTableMetadata(cols);
// ... Create the row create
RowCreate rc = new RowCreate(100, rs, etm);
@@ -492,7 +569,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SetCellNull()
{
// Setup: Generate a row create
RowCreate rc = await GetStandardRowCreate();
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 3);
var rs = await Common.GetResultSet(data.DbColumns, false);
var rc = new RowCreate(100, rs, data.TableMetadata);
// If: I set a cell in the newly created row to null
const string nullValue = "NULL";
@@ -534,16 +613,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RevertCellNotSet(bool hasDefaultValues)
[InlineData(1)]
[InlineData(0)]
public async Task RevertCellNotSet(int defaultCols)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, hasDefaultValues ? 1 : 0);
RowCreate rc = new RowCreate(100, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
// If: I attempt to revert a cell that has not been set
EditRevertCellResult result = rc.RevertCell(0);
@@ -553,7 +631,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(result);
// ... We should get back an edit cell with a value based on the default value
string expectedDisplayValue = hasDefaultValues ? Common.DefaultValue : string.Empty;
string expectedDisplayValue = defaultCols > 0 ? Common.DefaultValue : string.Empty;
Assert.NotNull(result.Cell);
Assert.Equal(expectedDisplayValue, result.Cell.DisplayValue);
Assert.False(result.Cell.IsNull); // TODO: Modify to support null defaults
@@ -566,16 +644,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RevertCellThatWasSet(bool hasDefaultValues)
[InlineData(1)]
[InlineData(0)]
public async Task RevertCellThatWasSet(int defaultCols)
{
// Setup:
// ... Generate the parameters for the row create
DbColumn[] columns = Common.GetColumns(false);
ResultSet rs = await Common.GetResultSet(columns, false);
EditTableMetadata etm = Common.GetStandardMetadata(columns, false, hasDefaultValues ? 1 : 0);
RowCreate rc = new RowCreate(100, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, defaultCols, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, false);
RowCreate rc = new RowCreate(100, rs, data.TableMetadata);
rc.SetCell(0, "1");
// If: I attempt to revert a cell that was set
@@ -586,7 +663,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(result);
// ... We should get back an edit cell with a value based on the default value
string expectedDisplayValue = hasDefaultValues ? Common.DefaultValue : string.Empty;
string expectedDisplayValue = defaultCols > 0 ? Common.DefaultValue : string.Empty;
Assert.NotNull(result.Cell);
Assert.Equal(expectedDisplayValue, result.Cell.DisplayValue);
Assert.False(result.Cell.IsNull); // TODO: Modify to support null defaults
@@ -602,10 +679,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private static async Task<RowCreate> GetStandardRowCreate()
{
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
return new RowCreate(100, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowCreate(100, rs, data.TableMetadata);
}
public class RegexExpectedOutput
@@ -617,9 +693,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
ExpectedOutColumns = expectedOutColumns;
}
public int ExpectedInColumns { get; set; }
public int ExpectedInValues { get; set; }
public int ExpectedOutColumns { get; set; }
public int ExpectedInColumns { get; }
public int ExpectedInValues { get; }
public int ExpectedOutColumns { get; }
}
}
}

View File

@@ -8,7 +8,6 @@ using System.Data.Common;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -24,17 +23,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task RowDeleteConstruction()
{
// Setup: Create the values to store
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I create a RowCreate instance
RowDelete rc = new RowDelete(100, rs, etm);
RowDelete rc = new RowDelete(100, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(100, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
[Theory]
@@ -42,12 +40,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
[InlineData(false)]
public async Task GetScriptTest(bool isMemoryOptimized)
{
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I ask for a script to be generated for delete
RowDelete rd = new RowDelete(0, rs, etm);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
string script = rd.GetScript();
// Then:
@@ -55,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.NotNull(script);
// ... It should be formatted as a delete script
string scriptStart = $"DELETE FROM {etm.EscapedMultipartName}";
string scriptStart = $"DELETE FROM {data.TableMetadata.EscapedMultipartName}";
if (isMemoryOptimized)
{
scriptStart += " WITH(SNAPSHOT)";
@@ -67,12 +64,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task ApplyChanges()
{
// Setup: Generate the parameters for the row delete object
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I ask for the change to be applied
RowDelete rd = new RowDelete(0, rs, etm);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
await rd.ApplyChanges(null); // Reader not used, can be null
// Then : The result set should have one less row in it
@@ -88,10 +84,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row delete
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
RowDelete rd = new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
// ... Mock db connection for building the command
var mockConn = new TestSqlConnection(null);
@@ -117,7 +112,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... There should be a table
string tbl = m.Groups[1].Value;
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
// ... There should be as many where components as there are keys
string[] whereComponents = m.Groups[2].Value.Split(new[] {"AND"}, StringSplitOptions.None);
@@ -142,10 +137,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetEditRow()
{
// Setup: Create a row delete
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowDelete rd = new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowDelete rd = new RowDelete(0, rs, data.TableMetadata);
// If: I attempt to get an edit row
DbCellValue[] cells = rs.GetRow(0).ToArray();
@@ -208,10 +202,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private async Task<RowDelete> GetStandardRowDelete()
{
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
return new RowDelete(0, rs, etm);
Common.TestDbColumnsWithTableMetadata data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowDelete(0, rs, data.TableMetadata);
}
}
}

View File

@@ -47,7 +47,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
new TestDbColumn("col1")
},
new object[] { "id", "1" });
var etm = Common.GetStandardMetadata(rs.Columns);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
// If: I validate a column ID that is out of range
// Then: It should throw
@@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
new TestDbColumn("col1")
},
new object[] { "id", "1" });
var etm = Common.GetStandardMetadata(rs.Columns);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
// If: I validate a column ID that is not updatable
// Then: It should throw
@@ -80,7 +80,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with a single column
var cols = new[] {col};
ResultSet rs = await GetResultSet(cols, new[] {val});
EditTableMetadata etm = Common.GetStandardMetadata(cols);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(cols);
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseSingleKey(nullClause);
@@ -130,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with multiple key columns
DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")};
ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"});
EditTableMetadata etm = Common.GetStandardMetadata(cols);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(cols);
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseMultipleKeys();
@@ -142,7 +142,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a result set and metadata provider with no key columns
DbColumn[] cols = {new TestDbColumn("col1"), new TestDbColumn("col2")};
ResultSet rs = await GetResultSet(cols, new object[] {"abc", "def"});
EditTableMetadata etm = Common.GetStandardMetadata(new DbColumn[] {});
EditTableMetadata etm = Common.GetCustomEditTableMetadata(new DbColumn[] {});
RowEditTester rt = new RowEditTester(rs, etm);
rt.ValidateWhereClauseNoKeys();
@@ -152,16 +152,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingByTypeTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I request to sort a list of the three different edit operations
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowDelete(0, rs, etm),
new RowUpdate(0, rs, etm),
new RowCreate(0, rs, etm)
new RowDelete(0, rs, data.TableMetadata),
new RowUpdate(0, rs, data.TableMetadata),
new RowCreate(0, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -174,16 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingUpdatesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false, 4);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false, 4);
// If: I sort 3 edit operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowUpdate(3, rs, etm),
new RowUpdate(1, rs, etm),
new RowUpdate(2, rs, etm)
new RowUpdate(3, rs, data.TableMetadata),
new RowUpdate(1, rs, data.TableMetadata),
new RowUpdate(2, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -197,16 +195,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingCreatesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I sort 3 edit operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowCreate(3, rs, etm),
new RowCreate(1, rs, etm),
new RowCreate(2, rs, etm)
new RowCreate(3, rs, data.TableMetadata),
new RowCreate(1, rs, data.TableMetadata),
new RowCreate(2, rs, data.TableMetadata)
};
rowEdits.Sort();
@@ -220,16 +217,15 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SortingDeletesByRowIdTest()
{
// Setup: Create a result set and metadata we can reuse
var cols = Common.GetColumns(false);
var rs = await Common.GetResultSet(cols, false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I sort 3 delete operations of the same type
List<RowEditBase> rowEdits = new List<RowEditBase>
{
new RowDelete(1, rs, etm),
new RowDelete(3, rs, etm),
new RowDelete(2, rs, etm)
new RowDelete(1, rs, data.TableMetadata),
new RowDelete(3, rs, data.TableMetadata),
new RowDelete(2, rs, data.TableMetadata)
};
rowEdits.Sort();

View File

@@ -9,7 +9,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.EditData;
using Microsoft.SqlTools.ServiceLayer.EditData.Contracts;
using Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement;
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
@@ -23,20 +22,20 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public class RowUpdateTests
{
[Fact]
public void RowUpdateConstruction()
public async Task RowUpdateConstruction()
{
// Setup: Create the values to store
const long rowId = 0;
ResultSet rs = QueryExecution.Common.GetBasicExecutedBatch().ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
// If: I create a RowUpdate instance
RowUpdate rc = new RowUpdate(rowId, rs, etm);
RowUpdate rc = new RowUpdate(rowId, rs, data.TableMetadata);
// Then: The values I provided should be available
Assert.Equal(rowId, rc.RowId);
Assert.Equal(rs, rc.AssociatedResultSet);
Assert.Equal(etm, rc.AssociatedObjectMetadata);
Assert.Equal(data.TableMetadata, rc.AssociatedObjectMetadata);
}
[Fact]
@@ -88,7 +87,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
rs.ReadResultToEnd(testReader, CancellationToken.None).Wait();
// ... Generate the metadata
var etm = Common.GetStandardMetadata(cols);
var etm = Common.GetCustomEditTableMetadata(cols);
// ... Create the row update
RowUpdate ru = new RowUpdate(0, rs, etm);
@@ -121,13 +120,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task SetCellImplicitRevertTest()
{
// Setup: Create a fake table to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If:
// ... I add updates to all the cells in the row
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, 1);
// ... Then I update a cell back to it's old value
@@ -159,16 +157,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.All(updateSplit, s => Assert.Equal(2, s.Split('=').Length));
}
[Fact]
public async Task SetCellImplicitRowRevertTests()
{
// Setup: Create a fake column to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If:
// ... I add updates to one cell in the row
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(1, "qqq");
// ... Then I update the cell to its original value
@@ -198,12 +196,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetScriptTest(bool isMemoryOptimized)
{
// Setup: Create a fake table to update
DbColumn[] columns = Common.GetColumns(true);
ResultSet rs = await Common.GetResultSet(columns, true);
EditTableMetadata etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, true, 0, 0);
ResultSet rs = await Common.GetResultSet(data.DbColumns, true);
// If: I ask for a script to be generated for update
RowUpdate ru = new RowUpdate(0, rs, etm);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, 1);
string script = ru.GetScript();
@@ -223,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
string tbl = m.Groups[1].Value;
string updates = m.Groups[2].Value;
string[] updateSplit = updates.Split(',');
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
Assert.Equal(3, updateSplit.Length);
Assert.All(updateSplit, s => Assert.Equal(2, s.Split('=').Length));
}
@@ -237,10 +234,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update with cell updates
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns, isMemoryOptimized);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(isMemoryOptimized, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
Common.AddCells(ru, includeIdentity ? 1 : 0);
// ... Mock db connection for building the command
@@ -268,7 +264,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... There should be a table
string tbl = m.Groups[1].Value;
Assert.Equal(etm.EscapedMultipartName, tbl);
Assert.Equal(data.TableMetadata.EscapedMultipartName, tbl);
// ... There should be 3 parameters for input
string[] inCols = m.Groups[2].Value.Split(',');
@@ -301,10 +297,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public async Task GetEditRow()
{
// Setup: Create a row update with a cell set
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "foo");
// If: I attempt to get an edit row
@@ -356,14 +351,13 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(includeIdentity);
var rs = await Common.GetResultSet(columns, includeIdentity);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, includeIdentity, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, includeIdentity);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
long oldBytesWritten = rs.totalBytesWritten;
// ... Setup a db reader for the result of an update
var newRowReader = Common.GetNewRowDataReader(columns, includeIdentity);
var newRowReader = Common.GetNewRowDataReader(data.DbColumns, includeIdentity);
// If: I ask for the change to be applied
await ru.ApplyChanges(newRowReader);
@@ -379,10 +373,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(true);
var rs = await Common.GetResultSet(columns, true);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, true);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I ask for the changes to be applied with a null db reader
// Then: I should get an exception
@@ -397,10 +390,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I attempt to revert a cell that is out of range
// Then: I should get an exception
@@ -412,10 +404,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update (no cell updates needed)
var columns = Common.GetColumns(true);
var rs = await Common.GetResultSet(columns, true);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, true, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, true);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
// If: I attempt to revert a cell that has not been set
EditRevertCellResult result = ru.RevertCell(0);
@@ -441,10 +432,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "qqq");
ru.SetCell(1, "qqq");
@@ -472,10 +462,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
// Setup:
// ... Create a row update
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
RowUpdate ru = new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
RowUpdate ru = new RowUpdate(0, rs, data.TableMetadata);
ru.SetCell(0, "qqq");
// If: I attempt to revert a cell that was set
@@ -499,10 +488,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
private async Task<RowUpdate> GetStandardRowUpdate()
{
var columns = Common.GetColumns(false);
var rs = await Common.GetResultSet(columns, false);
var etm = Common.GetStandardMetadata(columns);
return new RowUpdate(0, rs, etm);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
var rs = await Common.GetResultSet(data.DbColumns, false);
return new RowUpdate(0, rs, data.TableMetadata);
}
}
}

View File

@@ -16,7 +16,6 @@ using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts.ExecuteRequests;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Test.Common.RequestContextMocking;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Moq;
using Xunit;
@@ -357,7 +356,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
var cols = mockQueryResults[0].Columns;
// ... Create a metadata factory that will return some generic column information
var etm = Common.GetStandardMetadata(cols.ToArray());
var etm = Common.GetCustomEditTableMetadata(cols.ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -442,7 +441,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
return s;
}

View File

@@ -130,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// ... Add a mock edit to the edit cache to cause the .TryAdd to fail
@@ -155,7 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// If: I add a row to the session
@@ -212,7 +212,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
etm.Extend(cols);
// ... Create a result set
var q = await Common.GetQuery(cols, false);
var q = await Common.GetQuery(cols.Cast<DbColumn>().ToArray(), false);
// ... Create a session from all this
EditSession s = await Common.GetCustomSession(q, etm);
@@ -273,10 +273,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Revert Cell
Action<EditSession, long> revertCellAction = (s, l) => s.RevertCell(l, 0);
yield return new object[] {-1L, revertRowAction};
yield return new object[] {0L, revertRowAction}; // This is invalid b/c there isn't an edit pending for this row
yield return new object[] {(long) QueryExecution.Common.StandardRows, revertRowAction};
yield return new object[] {100L, revertRowAction};
yield return new object[] {-1L, revertCellAction};
yield return new object[] {0L, revertCellAction}; // This is invalid b/c there isn't an edit pending for this row
yield return new object[] {(long) QueryExecution.Common.StandardRows, revertCellAction};
yield return new object[] {100L, revertCellAction};
}
}
@@ -410,7 +410,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup:
// ... Create a metadata factory that will return some generic column information
var b = QueryExecution.Common.GetBasicExecutedBatch();
var etm = Common.GetStandardMetadata(b.ResultSets[0].Columns);
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -449,7 +449,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup:
// ... Create a metadata factory that will return some generic column information
var b = QueryExecution.Common.GetBasicExecutedBatch();
var etm = Common.GetStandardMetadata(b.ResultSets[0].Columns);
var etm = Common.GetCustomEditTableMetadata(b.ResultSets[0].Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -488,7 +488,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a metadata factory that will return some generic column information
var q = QueryExecution.Common.GetBasicExecutedQuery();
var rs = q.Batches[0].ResultSets[0];
var etm = Common.GetStandardMetadata(rs.Columns);
var etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
Mock<IEditMetadataFactory> emf = new Mock<IEditMetadataFactory>();
emf.Setup(f => f.GetObjectMetadata(It.IsAny<DbConnection>(), It.IsAny<string[]>(), It.IsAny<string>()))
.Returns(etm);
@@ -499,7 +499,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// ... Create a query runner that will return a successful query
Mock<EditSession.QueryRunner> qr = new Mock<EditSession.QueryRunner>();
qr.Setup(r => r(It.IsAny<string>()))
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q, null)));
.Returns(Task.FromResult(new EditSession.EditSessionQueryExecutionState(q)));
// ... Create a mock for verifying the failure handler will be called
var successHandler = DoNothingSuccessMock;
@@ -755,7 +755,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
// Setup: Create a session with a proper query and metadata
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
EditSession s = await Common.GetCustomSession(q, etm);
// If: I ask for 3 rows from session skipping the first
@@ -1129,15 +1129,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryWithoutLimit()
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows without a limit
EditInitializeFiltering eif = new EditInitializeFiltering
{
LimitResults = null
};
string query = EditSession.ConstructInitializeQuery(etm, eif);
string query = EditSession.ConstructInitializeQuery(data.TableMetadata, eif);
// Then:
// ... The query should look like a select statement
@@ -1146,10 +1145,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.True(match.Success);
// ... There should be columns in it
Assert.Equal(etm.Columns.Length, match.Groups[1].Value.Split(',').Length);
Assert.Equal(data.DbColumns.Length, match.Groups[1].Value.Split(',').Length);
// ... The table name should be in it
Assert.Equal(etm.EscapedMultipartName, match.Groups[2].Value);
Assert.Equal(data.TableMetadata.EscapedMultipartName, match.Groups[2].Value);
// ... It should NOT have a TOP clause in it
Assert.DoesNotContain("TOP", query);
@@ -1159,8 +1158,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryNegativeLimit()
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows with a negative limit
// Then: An exception should be thrown
@@ -1168,7 +1166,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
LimitResults = -1
};
Assert.Throws<ArgumentOutOfRangeException>(() => EditSession.ConstructInitializeQuery(etm, eif));
Assert.Throws<ArgumentOutOfRangeException>(() => EditSession.ConstructInitializeQuery(data.TableMetadata, eif));
}
[Theory]
@@ -1178,15 +1176,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
public void ConstructQueryWithLimit(int limit)
{
// Setup: Create a metadata provider for some basic columns
var cols = Common.GetColumns(false);
var etm = Common.GetStandardMetadata(cols);
var data = new Common.TestDbColumnsWithTableMetadata(false, false, 0, 0);
// If: I generate a query for selecting rows without a limit
EditInitializeFiltering eif = new EditInitializeFiltering
{
LimitResults = limit
};
string query = EditSession.ConstructInitializeQuery(etm, eif);
string query = EditSession.ConstructInitializeQuery(data.TableMetadata, eif);
// Then:
// ... The query should look like a select statement
@@ -1195,10 +1192,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
Assert.True(match.Success);
// ... There should be columns in it
Assert.Equal(etm.Columns.Length, match.Groups[2].Value.Split(',').Length);
Assert.Equal(data.DbColumns.Length, match.Groups[2].Value.Split(',').Length);
// ... The table name should be in it
Assert.Equal(etm.EscapedMultipartName, match.Groups[3].Value);
Assert.Equal(data.TableMetadata.EscapedMultipartName, match.Groups[3].Value);
// ... The top count should be equal to what we provided
int limitFromQuery;
@@ -1251,7 +1248,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.EditData
{
Query q = QueryExecution.Common.GetBasicExecutedQuery();
ResultSet rs = q.Batches[0].ResultSets[0];
EditTableMetadata etm = Common.GetStandardMetadata(rs.Columns);
EditTableMetadata etm = Common.GetCustomEditTableMetadata(rs.Columns.Cast<DbColumn>().ToArray());
return await Common.GetCustomSession(q, etm);
}
}

View File

@@ -0,0 +1,58 @@
ID | Identity Column | Default Cols | Nullable Cols | Values Set | INSERT VALID | In Cols | In Vals | Out Vals
---+-----------------+--------------+---------------+------------+--------------------------------------------------------------+------------------------------
01 | Y | 0 (None) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
02 | Y | 0 (None) | 0 (None) | 2/2 | INVALID - Values missing | N/A | N/A | N/A
03 | Y | 0 (None) | 0 (None) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
04 | Y | 0 (None) | 1 (Some) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
05 | Y | 0 (None) | 1 (Some) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
06 | Y | 0 (None) | 1 (Some) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
07 | Y | 0 (None) | 3 (All) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
08 | Y | 0 (None) | 3 (All) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
09 | Y | 0 (None) | 3 (All) | 0/4 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 4
10 | Y | 1 (Some) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
11 | Y | 1 (Some) | 0 (None) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
12 | Y | 1 (Some) | 0 (None) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
13 | Y | 1 (Some) | 1 (Some) | 3/1 | INSERT INTO [test] (col1, col2, col3) VALUES ('a', 'b', 'c') | 3 | 3 | 4
14 | Y | 1 (Some) | 1 (Some) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
15 | Y | 1 (Some) | 1 (Some) | 1/3 | INSERT INTO [test] (col3) VALUES ('c') | 1 | 1 | 4
16 | Y | 1 (Some) | 1 (Some) | 0/4 | INVALID - Values missing | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 1 (Some) | 3 (All) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
17 | Y | 3 (All) | 0 (None) | 3/1 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 4
18 | Y | 3 (All) | 0 (None) | 2/2 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 4
19 | Y | 3 (All) | 0 (None) | 0/4 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 4
!! | Y | 3 (All) | 1 (Some) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 1 (Some) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 1 (Some) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 3/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 2/2 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | Y | 3 (All) | 3 (All) | 0/4 | INVALID - Too many columns defined | N/A | N/A | N/A
20 | N | 0 (None) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
21 | N | 0 (None) | 0 (None) | 2/1 | INVALID - Values missing | N/A | N/A | N/A
22 | N | 0 (None) | 0 (None) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
23 | N | 0 (None) | 1 (Some) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
24 | N | 0 (None) | 1 (Some) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
25 | N | 0 (None) | 1 (Some) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
26 | N | 0 (None) | 3 (All) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
27 | N | 0 (None) | 3 (All) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
28 | N | 0 (None) | 3 (All) | 0/3 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 3
29 | N | 1 (Some) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
30 | N | 1 (Some) | 0 (None) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
31 | N | 1 (Some) | 0 (None) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
32 | N | 1 (Some) | 1 (Some) | 3/0 | INSERT INTO [test] (col1, col2, col3) VALUES ('a', 'b', 'c') | 3 | 3 | 3
33 | N | 1 (Some) | 1 (Some) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
34 | N | 1 (Some) | 1 (Some) | 1/2 | INSERT INTO [test] (col3) VALUES ('c') | 1 | 1 | 3
35 | N | 1 (Some) | 1 (Some) | 0/3 | INVALID - Values missing | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 1 (Some) | 3 (All) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A
36 | N | 3 (All) | 0 (None) | 3/0 | INSERT INTO [test] (col0, col1, col2) VALUES ('a', 'b', 'c') | 3 | 3 | 3
37 | N | 3 (All) | 0 (None) | 2/1 | INSERT INTO [test] (col2, col3) VALUES ('b', 'c') | 2 | 2 | 3
38 | N | 3 (All) | 0 (None) | 0/3 | INSERT INTO [test] DEFAULT VALUES | NULL | NULL | 3
!! | N | 3 (All) | 1 (Some) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 1 (Some) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 1 (Some) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 3/0 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 2/1 | INVALID - Too many columns defined | N/A | N/A | N/A
!! | N | 3 (All) | 3 (All) | 0/3 | INVALID - Too many columns defined | N/A | N/A | N/A