2
2
using System . Collections . Generic ;
3
3
using System . Data ;
4
4
using System . IO ;
5
- using System . Linq ;
6
- using System . Text ;
7
5
using System . Threading . Tasks ;
8
6
using Newtonsoft . Json . Linq ;
9
7
using Newtonsoft . Json ;
10
8
using Xunit . Abstractions ;
11
9
using Xunit ;
10
+ using System . Collections ;
12
11
13
12
namespace Microsoft . Data . SqlClient . ManualTesting . Tests . SQL . JsonTest
14
13
{
14
+ public class JsonBulkCopyTestData : IEnumerable < object [ ] >
15
+ {
16
+ public IEnumerator < object [ ] > GetEnumerator ( )
17
+ {
18
+ yield return new object [ ] { CommandBehavior . Default , false , 300 , 100 } ;
19
+ yield return new object [ ] { CommandBehavior . Default , true , 300 , 100 } ;
20
+ yield return new object [ ] { CommandBehavior . SequentialAccess , false , 300 , 100 } ;
21
+ yield return new object [ ] { CommandBehavior . SequentialAccess , true , 300 , 100 } ;
22
+ }
23
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
24
+ }
25
+
15
26
public class JsonBulkCopyTest
16
27
{
17
28
private readonly ITestOutputHelper _output ;
18
- private static readonly string _jsonFile = "randomRecords.json" ;
19
- private static readonly string _outputFile = "serverRecords.json" ;
29
+ private static readonly string _generatedJsonFile = DataTestUtility . GenerateRandomCharacters ( "randomRecords" ) ;
30
+ private static readonly string _outputFile = DataTestUtility . GenerateRandomCharacters ( "serverResults" ) ;
31
+ private static readonly string _sourceTableName = DataTestUtility . GenerateObjectName ( ) ;
32
+ private static readonly string _destinationTableName = DataTestUtility . GenerateObjectName ( ) ;
20
33
21
34
public JsonBulkCopyTest ( ITestOutputHelper output )
22
35
{
23
36
_output = output ;
24
37
}
25
38
26
- private void PopulateData ( int noOfRecords )
39
+ private void PopulateData ( int noOfRecords , int rows )
27
40
{
28
41
using ( SqlConnection connection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
29
42
{
30
- DataTestUtility . CreateTable ( connection , "jsonTab" , "(data json)" ) ;
31
- DataTestUtility . CreateTable ( connection , "jsonTabCopy" , "(data json)" ) ;
32
- GenerateJsonFile ( 50000 , _jsonFile ) ;
33
- StreamJsonFileToServer ( connection ) ;
43
+ DataTestUtility . CreateTable ( connection , _sourceTableName , "(data json)" ) ;
44
+ DataTestUtility . CreateTable ( connection , _destinationTableName , "(data json)" ) ;
45
+ GenerateJsonFile ( noOfRecords , _generatedJsonFile ) ;
46
+ while ( rows -- > 0 )
47
+ {
48
+ StreamJsonFileToServer ( connection ) ;
49
+ }
34
50
}
35
51
}
36
52
@@ -59,7 +75,7 @@ private void GenerateJsonFile(int noOfRecords, string filename)
59
75
60
76
private void CompareJsonFiles ( )
61
77
{
62
- using ( var stream1 = File . OpenText ( _jsonFile ) )
78
+ using ( var stream1 = File . OpenText ( _generatedJsonFile ) )
63
79
using ( var stream2 = File . OpenText ( _outputFile ) )
64
80
using ( var reader1 = new JsonTextReader ( stream1 ) )
65
81
using ( var reader2 = new JsonTextReader ( stream2 ) )
@@ -70,14 +86,14 @@ private void CompareJsonFiles()
70
86
}
71
87
}
72
88
73
- private void PrintJsonDataToFile ( SqlConnection connection )
89
+ private void PrintJsonDataToFileAndCompare ( SqlConnection connection )
74
90
{
75
- DeleteFile ( _outputFile ) ;
76
- using ( SqlCommand command = new SqlCommand ( "SELECT [data] FROM [jsonTabCopy]" , connection ) )
91
+ try
77
92
{
78
- using ( SqlDataReader reader = command . ExecuteReader ( CommandBehavior . SequentialAccess ) )
93
+ DeleteFile ( _outputFile ) ;
94
+ using ( SqlCommand command = new SqlCommand ( "SELECT [data] FROM [" + _destinationTableName + "]" , connection ) )
79
95
{
80
- using ( StreamWriter sw = new StreamWriter ( _outputFile ) )
96
+ using ( SqlDataReader reader = command . ExecuteReader ( CommandBehavior . SequentialAccess ) )
81
97
{
82
98
while ( reader . Read ( ) )
83
99
{
@@ -86,28 +102,36 @@ private void PrintJsonDataToFile(SqlConnection connection)
86
102
87
103
using ( TextReader data = reader . GetTextReader ( 0 ) )
88
104
{
89
- do
105
+ using ( StreamWriter sw = new StreamWriter ( _outputFile ) )
90
106
{
91
- charsRead = data . Read ( buffer , 0 , buffer . Length ) ;
92
- sw . Write ( buffer , 0 , charsRead ) ;
107
+ do
108
+ {
109
+ charsRead = data . Read ( buffer , 0 , buffer . Length ) ;
110
+ sw . Write ( buffer , 0 , charsRead ) ;
93
111
94
- } while ( charsRead > 0 ) ;
112
+ } while ( charsRead > 0 ) ;
113
+ }
95
114
}
96
- _output . WriteLine ( "Output written to " + _outputFile ) ;
115
+ CompareJsonFiles ( ) ;
97
116
}
98
117
}
99
118
}
100
119
}
120
+ finally
121
+ {
122
+ DeleteFile ( _outputFile ) ;
123
+ }
124
+
101
125
}
102
126
103
- private async Task PrintJsonDataToFileAsync ( SqlConnection connection )
127
+ private async Task PrintJsonDataToFileAndCompareAsync ( SqlConnection connection )
104
128
{
105
- DeleteFile ( _outputFile ) ;
106
- using ( SqlCommand command = new SqlCommand ( "SELECT [data] FROM [jsonTab]" , connection ) )
129
+ try
107
130
{
108
- using ( SqlDataReader reader = await command . ExecuteReaderAsync ( CommandBehavior . SequentialAccess ) )
131
+ DeleteFile ( _outputFile ) ;
132
+ using ( SqlCommand command = new SqlCommand ( "SELECT [data] FROM [" + _destinationTableName + "]" , connection ) )
109
133
{
110
- using ( StreamWriter sw = new StreamWriter ( _outputFile ) )
134
+ using ( SqlDataReader reader = await command . ExecuteReaderAsync ( CommandBehavior . SequentialAccess ) )
111
135
{
112
136
while ( await reader . ReadAsync ( ) )
113
137
{
@@ -116,25 +140,32 @@ private async Task PrintJsonDataToFileAsync(SqlConnection connection)
116
140
117
141
using ( TextReader data = reader . GetTextReader ( 0 ) )
118
142
{
119
- do
143
+ using ( StreamWriter sw = new StreamWriter ( _outputFile ) )
120
144
{
121
- charsRead = await data . ReadAsync ( buffer , 0 , buffer . Length ) ;
122
- await sw . WriteAsync ( buffer , 0 , charsRead ) ;
145
+ do
146
+ {
147
+ charsRead = await data . ReadAsync ( buffer , 0 , buffer . Length ) ;
148
+ await sw . WriteAsync ( buffer , 0 , charsRead ) ;
123
149
124
- } while ( charsRead > 0 ) ;
150
+ } while ( charsRead > 0 ) ;
151
+ }
125
152
}
126
- _output . WriteLine ( "Output written to file " + _outputFile ) ;
153
+ CompareJsonFiles ( ) ;
127
154
}
128
155
}
129
156
}
130
157
}
158
+ finally
159
+ {
160
+ DeleteFile ( _outputFile ) ;
161
+ }
131
162
}
132
163
133
164
private void StreamJsonFileToServer ( SqlConnection connection )
134
165
{
135
- using ( SqlCommand cmd = new SqlCommand ( "INSERT INTO [jsonTab ] (data) VALUES (@jsondata)" , connection ) )
166
+ using ( SqlCommand cmd = new SqlCommand ( "INSERT INTO [" + _sourceTableName + " ] (data) VALUES (@jsondata)", connection ) )
136
167
{
137
- using ( StreamReader jsonFile = File . OpenText ( _jsonFile ) )
168
+ using ( StreamReader jsonFile = File . OpenText ( _generatedJsonFile ) )
138
169
{
139
170
cmd . Parameters . Add ( "@jsondata" , Microsoft . Data . SqlDbTypeExtensions . Json , - 1 ) . Value = jsonFile ;
140
171
cmd . ExecuteNonQuery ( ) ;
@@ -144,9 +175,9 @@ private void StreamJsonFileToServer(SqlConnection connection)
144
175
145
176
private async Task StreamJsonFileToServerAsync ( SqlConnection connection )
146
177
{
147
- using ( SqlCommand cmd = new SqlCommand ( "INSERT INTO [jsonTab ] (data) VALUES (@jsondata)" , connection ) )
178
+ using ( SqlCommand cmd = new SqlCommand ( "INSERT INTO [" + _sourceTableName + " ] (data) VALUES (@jsondata)", connection ) )
148
179
{
149
- using ( StreamReader jsonFile = File . OpenText ( _jsonFile ) )
180
+ using ( StreamReader jsonFile = File . OpenText ( _generatedJsonFile ) )
150
181
{
151
182
cmd . Parameters . Add ( "@jsondata" , Microsoft . Data . SqlDbTypeExtensions . Json , - 1 ) . Value = jsonFile ;
152
183
await cmd . ExecuteNonQueryAsync ( ) ;
@@ -162,23 +193,23 @@ private void DeleteFile(string filename)
162
193
}
163
194
}
164
195
165
- private void BulkCopyData ( CommandBehavior cb , bool enableStraming )
196
+ private void BulkCopyData ( CommandBehavior cb , bool enableStraming , int expectedTransferCount )
166
197
{
167
198
using ( SqlConnection sourceConnection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
168
199
{
169
200
sourceConnection . Open ( ) ;
170
- SqlCommand commandRowCount = new SqlCommand ( "SELECT COUNT(*) FROM " + "dbo.jsonTabCopy;" , sourceConnection ) ;
201
+ SqlCommand commandRowCount = new SqlCommand ( "SELECT COUNT(*) FROM " + _destinationTableName , sourceConnection ) ;
171
202
long countStart = System . Convert . ToInt32 ( commandRowCount . ExecuteScalar ( ) ) ;
172
203
_output . WriteLine ( "Starting row count = {0}" , countStart ) ;
173
- SqlCommand commandSourceData = new SqlCommand ( "SELECT data FROM dbo.jsonTab;" , sourceConnection ) ;
204
+ SqlCommand commandSourceData = new SqlCommand ( "SELECT data FROM " + _sourceTableName , sourceConnection ) ;
174
205
SqlDataReader reader = commandSourceData . ExecuteReader ( cb ) ;
175
206
using ( SqlConnection destinationConnection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
176
207
{
177
208
destinationConnection . Open ( ) ;
178
209
using ( SqlBulkCopy bulkCopy = new SqlBulkCopy ( destinationConnection ) )
179
210
{
180
211
bulkCopy . EnableStreaming = enableStraming ;
181
- bulkCopy . DestinationTableName = "dbo.jsonTabCopy" ;
212
+ bulkCopy . DestinationTableName = _destinationTableName ;
182
213
try
183
214
{
184
215
bulkCopy . WriteToServer ( reader ) ;
@@ -195,27 +226,28 @@ private void BulkCopyData(CommandBehavior cb, bool enableStraming)
195
226
long countEnd = System . Convert . ToInt32 ( commandRowCount . ExecuteScalar ( ) ) ;
196
227
_output . WriteLine ( "Ending row count = {0}" , countEnd ) ;
197
228
_output . WriteLine ( "{0} rows were added." , countEnd - countStart ) ;
229
+ Assert . Equal ( expectedTransferCount , countEnd - countStart ) ;
198
230
}
199
231
}
200
232
}
201
233
202
- private async Task BulkCopyDataAsync ( CommandBehavior cb , bool enableStraming )
234
+ private async Task BulkCopyDataAsync ( CommandBehavior cb , bool enableStraming , int expectedTransferCount )
203
235
{
204
236
using ( SqlConnection sourceConnection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
205
237
{
206
238
await sourceConnection . OpenAsync ( ) ;
207
- SqlCommand commandRowCount = new SqlCommand ( "SELECT COUNT(*) FROM " + "dbo.jsonTabCopy;" , sourceConnection ) ;
239
+ SqlCommand commandRowCount = new SqlCommand ( "SELECT COUNT(*) FROM " + _destinationTableName , sourceConnection ) ;
208
240
long countStart = System . Convert . ToInt32 ( await commandRowCount . ExecuteScalarAsync ( ) ) ;
209
241
_output . WriteLine ( "Starting row count = {0}" , countStart ) ;
210
- SqlCommand commandSourceData = new SqlCommand ( "SELECT data FROM dbo.jsonTab;" , sourceConnection ) ;
242
+ SqlCommand commandSourceData = new SqlCommand ( "SELECT data FROM " + _sourceTableName , sourceConnection ) ;
211
243
SqlDataReader reader = await commandSourceData . ExecuteReaderAsync ( cb ) ;
212
244
using ( SqlConnection destinationConnection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
213
245
{
214
246
await destinationConnection . OpenAsync ( ) ;
215
247
using ( SqlBulkCopy bulkCopy = new SqlBulkCopy ( destinationConnection ) )
216
248
{
217
249
bulkCopy . EnableStreaming = enableStraming ;
218
- bulkCopy . DestinationTableName = "dbo.jsonTabCopy" ;
250
+ bulkCopy . DestinationTableName = _destinationTableName ;
219
251
try
220
252
{
221
253
await bulkCopy . WriteToServerAsync ( reader ) ;
@@ -232,44 +264,37 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming)
232
264
long countEnd = System . Convert . ToInt32 ( await commandRowCount . ExecuteScalarAsync ( ) ) ;
233
265
_output . WriteLine ( "Ending row count = {0}" , countEnd ) ;
234
266
_output . WriteLine ( "{0} rows were added." , countEnd - countStart ) ;
267
+ Assert . Equal ( expectedTransferCount , countEnd - countStart ) ;
235
268
}
236
269
}
237
270
}
238
271
239
- [ InlineData ( CommandBehavior . Default , false ) ]
240
- [ InlineData ( CommandBehavior . Default , true ) ]
241
- [ InlineData ( CommandBehavior . SequentialAccess , false ) ]
242
- [ InlineData ( CommandBehavior . SequentialAccess , true ) ]
243
272
[ ConditionalTheory ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . IsJsonSupported ) ) ]
244
- public void TestJsonBulkCopy ( CommandBehavior cb , bool enableStraming )
273
+ [ ClassData ( typeof ( JsonBulkCopyTestData ) ) ]
274
+ public void TestJsonBulkCopy ( CommandBehavior cb , bool enableStraming , int jsonArrayElements , int rows )
245
275
{
246
- PopulateData ( 10000 ) ;
276
+ PopulateData ( jsonArrayElements , rows ) ;
247
277
using ( SqlConnection connection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
248
278
{
249
- BulkCopyData ( cb , enableStraming ) ;
279
+ BulkCopyData ( cb , enableStraming , rows ) ;
250
280
connection . Open ( ) ;
251
- PrintJsonDataToFile ( connection ) ;
252
- CompareJsonFiles ( ) ;
253
- DeleteFile ( _jsonFile ) ;
281
+ PrintJsonDataToFileAndCompare ( connection ) ;
282
+ DeleteFile ( _generatedJsonFile ) ;
254
283
DeleteFile ( _outputFile ) ;
255
284
}
256
285
}
257
286
258
- [ InlineData ( CommandBehavior . Default , false ) ]
259
- [ InlineData ( CommandBehavior . Default , true ) ]
260
- [ InlineData ( CommandBehavior . SequentialAccess , false ) ]
261
- [ InlineData ( CommandBehavior . SequentialAccess , true ) ]
262
287
[ ConditionalTheory ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . IsJsonSupported ) ) ]
263
- public async Task TestJsonBulkCopyAsync ( CommandBehavior cb , bool enableStraming )
288
+ [ ClassData ( typeof ( JsonBulkCopyTestData ) ) ]
289
+ public async Task TestJsonBulkCopyAsync ( CommandBehavior cb , bool enableStraming , int jsonArrayElements , int rows )
264
290
{
265
- PopulateData ( 10000 ) ;
291
+ PopulateData ( jsonArrayElements , rows ) ;
266
292
using ( SqlConnection connection = new SqlConnection ( DataTestUtility . TCPConnectionString ) )
267
293
{
268
- await BulkCopyDataAsync ( cb , enableStraming ) ;
294
+ await BulkCopyDataAsync ( cb , enableStraming , rows ) ;
269
295
await connection . OpenAsync ( ) ;
270
- await PrintJsonDataToFileAsync ( connection ) ;
271
- CompareJsonFiles ( ) ;
272
- DeleteFile ( _jsonFile ) ;
296
+ await PrintJsonDataToFileAndCompareAsync ( connection ) ;
297
+ DeleteFile ( _generatedJsonFile ) ;
273
298
DeleteFile ( _outputFile ) ;
274
299
}
275
300
}
0 commit comments