diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d08bf8..7339181f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +* GetUint64(int ordinal) returns a ulong for Uint8, Uint16, Uint32, Uint64 YDB types. +* GetInt64(int ordinal) returns a int for Int8, Int16, Int32, Int64, Uint8, Uint16, Uint32 YDB types. +* GetUint32(int ordinal) returns a uint for Uint8, Uint16, Uint32 YDB types. +* GetInt32(int ordinal) returns a int for Int8, Int16, Int32, Uint8, Uint16 YDB types. +* GetUint16(int ordinal) returns a ushort for Uint8, Uint16 YDB types. +* GetInt16(int ordinal) returns a short for Int8, Int16, Uint8 YDB types. +* GetDouble(int ordinal) returns a double for Float and Double YDB types. +* Throw InvalidCastException on string.Empty in `GetChar(int ordinal)`. +* Changed Ydb.Sdk.Value.InvalidTypeException to InvalidCastException in YdbValueParser. * Changed InvalidCastException to InvalidOperationException in YdbParameter. * Added specification tests: YdbCommandTests and YdbParameterTests. * YdbConnection.Database returns string.Empty if ConnectionStringBuilder is null. diff --git a/src/Ydb.Sdk/src/Ado/ThrowHelper.cs b/src/Ydb.Sdk/src/Ado/ThrowHelper.cs index e00113cb..d665936b 100644 --- a/src/Ydb.Sdk/src/Ado/ThrowHelper.cs +++ b/src/Ydb.Sdk/src/Ado/ThrowHelper.cs @@ -6,11 +6,16 @@ internal static class ThrowHelper { internal static T ThrowInvalidCast(YdbValue ydbValue) { - throw new InvalidCastException($"Field type {ydbValue.TypeId} can't be cast to {typeof(T)} type."); + throw new InvalidCastException($"Field YDB type {ydbValue.TypeId} can't be cast to {typeof(T)} type."); } internal static void ThrowIndexOutOfRangeException(int columnCount) { throw new IndexOutOfRangeException("Ordinal must be between 0 and " + (columnCount - 1)); } + + internal static void ThrowInvalidCastException(string expectedType, string actualType) + { + throw new InvalidCastException($"Invalid type of YDB value, expected: {expectedType}, actual: {actualType}."); + } } diff --git a/src/Ydb.Sdk/src/Ado/YdbDataReader.cs b/src/Ydb.Sdk/src/Ado/YdbDataReader.cs index 517193a6..0839ef55 100644 --- a/src/Ydb.Sdk/src/Ado/YdbDataReader.cs +++ b/src/Ydb.Sdk/src/Ado/YdbDataReader.cs @@ -129,7 +129,8 @@ public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int public override char GetChar(int ordinal) { - return GetString(ordinal)[0]; + var str = GetString(ordinal); + return str.Length == 0 ? throw new InvalidCastException("Could not read char - string was empty") : str[0]; } public override long GetChars(int ordinal, long dataOffset, char[]? buffer, int bufferOffset, int length) @@ -208,7 +209,14 @@ public override decimal GetDecimal(int ordinal) public override double GetDouble(int ordinal) { - return GetFieldYdbValue(ordinal).GetDouble(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Float => ydbValue.GetFloat(), + YdbTypeId.Double => ydbValue.GetDouble(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public override T GetFieldValue(int ordinal) @@ -223,6 +231,11 @@ public override T GetFieldValue(int ordinal) return (T)(object)GetStream(ordinal); } + if (typeof(T) == typeof(char)) + { + return (T)(object)GetChar(ordinal); + } + return base.GetFieldValue(ordinal); } @@ -273,22 +286,55 @@ public override Guid GetGuid(int ordinal) public override short GetInt16(int ordinal) { - return GetFieldYdbValue(ordinal).GetInt16(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Int8 => ydbValue.GetInt8(), + YdbTypeId.Int16 => ydbValue.GetInt16(), + YdbTypeId.Uint8 => ydbValue.GetUint8(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public ushort GetUint16(int ordinal) { - return GetFieldYdbValue(ordinal).GetUint16(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Uint8 => ydbValue.GetUint8(), + YdbTypeId.Uint16 => ydbValue.GetUint16(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public override int GetInt32(int ordinal) { - return GetFieldYdbValue(ordinal).GetInt32(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Int32 => ydbValue.GetInt32(), + YdbTypeId.Int8 => ydbValue.GetInt8(), + YdbTypeId.Int16 => ydbValue.GetInt16(), + YdbTypeId.Uint8 => ydbValue.GetUint8(), + YdbTypeId.Uint16 => ydbValue.GetUint16(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public uint GetUint32(int ordinal) { - return GetFieldYdbValue(ordinal).GetUint32(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Uint8 => ydbValue.GetUint8(), + YdbTypeId.Uint16 => ydbValue.GetUint16(), + YdbTypeId.Uint32 => ydbValue.GetUint32(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public override long GetInt64(int ordinal) @@ -301,13 +347,25 @@ public override long GetInt64(int ordinal) YdbTypeId.Int32 => ydbValue.GetInt32(), YdbTypeId.Int8 => ydbValue.GetInt8(), YdbTypeId.Int16 => ydbValue.GetInt16(), + YdbTypeId.Uint8 => ydbValue.GetUint8(), + YdbTypeId.Uint16 => ydbValue.GetUint16(), + YdbTypeId.Uint32 => ydbValue.GetUint32(), _ => ThrowHelper.ThrowInvalidCast(ydbValue) }; } public ulong GetUint64(int ordinal) { - return GetFieldYdbValue(ordinal).GetUint64(); + var ydbValue = GetFieldYdbValue(ordinal); + + return ydbValue.TypeId switch + { + YdbTypeId.Uint64 => ydbValue.GetUint64(), + YdbTypeId.Uint8 => ydbValue.GetUint8(), + YdbTypeId.Uint16 => ydbValue.GetUint16(), + YdbTypeId.Uint32 => ydbValue.GetUint32(), + _ => ThrowHelper.ThrowInvalidCast(ydbValue) + }; } public override string GetName(int ordinal) diff --git a/src/Ydb.Sdk/src/Value/YdbValueParser.cs b/src/Ydb.Sdk/src/Value/YdbValueParser.cs index a0edc1a3..228bae00 100644 --- a/src/Ydb.Sdk/src/Value/YdbValueParser.cs +++ b/src/Ydb.Sdk/src/Value/YdbValueParser.cs @@ -1,4 +1,6 @@ -namespace Ydb.Sdk.Value; +using Ydb.Sdk.Ado; + +namespace Ydb.Sdk.Value; public partial class YdbValue { @@ -324,7 +326,7 @@ private void EnsureType(Type.TypeOneofCase expectedType) { if (_protoType.TypeCase != expectedType) { - throw new InvalidTypeException(expectedType.ToString(), TypeId.ToString()); + ThrowHelper.ThrowInvalidCastException(expectedType.ToString(), TypeId.ToString()); } } @@ -332,15 +334,7 @@ private void EnsurePrimitiveTypeId(Type.Types.PrimitiveTypeId primitiveTypeId) { if (_protoType.TypeCase != Type.TypeOneofCase.TypeId || _protoType.TypeId != primitiveTypeId) { - throw new InvalidTypeException(primitiveTypeId.ToString(), TypeId.ToString()); - } - } - - public class InvalidTypeException : InvalidCastException - { - internal InvalidTypeException(string expectedType, string actualType) - : base($"Invalid type of YDB value, expected: {expectedType}, actual: {actualType}.") - { + ThrowHelper.ThrowInvalidCastException(primitiveTypeId.ToString(), TypeId.ToString()); } } } diff --git a/src/Ydb.Sdk/tests/Ado/Specification/YdbConnectionStringBuilderTests.cs b/src/Ydb.Sdk/tests/Ado/Specification/YdbConnectionStringBuilderTests.cs new file mode 100644 index 00000000..9c7edca3 --- /dev/null +++ b/src/Ydb.Sdk/tests/Ado/Specification/YdbConnectionStringBuilderTests.cs @@ -0,0 +1,10 @@ +using AdoNet.Specification.Tests; + +namespace Ydb.Sdk.Tests.Ado.Specification; + +public class YdbConnectionStringBuilderTests : ConnectionStringTestBase +{ + public YdbConnectionStringBuilderTests(YdbFactoryFixture fixture) : base(fixture) + { + } +} diff --git a/src/Ydb.Sdk/tests/Ado/Specification/YdbGetValueConversionTests.cs b/src/Ydb.Sdk/tests/Ado/Specification/YdbGetValueConversionTests.cs new file mode 100644 index 00000000..78d64ffa --- /dev/null +++ b/src/Ydb.Sdk/tests/Ado/Specification/YdbGetValueConversionTests.cs @@ -0,0 +1,796 @@ +using System.Data; +using AdoNet.Specification.Tests; +using Xunit; +using Ydb.Sdk.Ado; + +namespace Ydb.Sdk.Tests.Ado.Specification; + +public class YdbGetValueConversionTests : GetValueConversionTestBase +{ + public YdbGetValueConversionTests(YdbSelectValueFixture fixture) : base(fixture) + { + } + +#pragma warning disable xUnit1004 + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_minimum_UInt16() + { + base.GetInt16_for_minimum_UInt16(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_minimum_UInt16_with_GetFieldValue() + { + base.GetInt16_for_minimum_UInt16_with_GetFieldValue(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override Task GetInt16_for_minimum_UInt16_with_GetFieldValueAsync() + { + return base.GetInt16_for_minimum_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_for_one_Int32() + { + base.GetInt16_for_one_Int32(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_for_one_Int32_with_GetFieldValue() + { + base.GetInt16_for_one_Int32_with_GetFieldValue(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override Task GetInt16_for_one_Int32_with_GetFieldValueAsync() + { + return base.GetInt16_for_one_Int32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_for_one_Int64() + { + base.GetInt16_for_one_Int64(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_for_one_Int64_with_GetFieldValue() + { + base.GetInt16_for_one_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override Task GetInt16_for_one_Int64_with_GetFieldValueAsync() + { + return base.GetInt16_for_one_Int64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_one_UInt16() + { + base.GetInt16_for_one_UInt16(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_one_UInt16_with_GetFieldValue() + { + base.GetInt16_for_one_UInt16_with_GetFieldValue(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override Task GetInt16_for_one_UInt16_with_GetFieldValueAsync() + { + return base.GetInt16_for_one_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_for_zero_Int32() + { + base.GetInt16_for_zero_Int32(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_for_zero_Int32_with_GetFieldValue() + { + base.GetInt16_for_zero_Int32_with_GetFieldValue(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override Task GetInt16_for_zero_Int32_with_GetFieldValueAsync() + { + return base.GetInt16_for_zero_Int32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_for_zero_Int64() + { + base.GetInt16_for_zero_Int64(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_for_zero_Int64_with_GetFieldValue() + { + base.GetInt16_for_zero_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override Task GetInt16_for_zero_Int64_with_GetFieldValueAsync() + { + return base.GetInt16_for_zero_Int64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_zero_UInt16() + { + base.GetInt16_for_zero_UInt16(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_for_zero_UInt16_with_GetFieldValue() + { + base.GetInt16_for_zero_UInt16_with_GetFieldValue(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override Task GetInt16_for_zero_UInt16_with_GetFieldValueAsync() + { + return base.GetInt16_for_zero_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_throws_for_maximum_Int32() + { + base.GetInt16_throws_for_maximum_Int32(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_throws_for_maximum_Int32_with_GetFieldValue() + { + base.GetInt16_throws_for_maximum_Int32_with_GetFieldValue(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override Task GetInt16_throws_for_maximum_Int32_with_GetFieldValueAsync() + { + return base.GetInt16_throws_for_maximum_Int32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_throws_for_maximum_Int64() + { + base.GetInt16_throws_for_maximum_Int64(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_throws_for_maximum_Int64_with_GetFieldValue() + { + base.GetInt16_throws_for_maximum_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override Task GetInt16_throws_for_maximum_Int64_with_GetFieldValueAsync() + { + return base.GetInt16_throws_for_maximum_Int64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_throws_for_maximum_UInt16() + { + base.GetInt16_throws_for_maximum_UInt16(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override void GetInt16_throws_for_maximum_UInt16_with_GetFieldValue() + { + base.GetInt16_throws_for_maximum_UInt16_with_GetFieldValue(); + } + + [Fact(Skip = "Uint16 >> Int16")] + public override Task GetInt16_throws_for_maximum_UInt16_with_GetFieldValueAsync() + { + return base.GetInt16_throws_for_maximum_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_throws_for_minimum_Int32() + { + base.GetInt16_throws_for_minimum_Int32(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override void GetInt16_throws_for_minimum_Int32_with_GetFieldValue() + { + base.GetInt16_throws_for_minimum_Int32_with_GetFieldValue(); + } + + [Fact(Skip = "Int32 >> Int16")] + public override Task GetInt16_throws_for_minimum_Int32_with_GetFieldValueAsync() + { + return base.GetInt16_throws_for_minimum_Int32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_throws_for_minimum_Int64() + { + base.GetInt16_throws_for_minimum_Int64(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt16_throws_for_minimum_Int64_with_GetFieldValue() + { + base.GetInt16_throws_for_minimum_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override Task GetInt16_throws_for_minimum_Int64_with_GetFieldValueAsync() + { + return base.GetInt16_throws_for_minimum_Int64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_maximum_Int16_with_GetFieldValue() + { + base.GetInt32_for_maximum_Int16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_maximum_Int16_with_GetFieldValueAsync() + { + return base.GetInt32_for_maximum_Int16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_maximum_UInt16_with_GetFieldValue() + { + base.GetInt32_for_maximum_UInt16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_maximum_UInt16_with_GetFieldValueAsync() + { + return base.GetInt32_for_maximum_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_minimum_Int16_with_GetFieldValue() + { + base.GetInt32_for_minimum_Int16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_minimum_Int16_with_GetFieldValueAsync() + { + return base.GetInt32_for_minimum_Int16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_minimum_UInt16_with_GetFieldValue() + { + base.GetInt32_for_minimum_Int16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_minimum_UInt16_with_GetFieldValueAsync() + { + return base.GetInt32_for_minimum_UInt16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override void GetInt32_for_minimum_UInt32() + { + base.GetInt32_for_minimum_UInt32(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override void GetInt32_for_minimum_UInt32_with_GetFieldValue() + { + base.GetInt32_for_minimum_UInt32_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int16")] + public override Task GetInt32_for_minimum_UInt32_with_GetFieldValueAsync() + { + return base.GetInt32_for_minimum_UInt32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Int64 >> Int32")] + public override void GetInt32_for_one_Int64() + { + base.GetInt16_for_one_Int64(); + } + + [Fact(Skip = "Int64 >> Int32")] + public override void GetInt32_for_one_Int64_with_GetFieldValue() + { + base.GetInt32_for_one_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Int64 >> Int32")] + public override Task GetInt32_for_one_Int64_with_GetFieldValueAsync() + { + return base.GetInt32_for_one_Int64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override void GetInt32_for_one_UInt32() + { + base.GetInt32_for_one_UInt32(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override void GetInt32_for_one_UInt32_with_GetFieldValue() + { + base.GetInt32_for_one_UInt32_with_GetFieldValue(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override Task GetInt32_for_one_UInt32_with_GetFieldValueAsync() + { + return base.GetInt32_for_one_UInt32_with_GetFieldValueAsync(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_throws_for_maximum_UInt64() + { + base.GetInt64_throws_for_maximum_UInt64(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_throws_for_maximum_UInt64_with_GetFieldValue() + { + base.GetInt64_throws_for_maximum_UInt64_with_GetFieldValue(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override Task GetInt64_throws_for_maximum_UInt64_with_GetFieldValueAsync() + { + return base.GetInt64_throws_for_maximum_UInt64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_zero_UInt64() + { + base.GetInt64_for_zero_UInt64(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_zero_UInt64_with_GetFieldValue() + { + base.GetInt64_for_zero_UInt64_with_GetFieldValue(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override Task GetInt64_for_zero_UInt64_with_GetFieldValueAsync() + { + return base.GetInt64_for_zero_UInt64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_one_UInt64() + { + base.GetInt64_for_one_UInt64(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_one_UInt64_with_GetFieldValue() + { + base.GetInt64_for_one_UInt64_with_GetFieldValue(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override Task GetInt64_for_one_UInt64_with_GetFieldValueAsync() + { + return base.GetInt64_for_one_UInt64_with_GetFieldValueAsync(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_minimum_UInt64() + { + base.GetInt64_for_minimum_UInt64(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override void GetInt64_for_minimum_UInt64_with_GetFieldValue() + { + base.GetInt64_for_minimum_UInt64_with_GetFieldValue(); + } + + [Fact(Skip = "UInt64 >> Int64")] + public override Task GetInt64_for_minimum_UInt64_with_GetFieldValueAsync() + { + return base.GetInt64_for_minimum_UInt64_with_GetFieldValueAsync(); + } + + public override void GetInt32_throws_for_maximum_Int64() + { + TestException(DbType.Int64, ValueKind.Maximum, x => x.GetInt32(0), typeof(InvalidCastException)); + } + + public override void GetInt32_for_zero_Int64() + { + TestException(DbType.Int64, ValueKind.Zero, x => x.GetInt32(0), typeof(InvalidCastException)); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override void GetInt32_for_zero_UInt32() + { + base.GetInt32_for_zero_UInt32(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override void GetInt32_for_zero_UInt32_with_GetFieldValue() + { + base.GetInt32_for_zero_UInt32_with_GetFieldValue(); + } + + [Fact(Skip = "Uint32 >> Int32")] + public override Task GetInt32_for_zero_UInt32_with_GetFieldValueAsync() + { + return base.GetInt32_for_zero_UInt32_with_GetFieldValueAsync(); + } + + public override void GetInt32_throws_for_maximum_UInt32() + { + TestException(DbType.UInt32, ValueKind.Maximum, x => x.GetInt32(0), typeof(InvalidCastException)); + } + + public override void GetInt32_throws_for_maximum_UInt32_with_GetFieldValue() + { + TestException(DbType.UInt32, ValueKind.Maximum, x => x.GetFieldValue(0), typeof(InvalidCastException)); + } + + public override async Task GetInt32_throws_for_maximum_UInt32_with_GetFieldValueAsync() + { + await TestExceptionAsync(DbType.UInt32, ValueKind.Maximum, async x => await x.GetFieldValueAsync(0), + typeof(InvalidCastException)); + } + + public override Task GetInt32_throws_for_maximum_Int64_with_GetFieldValueAsync() + { + return TestExceptionAsync(DbType.Int64, ValueKind.Maximum, async x => await x.GetFieldValueAsync(0), + typeof(InvalidCastException)); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_one_Int16_with_GetFieldValue() + { + TestGetValue(DbType.Int16, ValueKind.One, x => x.GetFieldValue(0), 1); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_one_Int16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int16, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_one_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.One, x => x.GetFieldValue(0), 1); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_one_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_zero_Int16_with_GetFieldValue() + { + base.GetInt32_for_zero_Int16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_zero_Int16_with_GetFieldValueAsync() + { + return base.GetInt32_for_zero_Int16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_zero_Int64_with_GetFieldValue() + { + base.GetInt32_for_zero_Int64_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_zero_Int64_with_GetFieldValueAsync() + { + return base.GetInt32_for_zero_Int64_with_GetFieldValueAsync(); + } + + public override void GetInt32_throws_for_minimum_Int64() + { + TestException(DbType.Int64, ValueKind.Minimum, x => x.GetInt32(0), typeof(InvalidCastException)); + } + + public override void GetInt32_throws_for_minimum_Int64_with_GetFieldValue() + { + TestException(DbType.Int64, ValueKind.Minimum, x => x.GetFieldValue(0), typeof(InvalidCastException)); + } + + public override Task GetInt32_throws_for_minimum_Int64_with_GetFieldValueAsync() + { + return TestExceptionAsync(DbType.Int64, ValueKind.Minimum, async x => await x.GetFieldValueAsync(0), + typeof(InvalidCastException)); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt32_for_zero_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.Zero, x => x.GetFieldValue(0), 0); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt32_for_zero_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.Zero, async x => await x.GetFieldValueAsync(0), 0); + } + + public override void GetInt32_throws_for_maximum_Int64_with_GetFieldValue() + { + TestException(DbType.Int64, ValueKind.Maximum, x => x.GetFieldValue(0), typeof(InvalidCastException)); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_maximum_Int16_with_GetFieldValue() + { + base.GetInt64_for_maximum_Int16_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_maximum_Int16_with_GetFieldValueAsync() + { + return base.GetInt64_for_maximum_Int16_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_maximum_Int32_with_GetFieldValue() + { + TestGetValue(DbType.Int32, ValueKind.Maximum, x => x.GetFieldValue(0), 2147483647L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_maximum_Int32_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int32, ValueKind.Maximum, async x => await x.GetFieldValueAsync(0), + 2147483647L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_maximum_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.Maximum, x => x.GetFieldValue(0), 65535L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_maximum_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.Maximum, async x => await x.GetFieldValueAsync(0), + 65535L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_minimum_Int16_with_GetFieldValue() + { + TestGetValue(DbType.Int16, ValueKind.Minimum, x => x.GetFieldValue(0), -32768L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_minimum_Int16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int16, ValueKind.Minimum, async x => await x.GetFieldValueAsync(0), + -32768L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_minimum_Int32_with_GetFieldValue() + { + TestGetValue(DbType.Int32, ValueKind.Minimum, x => x.GetFieldValue(0), -2147483648L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_minimum_Int32_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int32, ValueKind.Minimum, async x => await x.GetFieldValueAsync(0), + -2147483648L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_minimum_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.Minimum, x => x.GetFieldValue(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_minimum_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.Minimum, async x => await x.GetFieldValueAsync(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_one_Int16_with_GetFieldValue() + { + TestGetValue(DbType.Int16, ValueKind.One, x => x.GetFieldValue(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_one_Int16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int16, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_one_Int32_with_GetFieldValue() + { + TestGetValue(DbType.Int32, ValueKind.One, x => x.GetFieldValue(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_one_Int32_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int32, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_one_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.One, x => x.GetFieldValue(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_one_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_zero_Int16_with_GetFieldValue() + { + TestGetValue(DbType.Int16, ValueKind.Zero, x => x.GetFieldValue(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_zero_Int16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int16, ValueKind.Zero, async x => await x.GetFieldValueAsync(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_zero_Int32_with_GetFieldValue() + { + TestGetValue(DbType.Int32, ValueKind.Zero, x => x.GetFieldValue(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_zero_Int32_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Int32, ValueKind.Zero, async x => await x.GetFieldValueAsync(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetInt64_for_zero_UInt16_with_GetFieldValue() + { + TestGetValue(DbType.UInt16, ValueKind.Zero, x => x.GetFieldValue(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetInt64_for_zero_UInt16_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.UInt16, ValueKind.Zero, async x => await x.GetFieldValueAsync(0), 0L); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetDouble_for_zero_Single_with_GetFieldValueAsync() + { + return base.GetDouble_for_zero_Single_with_GetFieldValueAsync(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetDouble_for_zero_Single_with_GetFieldValue() + { + base.GetDouble_for_zero_Single_with_GetFieldValue(); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetDouble_for_maximum_Single_with_GetFieldValue() + { + TestGetValue(DbType.Single, ValueKind.Maximum, x => x.GetFieldValue(0), 3.3999999521443642E+38); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetDouble_for_maximum_Single_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Single, ValueKind.Maximum, async x => await x.GetFieldValueAsync(0), + 3.3999999521443642E+38); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetDouble_for_one_Single_with_GetFieldValue() + { + TestGetValue(DbType.Single, ValueKind.One, x => x.GetFieldValue(0), 1.0); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetDouble_for_one_Single_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Single, ValueKind.One, async x => await x.GetFieldValueAsync(0), 1.0); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override void GetDouble_for_minimum_Single_with_GetFieldValue() + { + TestGetValue(DbType.Single, ValueKind.Minimum, x => x.GetFieldValue(0), 1.1799999457746311E-38); + } + + [Fact(Skip = "Method GetFieldValue is not fully supported")] + public override Task GetDouble_for_minimum_Single_with_GetFieldValueAsync() + { + return TestGetValueAsync(DbType.Single, ValueKind.Minimum, async x => await x.GetFieldValueAsync(0), + 1.1799999457746311E-38); + } + +#pragma warning restore xUnit1004 + protected override async Task OnInitializeAsync() + { + await using var connection = CreateConnection(); + connection.ConnectionString = ConnectionString; + await connection.OpenAsync(); + + var ydbCommand = new YdbCommand + { + Connection = connection, + CommandText = $@" + CREATE TABLE `select_value_{Utils.Net}` + ( + `Id` Int32 NOT NULL, + `Binary` Bytes, + `Boolean` Bool, + `Byte` Uint8, + `SByte` Int8, + `Int16` Int16, + `UInt16` UInt16, + `Int32` Int32, + `UInt32` UInt32, + `Int64` Int64, + `UInt64` UInt64, + `Single` Float, + `Double` Double, + `Decimal` Decimal(22, 9), + `String` Text, + `Guid` Uuid, + `Date` Date, + `DateTime` Datetime, + `DateTime2` Timestamp, + + PRIMARY KEY (`Id`) + ); + " + }; + + await ydbCommand.ExecuteNonQueryAsync(); + ydbCommand.CommandText = $@" + INSERT INTO `select_value_{Utils.Net}`(`Id`, `Binary`, `Boolean`, `Byte`, `SByte`, `Int16`, `UInt16`,`Int32`, + `UInt32`, `Int64`, `UInt64`, `Single`, `Double`, `Decimal`, `String`, `Guid`, `Date`, `DateTime`, `DateTime2`) VALUES + (0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), + (1, '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', NULL, NULL, NULL, NULL), + (2, String::HexDecode('00'), FALSE, 0, 0, 0, 0, 0, 0, 0, 0, CAST(0 AS Float), 0, CAST(0 AS Decimal(22, 9)), '0', Uuid('00000000-0000-0000-0000-000000000000'), NULL, NULL, CurrentUtcTimestamp()), + (3, String::HexDecode('11'), TRUE, 1, 1, 1, 1, 1, 1, 1, 1, CAST(1 AS Float), 1, CAST(1 AS Decimal(22, 9)), '1', Uuid('11111111-1111-1111-1111-111111111111'), Date('2105-01-01'), Datetime('2105-01-01T11:11:11Z'), Timestamp('2105-01-01T11:11:11.111Z')), + (4, NULL, FALSE, 0, -128, -32768, 0, -2147483648, 0, -9223372036854775808, 0, CAST(1.18e-38 AS Float), 2.23e-308, CAST('0.000000000000001' AS Decimal(22, 9)), NULL, Uuid('33221100-5544-7766-9988-aabbccddeeff'), Date('2000-01-01'), Datetime('2000-01-01T00:00:00Z'), Timestamp('2000-01-01T00:00:00.000Z')), + (5, NULL, TRUE, 255, 127, 32767, 65535, 2147483647, 4294967295, 9223372036854775807, 18446744073709551615, CAST(3.40e38 AS Float), 1.79e308, CAST('99999999999999999999.999999999' AS Decimal(22, 9)), NULL, Uuid('ccddeeff-aabb-8899-7766-554433221100'), Date('1999-12-31'), Datetime('1999-12-31T23:59:59Z'), Timestamp('1999-12-31T23:59:59.999Z')); + "; + await ydbCommand.ExecuteNonQueryAsync(); + } + + protected override async Task OnDisposeAsync() + { + await using var connection = CreateConnection(); + connection.ConnectionString = ConnectionString; + await connection.OpenAsync(); + + await new YdbCommand { Connection = connection, CommandText = $"DROP TABLE `select_value_{Utils.Net}`" } + .ExecuteNonQueryAsync(); + } +} diff --git a/src/Ydb.Sdk/tests/Ado/Specification/YdbSelectValueFixture.cs b/src/Ydb.Sdk/tests/Ado/Specification/YdbSelectValueFixture.cs index 4a36856f..964de6ef 100644 --- a/src/Ydb.Sdk/tests/Ado/Specification/YdbSelectValueFixture.cs +++ b/src/Ydb.Sdk/tests/Ado/Specification/YdbSelectValueFixture.cs @@ -21,9 +21,9 @@ public string CreateSelectSql(byte[] value) DbType.Binary, DbType.Boolean, DbType.Byte, - DbType.Date, - DbType.DateTime, - DbType.Decimal, + // DbType.Date, + // DbType.DateTime, + // DbType.Decimal, DbType.Double, DbType.Guid, DbType.Int16, @@ -32,7 +32,7 @@ public string CreateSelectSql(byte[] value) DbType.SByte, DbType.Single, DbType.String, - DbType.DateTime2, + // DbType.DateTime2, DbType.UInt16, DbType.UInt32, DbType.UInt64