Skip to content

Commit 4e94659

Browse files
Add SqlServer.ExecuteScriptAsync() method.
1 parent ec264cc commit 4e94659

3 files changed

Lines changed: 168 additions & 0 deletions

File tree

src/Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
2.2.0
1515
- Add SqlServer.CreateEmptyDatabaseAsync() method.
1616
- Add SqlServer.DeleteDatabaseAsync() method.
17+
- Add SqlServer.ExecuteScriptAsync() method.
1718

1819
2.1.0
1920
- PosInformatique.Testing.Databases.SqlServer target the .NET Standard 2.0 platform.

src/Testing.Databases.SqlServer/SqlServerDatabaseExtensions.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,44 @@ public static void ExecuteScript(this SqlServerDatabase database, StringReader s
164164
}
165165
}
166166

167+
/// <summary>
168+
/// Execute an T-SQL script on the <paramref name="database"/>.
169+
/// </summary>
170+
/// <param name="database"><see cref="SqlServerDatabase"/> where the <paramref name="script"/> will be executed.</param>
171+
/// <param name="script">T-SQL script to execute.</param>
172+
/// <param name="cancellationToken"><see cref="CancellationToken"/> used to cancel the asynchronous operation.</param>
173+
/// <returns>A <see cref="Task"/> which represents the asynchronous operation.</returns>
174+
public static async Task ExecuteScriptAsync(this SqlServerDatabase database, string script, CancellationToken cancellationToken = default)
175+
{
176+
using var stringReader = new StringReader(script);
177+
178+
await ExecuteScriptAsync(database, stringReader);
179+
}
180+
181+
/// <summary>
182+
/// Execute an T-SQL script on the <paramref name="database"/> asynchronously.
183+
/// </summary>
184+
/// <param name="database"><see cref="SqlServerDatabase"/> where the <paramref name="script"/> will be executed.</param>
185+
/// <param name="script"><see cref="StringReader"/> which contains the T-SQL script to execute.</param>
186+
/// <param name="cancellationToken"><see cref="CancellationToken"/> used to cancel the asynchronous operation.</param>
187+
/// <returns>A <see cref="Task"/> which represents the asynchronous operation.</returns>
188+
public static async Task ExecuteScriptAsync(this SqlServerDatabase database, StringReader script, CancellationToken cancellationToken = default)
189+
{
190+
var parser = new SqlServerScriptParser(script);
191+
192+
var block = parser.ReadNextBlock();
193+
194+
while (block is not null)
195+
{
196+
for (var i = 0; i < block.Count; i++)
197+
{
198+
await database.ExecuteNonQueryAsync(block.Code, cancellationToken);
199+
}
200+
201+
block = parser.ReadNextBlock();
202+
}
203+
}
204+
167205
private sealed class SqlInsertStatementBuilder
168206
{
169207
private readonly string tableName;

tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseExtensionsTest.cs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,134 @@ GO 10
219219

220220
table.Rows[0]["Id"].Should().Be(10);
221221
}
222+
223+
[Fact]
224+
public async Task ExecuteScriptAsync_String()
225+
{
226+
var server = new SqlServer(ConnectionString);
227+
228+
var database = server.CreateEmptyDatabase("SqlServerDatabaseExtensionsTest");
229+
230+
await database.ExecuteScriptAsync(@"
231+
CREATE TABLE TableTest
232+
(
233+
Id INT NOT NULL
234+
)
235+
236+
GO
237+
GO
238+
239+
INSERT INTO [TableTest] ([Id]) VALUES (0)
240+
241+
GO
242+
UPDATE [TableTest]
243+
SET [Id] = [Id] + 1
244+
245+
GO 10");
246+
247+
var table = await database.ExecuteQueryAsync("SELECT * FROM [TableTest]");
248+
249+
table.Rows.Should().HaveCount(1);
250+
251+
table.Rows[0]["Id"].Should().Be(10);
252+
}
253+
254+
[Fact]
255+
public async Task ExecuteScriptAsync_String_WithEmptyLinesAtTheEnd()
256+
{
257+
var server = new SqlServer(ConnectionString);
258+
259+
var database = server.CreateEmptyDatabase("SqlServerDatabaseExtensionsTest");
260+
261+
await database.ExecuteScriptAsync(@"
262+
CREATE TABLE TableTest
263+
(
264+
Id INT NOT NULL
265+
)
266+
267+
GO
268+
GO
269+
270+
INSERT INTO [TableTest] ([Id]) VALUES (0)
271+
272+
GO
273+
UPDATE [TableTest]
274+
SET [Id] = [Id] + 1
275+
276+
GO 10
277+
278+
");
279+
280+
var table = await database.ExecuteQueryAsync("SELECT * FROM [TableTest]");
281+
282+
table.Rows.Should().HaveCount(1);
283+
284+
table.Rows[0]["Id"].Should().Be(10);
285+
}
286+
287+
[Fact]
288+
public async Task ExecuteScriptAsync_StringReader()
289+
{
290+
var server = new SqlServer(ConnectionString);
291+
292+
var database = server.CreateEmptyDatabase("SqlServerDatabaseExtensionsTest");
293+
294+
await database.ExecuteScriptAsync(new StringReader(@"
295+
CREATE TABLE TableTest
296+
(
297+
Id INT NOT NULL
298+
)
299+
300+
GO
301+
GO
302+
303+
INSERT INTO [TableTest] ([Id]) VALUES (0)
304+
305+
GO
306+
UPDATE [TableTest]
307+
SET [Id] = [Id] + 1
308+
309+
GO 10"));
310+
311+
var table = await database.ExecuteQueryAsync("SELECT * FROM [TableTest]");
312+
313+
table.Rows.Should().HaveCount(1);
314+
315+
table.Rows[0]["Id"].Should().Be(10);
316+
}
317+
318+
[Fact]
319+
public async Task ExecuteScriptAsync_StringReader_WithEmptyLinesAtTheEnd()
320+
{
321+
var server = new SqlServer(ConnectionString);
322+
323+
var database = server.CreateEmptyDatabase("SqlServerDatabaseExtensionsTest");
324+
325+
await database.ExecuteScriptAsync(new StringReader(@"
326+
CREATE TABLE TableTest
327+
(
328+
Id INT NOT NULL
329+
)
330+
331+
GO
332+
GO
333+
334+
INSERT INTO [TableTest] ([Id]) VALUES (0)
335+
336+
GO
337+
UPDATE [TableTest]
338+
SET [Id] = [Id] + 1
339+
340+
GO 10
341+
342+
343+
"));
344+
345+
var table = await database.ExecuteQueryAsync("SELECT * FROM [TableTest]");
346+
347+
table.Rows.Should().HaveCount(1);
348+
349+
table.Rows[0]["Id"].Should().Be(10);
350+
}
222351
}
223352
}

0 commit comments

Comments
 (0)