Browse Source

Fix | SqlBuffer.SqlGuid (#2310)

pull/2457/head
Evgeny Akhtimirov 1 year ago
committed by GitHub
parent
commit
f5df519f5e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      .gitignore
  2. 2
      src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs
  3. 1
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
  4. 253
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs

3
.gitignore

@ -353,6 +353,9 @@ healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# JetBrains Rider (cross platform .NET IDE) working folder
.idea/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

2
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs

@ -811,7 +811,7 @@ namespace Microsoft.Data.SqlClient
{
if (StorageType.Guid == _type)
{
return new SqlGuid(_value._guid);
return IsNull ? SqlGuid.Null : new SqlGuid(_value._guid);
}
else if (StorageType.SqlGuid == _type)
{

1
src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj

@ -33,6 +33,7 @@
<Compile Include="LocalizationTest.cs" />
<Compile Include="MultipartIdentifierTests.cs" />
<Compile Include="SqlAuthenticationProviderTest.cs" />
<Compile Include="SqlBufferTests.cs" />
<Compile Include="SqlClientLoggerTest.cs" />
<Compile Include="SqlCommandSetTest.cs" />
<Compile Include="SqlConfigurableRetryLogicTest.cs" />

253
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs

@ -0,0 +1,253 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
{
public sealed class SqlBufferTests
{
static SqlBufferTests()
{
const string sqlBufferTypeFullName = "Microsoft.Data.SqlClient.SqlBuffer";
const string storageTypeName = nameof(SqlBufferProxy.StorageType);
var assembly = typeof(SqlClientFactory).Assembly;
_sqlBufferType = assembly.GetType(sqlBufferTypeFullName)
?? throw new Exception($"Type not found [{sqlBufferTypeFullName}]");
_storageTypeType = _sqlBufferType.GetNestedTypes(BindingFlags.NonPublic)
.FirstOrDefault(x => x.Name == storageTypeName)
?? throw new Exception($"Type not found [{sqlBufferTypeFullName}+{storageTypeName}]");
}
private static readonly Type _sqlBufferType;
private static readonly Type _storageTypeType;
private readonly SqlBufferProxy _target = new();
public static IEnumerable<object[]> GetStorageTypeValues()
{
#if NET6_0_OR_GREATER
return Enum.GetValues<SqlBufferProxy.StorageType>()
.Select(x => new object[] { x });
#else
return Enum.GetValues(typeof(SqlBufferProxy.StorageType))
.OfType<SqlBufferProxy.StorageType>()
.Select(x => new object[] { x });
#endif
}
[Theory]
[MemberData(nameof(GetStorageTypeValues))]
public void StorageTypeInProxyShouldHaveTheSameValueAsOriginal(SqlBufferProxy.StorageType expected)
{
var originalEnumName = Enum.GetName(_storageTypeType, (int)expected);
Assert.Equal(expected.ToString(), originalEnumName);
}
[Fact]
public void GuidShouldThrowWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
[Theory]
[InlineData(SqlBufferProxy.StorageType.Guid)]
[InlineData(SqlBufferProxy.StorageType.SqlGuid)]
public void GuidShouldThrowWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
[Fact]
public void GuidShouldReturnWhenGuidIsSet()
{
var expected = Guid.NewGuid();
_target.Guid = expected;
Assert.Equal(expected, _target.Guid);
}
[Fact]
public void GuidShouldReturnExpectedWhenSqlGuidIsSet()
{
var expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.Guid);
}
[Theory]
[InlineData(SqlBufferProxy.StorageType.Guid)]
[InlineData(SqlBufferProxy.StorageType.SqlGuid)]
public void SqlGuidShouldReturnSqlNullWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnSqlGuidNullWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlGuid);
}
[Fact]
public void SqlValueShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlValue);
}
[Fact]
public void SqlValueShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlValue);
}
public sealed class SqlBufferProxy
{
public enum StorageType
{
Empty = 0,
Boolean,
Byte,
DateTime,
Decimal,
Double,
Int16,
Int32,
Int64,
Guid,
Money,
Single,
String,
SqlBinary,
SqlCachedBuffer,
SqlGuid,
SqlXml,
Date,
DateTime2,
DateTimeOffset,
Time,
}
private static readonly PropertyInfo _guidProperty;
private static readonly PropertyInfo _sqlGuidProperty;
private static readonly PropertyInfo _sqlValueProperty;
private static readonly MethodInfo _setToNullOfTypeMethod;
private readonly object _instance;
static SqlBufferProxy()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
_guidProperty = _sqlBufferType.GetProperty(nameof(Guid), flags);
_sqlGuidProperty = _sqlBufferType.GetProperty(nameof(SqlGuid), flags);
_sqlValueProperty = _sqlBufferType.GetProperty(nameof(SqlValue), flags);
_setToNullOfTypeMethod = _sqlBufferType.GetMethod(nameof(SetToNullOfType), flags);
}
public SqlBufferProxy()
{
_instance = Activator.CreateInstance(_sqlBufferType, true);
}
public Guid Guid
{
get => GetPropertyValue<Guid>(_guidProperty);
set => SetPropertyValue(_guidProperty, value);
}
public SqlGuid SqlGuid
{
get => GetPropertyValue<SqlGuid>(_sqlGuidProperty);
set => SetPropertyValue(_sqlGuidProperty, value);
}
public object SqlValue
{
get => GetPropertyValue<object>(_sqlValueProperty);
}
public void SetToNullOfType(StorageType storageType)
{
#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
_setToNullOfTypeMethod
.Invoke(_instance, BindingFlags.DoNotWrapExceptions, null, new object[] { (int)storageType }, null);
#else
_setToNullOfTypeMethod.Invoke(_instance, new object[] { (int)storageType });
#endif
}
private T GetPropertyValue<T>(PropertyInfo property)
{
#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
return (T)property.GetValue(_instance, BindingFlags.DoNotWrapExceptions, null, null, null);
#else
try
{
return (T)property.GetValue(_instance);
}
catch (TargetInvocationException e)
{
throw e.InnerException!;
}
#endif
}
private void SetPropertyValue(PropertyInfo property, object value)
{
#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
property.SetValue(_instance, value, BindingFlags.DoNotWrapExceptions, null, null, null);
#else
try
{
property.SetValue(_instance, value);
}
catch (TargetInvocationException e)
{
throw e.InnerException!;
}
#endif
}
}
}
}
Loading…
Cancel
Save