Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Restore
run: dotnet restore ${{ matrix.source-dir }}${{ matrix.solutionFile }}
- name: Install ReSharper
run: dotnet tool install -g JetBrains.ReSharper.GlobalTools
run: dotnet tool install -g JetBrains.ReSharper.GlobalTools --version 2025.2.1
- name: format all files with auto-formatter
run: bash ./.github/scripts/format-all-dotnet-code.sh ${{ matrix.source-dir }} ${{ matrix.solutionFile }}
- name: Check repository diff
Expand Down Expand Up @@ -63,6 +63,7 @@ jobs:
**.cshtml
minimumReportSeverity: WARNING
dotnetVersion: ${{ steps.setup-dotnet.outputs.dotnet-version }}
version: 2025.2.1
ignoreIssueType: |
UnusedField.Compiler,
UnusedVariable.Compiler,
Expand Down
2 changes: 2 additions & 0 deletions src/Ydb.Sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- Feat ADO.NET: Added YSON type support (YdbDbType.Yson) with byte[] values.

## v0.23.0

- Feat ADO.NET: `YdbDataSource.OpenRetryableConnectionAsync` opens a retryable connection with automatic retries for transient failures.
Expand Down
3 changes: 3 additions & 0 deletions src/Ydb.Sdk/src/Ado/Internal/YdbTypedValueExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ internal static TypedValue Decimal(this decimal value, byte precision, byte scal
internal static TypedValue Bytes(this byte[] value) => MakePrimitiveTypedValue(Type.Types.PrimitiveTypeId.String,
new Ydb.Value { BytesValue = ByteString.CopyFrom(value) });

internal static TypedValue Yson(this byte[] value) => MakePrimitiveTypedValue(Type.Types.PrimitiveTypeId.Yson,
new Ydb.Value { BytesValue = ByteString.CopyFrom(value) });

internal static TypedValue Json(this string value) => MakeText(Type.Types.PrimitiveTypeId.Json, value);

internal static TypedValue JsonDocument(this string value) =>
Expand Down
2 changes: 2 additions & 0 deletions src/Ydb.Sdk/src/Ado/Internal/YdbValueExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ internal static TimeSpan GetInterval64(this Ydb.Value value) =>

internal static byte[] GetBytes(this Ydb.Value value) => value.BytesValue.ToByteArray();

internal static byte[] GetYson(this Ydb.Value value) => value.BytesValue.ToByteArray();

internal static string GetText(this Ydb.Value value) => value.TextValue;

internal static string GetJson(this Ydb.Value value) => value.TextValue;
Expand Down
6 changes: 5 additions & 1 deletion src/Ydb.Sdk/src/Ado/YdbDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ public override byte GetByte(int ordinal) =>

public byte[] GetBytes(int ordinal) => GetPrimitiveValue(Type.Types.PrimitiveTypeId.String, ordinal).GetBytes();

public byte[] GetYson(int ordinal) => GetPrimitiveValue(Type.Types.PrimitiveTypeId.Yson, ordinal).GetYson();

public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int bufferOffset, int length)
{
var bytes = GetBytes(ordinal);
Expand Down Expand Up @@ -281,6 +283,7 @@ or Type.Types.PrimitiveTypeId.Timestamp
or Type.Types.PrimitiveTypeId.JsonDocument
or Type.Types.PrimitiveTypeId.Json => typeof(string),
Type.Types.PrimitiveTypeId.String => typeof(byte[]),
Type.Types.PrimitiveTypeId.Yson => typeof(byte[]),
Type.Types.PrimitiveTypeId.Uuid => typeof(Guid),
_ => throw new YdbException($"Unsupported ydb type {type}")
};
Expand Down Expand Up @@ -440,6 +443,7 @@ public override object GetValue(int ordinal)
Type.Types.PrimitiveTypeId.Utf8 => ydbValue.GetText(),
Type.Types.PrimitiveTypeId.Json => ydbValue.GetJson(),
Type.Types.PrimitiveTypeId.JsonDocument => ydbValue.GetJsonDocument(),
Type.Types.PrimitiveTypeId.Yson => ydbValue.GetYson(),
Type.Types.PrimitiveTypeId.String => ydbValue.GetBytes(),
Type.Types.PrimitiveTypeId.Uuid => ydbValue.GetUuid(),
_ => throw new YdbException($"Unsupported ydb type {GetColumnType(ordinal)}")
Expand Down Expand Up @@ -707,7 +711,7 @@ private class Metadata : IMetadata
public Metadata(ResultSet resultSet)
{
Columns = resultSet.Columns;
ColumnNameToOrdinal = ColumnNameToOrdinal = Columns
ColumnNameToOrdinal = Columns
.Select((c, idx) => (c.Name, Index: idx))
.ToDictionary(t => t.Name, t => t.Index);
RowsCount = resultSet.Rows.Count;
Expand Down
9 changes: 9 additions & 0 deletions src/Ydb.Sdk/src/Ado/YdbParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public sealed class YdbParameter : DbParameter
{ YdbDbType.Float, Type.Types.PrimitiveTypeId.Float.Null() },
{ YdbDbType.Double, Type.Types.PrimitiveTypeId.Double.Null() },
{ YdbDbType.Uuid, Type.Types.PrimitiveTypeId.Uuid.Null() },
{ YdbDbType.Yson, Type.Types.PrimitiveTypeId.Yson.Null() },
{ YdbDbType.Json, Type.Types.PrimitiveTypeId.Json.Null() },
{ YdbDbType.JsonDocument, Type.Types.PrimitiveTypeId.JsonDocument.Null() },
{ YdbDbType.Date32, Type.Types.PrimitiveTypeId.Date32.Null() },
Expand Down Expand Up @@ -155,6 +156,7 @@ internal TypedValue TypedValue
YdbDbType.Double => MakeDouble(value),
YdbDbType.Decimal when value is decimal decimalValue => Decimal(decimalValue),
YdbDbType.Bytes => MakeBytes(value),
YdbDbType.Yson => MakeYson(value),
YdbDbType.Json when value is string stringValue => stringValue.Json(),
YdbDbType.JsonDocument when value is string stringValue => stringValue.JsonDocument(),
YdbDbType.Uuid when value is Guid guidValue => guidValue.Uuid(),
Expand Down Expand Up @@ -240,6 +242,13 @@ internal TypedValue TypedValue
_ => throw ValueTypeNotSupportedException
};

private TypedValue MakeYson(object value) => value switch
{
byte[] bytesValue => bytesValue.Yson(),
MemoryStream memoryStream => memoryStream.ToArray().Yson(),
_ => throw ValueTypeNotSupportedException
};

private TypedValue MakeDate(object value) => value switch
{
DateTime dateTimeValue => dateTimeValue.Date(),
Expand Down
8 changes: 8 additions & 0 deletions src/Ydb.Sdk/src/Ado/YdbType/YdbDbType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ public enum YdbDbType
/// </remarks>
Text,

/// <summary>
/// YSON in binary form (passed/returned as byte[]).
/// </summary>
/// <remarks>
/// Can't be used in the primary key.
/// </remarks>
Yson,

/// <summary>
/// JSON represented as text.
/// </summary>
Expand Down
13 changes: 8 additions & 5 deletions src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbParameterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ CustomDecimalColumn Decimal(35, 5) NOT NULL,
IntervalColumn Interval NOT NULL,
JsonColumn Json NOT NULL,
JsonDocumentColumn JsonDocument NOT NULL,
YsonColumn Yson NOT NULL,
Date32Column Date32 NOT NULL,
Datetime64Column DateTime64 NOT NULL,
Timestamp64Column Timestamp64 NOT NULL,
Expand All @@ -359,13 +360,13 @@ PRIMARY KEY (Int32Column)
Int32Column, BoolColumn, Int64Column, Int16Column, Int8Column, FloatColumn, DoubleColumn,
DefaultDecimalColumn, CustomDecimalColumn, Uint8Column, Uint16Column, Uint32Column,
Uint64Column, TextColumn, BytesColumn, DateColumn, DatetimeColumn, TimestampColumn,
IntervalColumn, JsonColumn, JsonDocumentColumn, Date32Column, Datetime64Column,
IntervalColumn, JsonColumn, JsonDocumentColumn, YsonColumn, Date32Column, Datetime64Column,
Timestamp64Column, Interval64Column
) VALUES (
@Int32Column, @BoolColumn, @Int64Column, @Int16Column, @Int8Column, @FloatColumn,
@DoubleColumn, @DefaultDecimalColumn, @CustomDecimalColumn, @Uint8Column, @Uint16Column,
@Uint32Column, @Uint64Column, @TextColumn, @BytesColumn, @DateColumn, @DatetimeColumn,
@TimestampColumn, @IntervalColumn, @JsonColumn, @JsonDocumentColumn, @Date32Column,
@TimestampColumn, @IntervalColumn, @JsonColumn, @JsonDocumentColumn, @YsonColumn, @Date32Column,
@Datetime64Column, @Timestamp64Column, @Interval64Column
);
""",
Expand All @@ -392,6 +393,7 @@ PRIMARY KEY (Int32Column)
new YdbParameter("IntervalColumn", YdbDbType.Interval, TimeSpan.Zero),
new YdbParameter("JsonColumn", YdbDbType.Json, "{}"),
new YdbParameter("JsonDocumentColumn", YdbDbType.JsonDocument, "{}"),
new YdbParameter("YsonColumn", YdbDbType.Yson, "{a=1u}"u8.ToArray()),
new YdbParameter("Date32Column", YdbDbType.Date32, DateTime.MinValue),
new YdbParameter("Datetime64Column", YdbDbType.Datetime64, DateTime.MinValue),
new YdbParameter("Timestamp64Column", YdbDbType.Timestamp64, DateTime.MinValue),
Expand All @@ -407,7 +409,7 @@ PRIMARY KEY (Int32Column)
Int32Column, BoolColumn, Int64Column, Int16Column, Int8Column, FloatColumn, DoubleColumn,
DefaultDecimalColumn, CustomDecimalColumn, Uint8Column, Uint16Column, Uint32Column,
Uint64Column, TextColumn, BytesColumn, DateColumn, DatetimeColumn, TimestampColumn,
IntervalColumn, JsonColumn, JsonDocumentColumn, Date32Column, Datetime64Column,
IntervalColumn, JsonColumn, JsonDocumentColumn, YsonColumn, Date32Column, Datetime64Column,
Timestamp64Column, Interval64Column
FROM {tableName};
"""
Expand Down Expand Up @@ -435,10 +437,11 @@ PRIMARY KEY (Int32Column)
Assert.Equal(TimeSpan.Zero, ydbDataReader.GetInterval(18));
Assert.Equal("{}", ydbDataReader.GetJson(19));
Assert.Equal("{}", ydbDataReader.GetJsonDocument(20));
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(21));
Assert.Equal("{a=1u}"u8.ToArray(), ydbDataReader.GetYson(21));
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(22));
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(23));
Assert.Equal(TimeSpan.FromMilliseconds(TimeSpan.MinValue.Milliseconds), ydbDataReader.GetInterval(24));
Assert.Equal(DateTime.MinValue, ydbDataReader.GetDateTime(24));
Assert.Equal(TimeSpan.FromMilliseconds(TimeSpan.MinValue.Milliseconds), ydbDataReader.GetInterval(25));
Assert.False(ydbDataReader.Read());
await ydbDataReader.CloseAsync();

Expand Down
7 changes: 5 additions & 2 deletions src/Ydb.Sdk/test/Ydb.Sdk.Ado.Tests/YdbSchemaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ public async Task GetSchema_WhenAllTypesTable_ReturnAllTypes()
var dataTable = await ydbConnection.GetSchemaAsync("Columns", [_allTypesTable, null]);
var dataTableNullable = await ydbConnection.GetSchemaAsync("Columns", [_allTypesTableNullable, null]);

Assert.Equal(17, dataTable.Rows.Count);
Assert.Equal(17, dataTableNullable.Rows.Count);
Assert.Equal(18, dataTable.Rows.Count);
Assert.Equal(18, dataTableNullable.Rows.Count);

CheckAllColumns(dataTable, false);
CheckAllColumns(dataTableNullable, true);
Expand All @@ -202,6 +202,7 @@ void CheckAllColumns(DataTable pDataTable, bool isNullableTable)
CheckColumn(pDataTable.Rows[14], "DateColumn", 14, isNullableTable);
CheckColumn(pDataTable.Rows[15], "DatetimeColumn", 15, isNullableTable);
CheckColumn(pDataTable.Rows[16], "TimestampColumn", 16, isNullableTable);
CheckColumn(pDataTable.Rows[17], "YsonColumn", 17, isNullableTable, "Yson");
}

void CheckColumn(DataRow column, string columnName, int ordinal, bool isNullable, string? dataType = null)
Expand Down Expand Up @@ -243,6 +244,7 @@ DefaultDecimalColumn Decimal(22,9) NOT NULL,
DateColumn Date NOT NULL,
DatetimeColumn Datetime NOT NULL,
TimestampColumn Timestamp NOT NULL,
YsonColumn Yson NOT NULL,
PRIMARY KEY (Int32Column)
);

Expand All @@ -264,6 +266,7 @@ DefaultDecimalColumn Decimal(22,9),
DateColumn Date,
DatetimeColumn Datetime,
TimestampColumn Timestamp,
YsonColumn Yson,
PRIMARY KEY (Int32Column)
);
"""
Expand Down
Loading