Skip to content

Commit 726c00b

Browse files
committed
feat: make YdbList struct-only builder for List<Struct<...>>; remove plain mode
1 parent 2573547 commit 726c00b

File tree

6 files changed

+170
-215
lines changed

6 files changed

+170
-215
lines changed

src/Ydb.Sdk/src/Ado/BulkUpsert/BulkUpsertImporter.cs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,51 +31,58 @@ internal BulkUpsertImporter(
3131
_cancellationToken = cancellationToken;
3232
}
3333

34-
/// <summary>Adds one line to the current BulkUpsert batch.</summary>
35-
/// <param name="values">Column values are in array order <c>columns</c>.</param>
36-
/// <remarks>Types: <see cref="YdbValue"/> / <see cref="YdbParameter"/> / <see cref="YdbList"/> — as is; others are displayed.</remarks>
37-
/// <example><code>// columns: ["Id","Name"]
34+
/// <summary>
35+
/// Add a single row to the current BulkUpsert batch.
36+
/// </summary>
37+
/// <param name="values">Column values in the same order as the configured <c>columns</c>.</param>
38+
/// <remarks>
39+
/// Supported element types: <see cref="YdbValue"/>, <see cref="YdbParameter"/>, <see cref="YdbList"/> (as-is);
40+
/// other CLR values are converted via <see cref="YdbParameter"/>.
41+
/// </remarks>
42+
/// <example>
43+
/// <code>
44+
/// // columns: ["Id", "Name"]
3845
/// await importer.AddRowAsync(1, "Alice");
39-
/// </code></example>
40-
/// <exception cref="ArgumentException">The number of values is not equal to the number of columns.</exception>
41-
/// <exception cref="InvalidOperationException">The value cannot be compared with the YDB type.</exception>
46+
/// </code>
47+
/// </example>
48+
/// <exception cref="ArgumentException">When the number of values doesn't equal the number of columns.</exception>
49+
/// <exception cref="InvalidOperationException">When a value cannot be mapped to a YDB type.</exception>
4250
public async ValueTask AddRowAsync(params object[] values)
4351
{
4452
if (values.Length != _columns.Count)
45-
throw new ArgumentException("Values count must match columns count", nameof(values));
53+
throw new ArgumentException("Values count must match columns count.", nameof(values));
4654

4755
var ydbValues = values.Select(v => v switch
48-
{
49-
YdbValue ydbValue => ydbValue.GetProto(),
50-
YdbParameter param => param.TypedValue,
51-
YdbList list => list.ToTypedValue(),
52-
_ => new YdbParameter { Value = v }.TypedValue
53-
}
54-
).ToArray();
56+
{
57+
YdbValue ydbValue => ydbValue.GetProto(),
58+
YdbParameter param => param.TypedValue,
59+
YdbList list => list.ToTypedValue(),
60+
_ => new YdbParameter { Value = v }.TypedValue
61+
}).ToArray();
5562

5663
var protoStruct = new Ydb.Value();
57-
foreach (var value in ydbValues) protoStruct.Items.Add(value.Value);
64+
foreach (var value in ydbValues)
65+
protoStruct.Items.Add(value.Value);
5866

5967
var rowSize = protoStruct.CalculateSize();
6068

6169
if (_currentBytes + rowSize > _maxBatchByteSize && _rows.Count > 0)
62-
{
6370
await FlushAsync();
64-
}
6571

6672
_rows.Add(protoStruct);
6773
_currentBytes += rowSize;
6874

6975
_structType ??= new StructType
70-
{ Members = { _columns.Select((col, i) => new StructMember { Name = col, Type = ydbValues[i].Type }) } };
76+
{
77+
Members = { _columns.Select((col, i) => new StructMember { Name = col, Type = ydbValues[i].Type }) }
78+
};
7179
}
72-
80+
7381
/// <summary>
74-
/// Adds a set of strings in the form <see cref="YdbList"/>.
82+
/// Add multiple rows from a single <see cref="YdbList"/> parameter.
7583
/// </summary>
7684
/// <remarks>
77-
/// The expected value is of the type <c>List&lt;Struct&lt;...&gt;&gt;</c>. Names and order of fields <c>Struct</c>
78-
/// they must exactly match the array <c>columns</c> passed when creating the importer..
85+
/// Expects <c>List&lt;Struct&lt;...&gt;&gt;</c>; struct member names and order must exactly match the configured <c>columns</c>.
7986
/// Example: <c>columns=["Id","Name"]</c> → <c>List&lt;Struct&lt;Id:Int64, Name:Utf8&gt;&gt;</c>.
8087
/// </remarks>
8188
public async ValueTask AddListAsync(YdbList list)
@@ -120,9 +127,14 @@ public async ValueTask AddListAsync(YdbList list)
120127
}
121128
}
122129

130+
/// <summary>
131+
/// Flush the current batch via BulkUpsert. No-op if the batch is empty.
132+
/// </summary>
123133
public async ValueTask FlushAsync()
124134
{
125-
if (_rows.Count == 0) return;
135+
if (_rows.Count == 0)
136+
return;
137+
126138
if (_structType == null)
127139
throw new InvalidOperationException("structType is undefined");
128140

src/Ydb.Sdk/src/Ado/BulkUpsert/IBulkUpsertImporter.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ namespace Ydb.Sdk.Ado.BulkUpsert;
44

55
public interface IBulkUpsertImporter
66
{
7-
/// <summary>Adds one line to the batch.</summary>
8-
/// <param name="row">The column values are in order <c>columns</c>.</param>
7+
/// <summary>Add a single row to the batch. Values must match the importer column order.</summary>
8+
/// <param name="row">Column values in the same order as the configured <c>columns</c>.</param>
99
ValueTask AddRowAsync(params object[] row);
10-
10+
1111
/// <summary>
12-
/// Adds multiple lines with a single parameter <see cref="YdbList"/>.
12+
/// Add many rows from <see cref="YdbList"/> (shape: <c>List&lt;Struct&lt;...&gt;&gt;</c>).
13+
/// Struct member names and order must exactly match the configured <c>columns</c>.
1314
/// </summary>
14-
/// <remarks>
15-
/// Expected <c>List&lt;Struct&lt;...&gt;&gt;</c>, where the names and order of the fields are the same as <c>columns</c>.
16-
/// Form Example: <c>List&lt;Struct&lt;Id:Int64, Name:Utf8&gt;&gt;</c>.
17-
/// </remarks>
1815
ValueTask AddListAsync(YdbList list);
1916

17+
/// <summary>Flush the current batch via BulkUpsert (no-op if empty).</summary>
2018
ValueTask FlushAsync();
2119
}

src/Ydb.Sdk/src/Ado/YdbParameter.cs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ public sealed class YdbParameter : DbParameter
3737

3838
private string _parameterName = string.Empty;
3939

40-
public YdbParameter() { }
40+
public YdbParameter()
41+
{
42+
}
4143

4244
public YdbParameter(string parameterName, object value)
4345
{
@@ -122,14 +124,10 @@ internal TypedValue TypedValue
122124
var value = Value;
123125

124126
if (value is YdbValue ydbValue)
125-
{
126127
return ydbValue.GetProto();
127-
}
128128

129129
if (value == null || value == DBNull.Value)
130-
{
131130
return NullTypedValue();
132-
}
133131

134132
return YdbDbType switch
135133
{
@@ -147,13 +145,13 @@ internal TypedValue TypedValue
147145
YdbDbType.Double => MakeDouble(value),
148146
YdbDbType.Decimal when value is decimal decimalValue => Decimal(decimalValue),
149147
YdbDbType.Bytes => MakeBytes(value),
150-
YdbDbType.Json when value is string stringValue => stringValue.Json(),
151-
YdbDbType.JsonDocument when value is string stringValue => stringValue.JsonDocument(),
148+
YdbDbType.Json when value is string sJson => sJson.Json(),
149+
YdbDbType.JsonDocument when value is string sJsonDoc => sJsonDoc.JsonDocument(),
152150
YdbDbType.Uuid when value is Guid guidValue => guidValue.Uuid(),
153151
YdbDbType.Date => MakeDate(value),
154-
YdbDbType.DateTime when value is DateTime dateTimeValue => dateTimeValue.Datetime(),
152+
YdbDbType.DateTime when value is DateTime dt => dt.Datetime(),
155153
YdbDbType.Timestamp => MakeTimestamp(value),
156-
YdbDbType.Interval when value is TimeSpan timeSpanValue => timeSpanValue.Interval(),
154+
YdbDbType.Interval when value is TimeSpan ts => ts.Interval(),
157155
YdbDbType.Unspecified => Cast(value),
158156
_ => throw ValueTypeNotSupportedException
159157
};
@@ -277,9 +275,7 @@ private TypedValue Decimal(decimal value) =>
277275
private TypedValue NullTypedValue()
278276
{
279277
if (YdbNullByDbType.TryGetValue(YdbDbType, out var value))
280-
{
281278
return value;
282-
}
283279

284280
if (YdbDbType == YdbDbType.Decimal)
285281
{
@@ -289,8 +285,7 @@ private TypedValue NullTypedValue()
289285
}
290286

291287
throw new InvalidOperationException(
292-
"Writing value of 'null' is not supported without explicit mapping to the YdbDbType"
293-
);
288+
"Writing value of 'null' is not supported without explicit mapping to the YdbDbType");
294289
}
295290

296291
private InvalidOperationException ValueTypeNotSupportedException =>

0 commit comments

Comments
 (0)