Skip to content

Commit 314a874

Browse files
feat: generate DECLARE AS (#183)
1 parent 9b69b30 commit 314a874

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

src/Ydb.Sdk/src/Ado/YdbCommand.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Data;
22
using System.Data.Common;
3+
using System.Text;
4+
using Ydb.Sdk.Ado.Internal;
35
using Ydb.Sdk.Services.Query;
46

57
namespace Ydb.Sdk.Ado;
@@ -171,12 +173,30 @@ protected override async Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBeha
171173
throw new YdbOperationInProgressException(YdbConnection);
172174
}
173175

176+
var ydbParameters = DbParameterCollection.YdbParameters;
177+
var (sql, paramNames) = SqlParser.Parse(CommandText);
178+
var preparedSql = new StringBuilder();
179+
180+
foreach (var paramName in paramNames)
181+
{
182+
if (ydbParameters.TryGetValue(paramName, out var ydbValue))
183+
{
184+
preparedSql.Append($"DECLARE {paramName} AS {ydbValue.ToYql()};\n");
185+
}
186+
else
187+
{
188+
throw new YdbException($"Not found YDB parameter [name: {paramName}]");
189+
}
190+
}
191+
192+
preparedSql.Append(sql);
193+
174194
var execSettings = CommandTimeout > 0
175195
? new ExecuteQuerySettings { TransportTimeout = TimeSpan.FromSeconds(CommandTimeout) }
176196
: ExecuteQuerySettings.DefaultInstance;
177197

178198
var ydbDataReader = await YdbDataReader.CreateYdbDataReader(YdbConnection.Session.ExecuteQuery(
179-
_commandText, DbParameterCollection.YdbParameters, execSettings, Transaction?.TransactionControl),
199+
preparedSql.ToString(), ydbParameters, execSettings, Transaction?.TransactionControl),
180200
YdbConnection.Session.OnStatus, Transaction);
181201

182202
YdbConnection.LastReader = ydbDataReader;

src/Ydb.Sdk/src/Value/YdbValue.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,9 @@ internal YdbValue(Type type, Ydb.Value value)
5656
{
5757
_protoType = type;
5858
_protoValue = value;
59-
60-
TypeId = GetYdbTypeId(type);
6159
}
6260

63-
public YdbTypeId TypeId { get; }
61+
public YdbTypeId TypeId => GetYdbTypeId(_protoType);
6462

6563
public TypedValue GetProto()
6664
{
@@ -76,6 +74,24 @@ public override string ToString()
7674
return _protoValue.ToString() ?? "";
7775
}
7876

77+
internal string ToYql()
78+
{
79+
return ToYql(_protoType);
80+
}
81+
82+
private static string ToYql(Type type)
83+
{
84+
return type.TypeCase switch
85+
{
86+
Type.TypeOneofCase.TypeId => type.TypeId.ToString(),
87+
Type.TypeOneofCase.DecimalType => "Decimal(22, 9)",
88+
Type.TypeOneofCase.OptionalType => $"{ToYql(type.OptionalType.Item)}?",
89+
Type.TypeOneofCase.ListType => $"List<{ToYql(type.ListType.Item)}>",
90+
Type.TypeOneofCase.VoidType => "Void",
91+
_ => "Unknown"
92+
};
93+
}
94+
7995
internal static YdbTypeId GetYdbTypeId(Type protoType)
8096
{
8197
return protoType.TypeCase switch

src/Ydb.Sdk/tests/Ado/YdbCommandTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,30 @@ public async Task ExecuteScalarAsync_WhenSetYdbParameter_ReturnThisValue<T>(YdbP
4343
}
4444
}
4545

46+
[Theory]
47+
[ClassData(typeof(YdbParameterTests.TestDataGenerator))]
48+
public async Task ExecuteScalarAsync_WhenSetYdbParameterThenPrepare_ReturnThisValue<T>(
49+
YdbParameterTests.Data<T> data)
50+
{
51+
await using var connection = new YdbConnection();
52+
await connection.OpenAsync();
53+
54+
var dbCommand = connection.CreateCommand();
55+
56+
dbCommand.CommandText = "SELECT @var;";
57+
58+
var dbParameter = new YdbParameter
59+
{
60+
ParameterName = "@var",
61+
DbType = data.DbType,
62+
Value = data.Expected,
63+
IsNullable = data.IsNullable
64+
};
65+
dbCommand.Parameters.Add(dbParameter);
66+
67+
Assert.Equal(data.Expected, await dbCommand.ExecuteScalarAsync());
68+
}
69+
4670
[Fact]
4771
public async Task ExecuteNonQueryAsync_WhenCreateUser_ReturnEmptyResultSet()
4872
{

0 commit comments

Comments
 (0)