1- using Ydb . Sdk . Ado . Internal ;
21using Ydb . Sdk . Value ;
2+ using Ydb . Sdk . Ado . Internal ;
33using Ydb . Table ;
44using Ydb . Table . V1 ;
55
@@ -10,82 +10,87 @@ public sealed class BulkUpsertImporter : IBulkUpsertImporter
1010 private readonly YdbConnection _connection ;
1111 private readonly string _tablePath ;
1212 private readonly IReadOnlyList < string > _columns ;
13- private readonly IReadOnlyList < Type > _types ;
1413 private readonly int _maxBytes ;
15- private readonly List < Ydb . Value > _rows = new ( ) ;
14+ private readonly List < YdbValue > _rows = new ( ) ;
15+ private readonly CancellationToken _cancellationToken ;
1616 private bool _disposed ;
1717
1818 public BulkUpsertImporter (
1919 YdbConnection connection ,
20- string tablePath ,
20+ string tableName ,
2121 IReadOnlyList < string > columns ,
22- IReadOnlyList < Type > types ,
23- int maxBytes = 64 * 1024 * 1024
24- )
22+ CancellationToken cancellationToken = default ,
23+ int maxBytes = 64 * 1024 * 1024 )
2524 {
2625 _connection = connection ;
27- _tablePath = tablePath ;
26+ _tablePath = tableName ;
2827 _columns = columns ;
29- _types = types ;
3028 _maxBytes = maxBytes ;
29+ _cancellationToken = cancellationToken ;
3130 }
3231
33- public async ValueTask AddRowAsync ( params object ? [ ] values )
32+ public async ValueTask AddRowsAsync ( IEnumerable < object ? [ ] > rows )
3433 {
3534 ThrowIfDisposed ( ) ;
36- if ( values . Length != _columns . Count )
37- throw new ArgumentException ( "Values count must match columns count" , nameof ( values ) ) ;
38-
39- var ydbValues = values . Select ( v =>
40- v is YdbValue yv ? yv :
41- v is YdbParameter param ? param . YdbValue :
42- throw new ArgumentException ( "All values must be either YdbValue or YdbParameter" ) ) . ToArray ( ) ;
43-
44- await AddRowAsync ( ydbValues ) ;
45- }
35+ foreach ( var values in rows )
36+ {
37+ if ( values . Length != _columns . Count )
38+ throw new ArgumentException ( "Values count must match columns count" , nameof ( values ) ) ;
4639
47- public async ValueTask AddRowAsync ( params YdbValue [ ] values )
48- {
49- ThrowIfDisposed ( ) ;
50- if ( values . Length != _columns . Count )
51- throw new ArgumentException ( "Values count must match columns count" , nameof ( values ) ) ;
40+ var ydbValues = values . Select ( v =>
41+ v is YdbValue yv ? yv :
42+ v is YdbParameter param ? param . YdbValue :
43+ throw new ArgumentException ( "All values must be either YdbValue or YdbParameter" ) ) . ToArray ( ) ;
5244
53- var dict = _columns . Zip ( values , ( name , value ) => new KeyValuePair < string , YdbValue > ( name , value ) )
54- . ToDictionary ( x => x . Key , x => x . Value ) ;
45+ var dict = _columns . Zip ( ydbValues , ( name , value ) => new KeyValuePair < string , YdbValue > ( name , value ) )
46+ . ToDictionary ( x => x . Key , x => x . Value ) ;
5547
56- var structValue = YdbValue . MakeStruct ( dict ) . GetProto ( ) . Value ;
57- _rows . Add ( structValue ) ;
48+ var structRow = YdbValue . MakeStruct ( dict ) ;
49+ _rows . Add ( structRow ) ;
5850
59- var totalSize = _rows . Sum ( r => r . CalculateSize ( ) ) ;
60- if ( totalSize >= _maxBytes )
61- await FlushAsync ( ) ;
51+ var totalSize = _rows . Sum ( r => r . GetProto ( ) . Value . CalculateSize ( ) ) ;
52+ if ( totalSize >= _maxBytes )
53+ await FlushAsync ( _cancellationToken ) ;
54+ }
6255 }
6356
64- public async ValueTask AddRowsAsync ( IEnumerable < object ? [ ] > rows , CancellationToken cancellationToken = default )
57+ public async ValueTask AddRowsAsync ( IEnumerable < YdbValue [ ] > rows )
6558 {
6659 ThrowIfDisposed ( ) ;
67-
6860 foreach ( var values in rows )
69- await AddRowAsync ( values ) ;
70- }
61+ {
62+ if ( values . Length != _columns . Count )
63+ throw new ArgumentException ( "Values count must match columns count" , nameof ( values ) ) ;
7164
72- public async ValueTask AddRowsAsync ( IEnumerable < YdbValue [ ] > rows , CancellationToken cancellationToken = default )
73- {
74- ThrowIfDisposed ( ) ;
65+ var dict = _columns . Zip ( values , ( name , value ) => new KeyValuePair < string , YdbValue > ( name , value ) )
66+ . ToDictionary ( x => x . Key , x => x . Value ) ;
7567
76- foreach ( var values in rows )
77- await AddRowAsync ( values ) ;
68+ var structRow = YdbValue . MakeStruct ( dict ) ;
69+ _rows . Add ( structRow ) ;
70+
71+ var totalSize = _rows . Sum ( r => r . GetProto ( ) . Value . CalculateSize ( ) ) ;
72+ if ( totalSize >= _maxBytes )
73+ await FlushAsync ( _cancellationToken ) ;
74+ }
7875 }
7976
8077 public async ValueTask FlushAsync ( CancellationToken cancellationToken = default )
8178 {
8279 ThrowIfDisposed ( ) ;
8380 if ( _rows . Count == 0 ) return ;
8481
82+ var structType = _rows [ 0 ] . GetProto ( ) . Type ;
83+
8584 var listValue = new Ydb . Value ( ) ;
86- listValue . Items . AddRange ( _rows ) ;
85+ foreach ( var row in _rows )
86+ listValue . Items . Add ( row . GetProto ( ) . Value ) ;
87+
88+ var typedValue = new TypedValue
89+ {
90+ Type = new Type { ListType = new ListType { Item = structType } } ,
91+ Value = listValue
92+ } ;
8793
88- var typedValue = new TypedValue { Type = GetStructType ( ) , Value = listValue } ;
8994 var req = new BulkUpsertRequest { Table = _tablePath , Rows = typedValue } ;
9095
9196 var resp = await _connection . Session . Driver . UnaryCall (
@@ -101,23 +106,13 @@ public async ValueTask FlushAsync(CancellationToken cancellationToken = default)
101106 _rows . Clear ( ) ;
102107 }
103108
104- public IReadOnlyList < Ydb . Value > GetBufferedRows ( ) => _rows ;
105-
106109 public async ValueTask DisposeAsync ( )
107110 {
108111 if ( _disposed ) return ;
109112 await FlushAsync ( ) ;
110113 _disposed = true ;
111114 }
112115
113- private Type GetStructType ( )
114- {
115- var structType = new Type { StructType = new StructType ( ) } ;
116- for ( var i = 0 ; i < _columns . Count ; i ++ )
117- structType . StructType . Members . Add ( new StructMember { Name = _columns [ i ] , Type = _types [ i ] } ) ;
118- return structType ;
119- }
120-
121116 private void ThrowIfDisposed ( )
122117 {
123118 if ( _disposed )
0 commit comments