Skip to content

Commit 6dd1083

Browse files
Add the support in SqlServerDacExtensions to deploy database in a specific folder.
1 parent 0edd563 commit 6dd1083

12 files changed

Lines changed: 261 additions & 70 deletions

PosInformatique.Testing.Databases.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testing.Databases.SqlServer
5151
EndProject
5252
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{8500A9B6-CAA0-432C-BABB-DDC86CE08994}"
5353
ProjectSection(SolutionItems) = preProject
54-
docs\WriteTest.md = docs\WriteTest.md
5554
docs\WriteDatabaseMigrationTest.md = docs\WriteDatabaseMigrationTest.md
55+
docs\WriteTest.md = docs\WriteTest.md
5656
EndProjectSection
5757
EndProject
5858
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testing.Databases.SqlServer.Dac", "src\Testing.Databases.SqlServer.Dac\Testing.Databases.SqlServer.Dac.csproj", "{8BE60460-EBA5-43DE-B85D-C756E2988DC8}"
5959
EndProject
60+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testing.Databases.SqlServer.Dac.Tests", "tests\Testing.Databases.SqlServer.Dac.Tests\Testing.Databases.SqlServer.Dac.Tests.csproj", "{6751A585-1BB0-49A1-BF68-D7FBD3392DF6}"
61+
EndProject
6062
Global
6163
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6264
Debug|Any CPU = Debug|Any CPU
@@ -101,6 +103,10 @@ Global
101103
{8BE60460-EBA5-43DE-B85D-C756E2988DC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
102104
{8BE60460-EBA5-43DE-B85D-C756E2988DC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
103105
{8BE60460-EBA5-43DE-B85D-C756E2988DC8}.Release|Any CPU.Build.0 = Release|Any CPU
106+
{6751A585-1BB0-49A1-BF68-D7FBD3392DF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
107+
{6751A585-1BB0-49A1-BF68-D7FBD3392DF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
108+
{6751A585-1BB0-49A1-BF68-D7FBD3392DF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
109+
{6751A585-1BB0-49A1-BF68-D7FBD3392DF6}.Release|Any CPU.Build.0 = Release|Any CPU
104110
EndGlobalSection
105111
GlobalSection(SolutionProperties) = preSolution
106112
HideSolutionNode = FALSE

src/Testing.Databases.SqlServer.Dac/SqlServerDacDatabaseInitializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace PosInformatique.Testing.Databases.SqlServer
1313
/// Call the <see cref="Initialize(SqlServerDatabaseInitializer, string, string)"/> method to initialize a database from
1414
/// a DACPAC file.
1515
/// </summary>
16-
/// <remarks>The database will be created the call of the <see cref="Initialize(string, string)"/> method. For the next calls
16+
/// <remarks>The database will be created the call of the <see cref="Initialize(SqlServerDatabaseInitializer, string, string)"/> method. For the next calls
1717
/// the database is preserved but all the data are deleted.</remarks>
1818
public static class SqlServerDacDatabaseInitializer
1919
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="SqlServerDacDeploymentSettings.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace PosInformatique.Testing.Databases.SqlServer
8+
{
9+
/// <summary>
10+
/// Contains additional settings when deploying a <see cref="SqlServerDatabase"/>
11+
/// using <see cref="SqlServerDacExtensions"/> or <see cref="SqlServerDacDatabaseInitializer"/>.
12+
/// </summary>
13+
public class SqlServerDacDeploymentSettings
14+
{
15+
/// <summary>
16+
/// Gets or sets the data file name (full path) of the database to create.
17+
/// </summary>
18+
public string? DataFileName { get; set; }
19+
}
20+
}

src/Testing.Databases.SqlServer.Dac/SqlServerDacExtensions.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ public static class SqlServerDacExtensions
2121
/// <param name="server"><see cref="SqlServer"/> instance where the DACPAC file will be deployed.</param>
2222
/// <param name="fileName">File name (including the path) for the DACPAC file to deploy.</param>
2323
/// <param name="databaseName">Name of the database which will be created.</param>
24+
/// <param name="settings">Additional settings of the database to deploy.</param>
2425
/// <returns>An instance of the <see cref="SqlServerDatabase"/> which represents the deployed database.</returns>
25-
public static SqlServerDatabase DeployDacPackage(this SqlServer server, string fileName, string databaseName)
26+
public static SqlServerDatabase DeployDacPackage(this SqlServer server, string fileName, string databaseName, SqlServerDacDeploymentSettings? settings = null)
2627
{
2728
using (var package = DacPackage.Load(fileName))
2829
{
29-
var options = new DacDeployOptions();
30-
options.CreateNewDatabase = true;
30+
// Currently DacFx does not support to define explicitly the location of the database files.
31+
// So, we create an empty database and after we run the deployment without deleting the database.
32+
server.CreateEmptyDatabase(databaseName, new SqlDatabaseCreationSettings() { DataFileName = settings?.DataFileName });
3133

3234
var services = new DacServices(server.Master.ConnectionString);
33-
services.Deploy(package, databaseName, true, options: options);
35+
services.Deploy(package, databaseName, true);
3436
}
3537

3638
return server.GetDatabase(databaseName);

src/Testing.Databases.SqlServer.Dac/Testing.Databases.SqlServer.Dac.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
<Description>Testing.Databases.SqlServer.Dac is a library that contains a set of tools for testing to deploy DAC (Data-tier Applications) packages (.dacpac files).</Description>
77
<PackageTags>testing unittest sqlserver repository tdd dataaccesslayer dacpac dac</PackageTags>
8+
<GenerateDocumentationFile>True</GenerateDocumentationFile>
89
</PropertyGroup>
910

1011
<ItemGroup>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="SqlServerDacDeploymentSettingsTest.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace PosInformatique.Testing.Databases.SqlServer.Tests
8+
{
9+
public class SqlServerDacDeploymentSettingsTest
10+
{
11+
[Fact]
12+
public void Constructor()
13+
{
14+
var settings = new SqlServerDacDeploymentSettings();
15+
16+
settings.DataFileName.Should().BeNull();
17+
}
18+
19+
[Fact]
20+
public void DataFileName_ValueChanged()
21+
{
22+
var settings = new SqlServerDacDeploymentSettings();
23+
24+
settings.DataFileName = "The value";
25+
26+
settings.DataFileName.Should().Be("The value");
27+
}
28+
}
29+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="SqlServerDacExtensionsTest.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace PosInformatique.Testing.Databases.SqlServer.Tests
8+
{
9+
[Collection("PosInformatique.Testing.Databases.SqlServer.Tests")]
10+
public class SqlServerDacExtensionsTest
11+
{
12+
private const string ConnectionString = $"Data Source=(localDB)\\posinfo-tests; Integrated Security=True";
13+
14+
[Theory]
15+
[InlineData(false)]
16+
[InlineData(true)]
17+
public void DeployDacPackage(bool withSettings)
18+
{
19+
// Create existing database to be sure the database is recreated when deploying the database with a DACPAC
20+
CreateDatabase("SqlServerDacExtensionsTest_DeployDacPackage");
21+
22+
var server = new SqlServer(ConnectionString);
23+
24+
SqlServerDacDeploymentSettings settings = null;
25+
26+
if (withSettings)
27+
{
28+
settings = new SqlServerDacDeploymentSettings();
29+
}
30+
31+
var database = server.DeployDacPackage("Testing.Databases.SqlServer.Tests.DacPac.dacpac", "SqlServerDacExtensionsTest_DeployDacPackage", settings);
32+
33+
var table = database.ExecuteQuery("SELECT * FROM MyTable");
34+
35+
table.Rows.Should().BeEmpty();
36+
37+
// Insert data to check the connection.
38+
database.InsertInto("MyTable", new { Id = 1, Name = "Name 1" });
39+
database.InsertInto("MyTable", new { Id = 2, Name = "Name 2" });
40+
}
41+
42+
[Fact]
43+
public void DeployDacPackage_WithSpecificFile()
44+
{
45+
// Create existing database to be sure the database is recreated when deploying the database with a DACPAC
46+
CreateDatabase("SqlServerDacExtensionsTest_DeployDacPackage_WithSpecificFile");
47+
48+
using var temporaryFolder = TemporaryFolder.Create();
49+
50+
var server = new SqlServer(ConnectionString);
51+
52+
var settings = new SqlServerDacDeploymentSettings()
53+
{
54+
DataFileName = Path.Combine(temporaryFolder.Path, "TheSpecificDataFileName.mdf"),
55+
};
56+
57+
var database = server.DeployDacPackage("Testing.Databases.SqlServer.Tests.DacPac.dacpac", "SqlServerDacExtensionsTest_DeployDacPackage_WithSpecificFile", settings);
58+
59+
var table = database.ExecuteQuery("SELECT * FROM MyTable");
60+
61+
table.Rows.Should().BeEmpty();
62+
63+
// Insert data to check the connection.
64+
database.InsertInto("MyTable", new { Id = 1, Name = "Name 1" });
65+
database.InsertInto("MyTable", new { Id = 2, Name = "Name 2" });
66+
67+
// Check the location of the database
68+
File.Exists(Path.Combine(temporaryFolder.Path, "TheSpecificDataFileName.mdf")).Should().BeTrue();
69+
File.Exists(Path.Combine(temporaryFolder.Path, "TheSpecificDataFileName_log.ldf")).Should().BeTrue();
70+
71+
var result = database.ExecuteQuery("SELECT * FROM [sys].[database_files] ORDER BY [physical_name]");
72+
73+
result.Rows.Should().HaveCount(2);
74+
75+
result.Rows[0]["name"].Should().Be("SqlServerDacExtensionsTest_DeployDacPackage_WithSpecificFile");
76+
result.Rows[0]["physical_name"].Should().Be(Path.Combine(temporaryFolder.Path, "TheSpecificDataFileName.mdf"));
77+
result.Rows[0]["type_desc"].Should().Be("ROWS");
78+
79+
result.Rows[1]["name"].Should().Be("TheSpecificDataFileName_log");
80+
result.Rows[1]["physical_name"].Should().Be(Path.Combine(temporaryFolder.Path, "TheSpecificDataFileName_log.ldf"));
81+
result.Rows[1]["type_desc"].Should().Be("LOG");
82+
83+
// Delete the database (for deleting the temporary folder).
84+
server.DeleteDatabase("SqlServerDacExtensionsTest_DeployDacPackage_WithSpecificFile");
85+
}
86+
87+
private static void CreateDatabase(string name)
88+
{
89+
var server = new SqlServer(ConnectionString);
90+
91+
var database = server.CreateEmptyDatabase(name);
92+
93+
database.ExecuteNonQuery("CREATE TABLE OtherTable (Id INT)");
94+
}
95+
}
96+
}

tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseInitializerTest.cs renamed to tests/Testing.Databases.SqlServer.Dac.Tests/SqlServerDatabaseInitializerTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public SqlServerDatabaseInitializerTest(SqlServerDatabaseInitializer initializer
2121

2222
table.Rows.Should().BeEmpty();
2323

24+
// Insert data to check the connection.
2425
this.database.InsertInto("MyTable", new { Id = 1, Name = "Name 1" });
2526
this.database.InsertInto("MyTable", new { Id = 2, Name = "Name 2" });
2627
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="..\Testing.Databases.SqlServer.Tests\TemporaryFolder.cs" Link="TemporaryFolder.cs" />
9+
</ItemGroup>
10+
11+
<ItemGroup>
12+
<Content Include="..\Testing.Databases.SqlServer.Tests.DacPac\bin\Debug\Testing.Databases.SqlServer.Tests.DacPac.dacpac" Link="Testing.Databases.SqlServer.Tests.DacPac.dacpac">
13+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
14+
</Content>
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="coverlet.collector">
19+
<PrivateAssets>all</PrivateAssets>
20+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
21+
</PackageReference>
22+
<PackageReference Include="FluentAssertions" />
23+
<PackageReference Include="Microsoft.NET.Test.Sdk" />
24+
<PackageReference Include="xunit" />
25+
<PackageReference Include="xunit.runner.visualstudio">
26+
<PrivateAssets>all</PrivateAssets>
27+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
28+
</PackageReference>
29+
</ItemGroup>
30+
<ItemGroup>
31+
<ProjectReference Include="..\..\src\Testing.Databases.SqlServer.Dac\Testing.Databases.SqlServer.Dac.csproj" />
32+
<ProjectReference Include="..\Testing.Databases.SqlServer.Tests.DacPac\Testing.Databases.SqlServer.Tests.DacPac.sqlproj" />
33+
</ItemGroup>
34+
35+
</Project>

0 commit comments

Comments
 (0)