Skip to content

Commit

Permalink
Add the XML comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
GillesTourreau committed Aug 27, 2024
1 parent f12e5e4 commit 7d2a3ca
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,19 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;

/// <summary>
/// Contains extensions methods on the <see cref="SqlServerDatabaseInitializer"/> to initialize
/// database using Entity Framework <see cref="DbContext"/>.
/// </summary>
public static class EntityFrameworkDatabaseInitializerExtensions
{
public static SqlServerDatabase Initialize<TContext>(this SqlServerDatabaseInitializer initializer, TContext context)
where TContext : DbContext
/// <summary>
/// Initialize a SQL Server database from a <see cref="DbContext"/> specified in the <paramref name="context"/> argument.
/// </summary>
/// <param name="initializer"><see cref="SqlServerDatabaseInitializer"/> which the initialization will be perform on.</param>
/// <param name="context">Instance of the <see cref="DbContext"/> which represents the database schema to initialize.</param>
/// <returns>An instance of the <see cref="SqlServerDatabase"/> which allows to perform query to initialize the data.</returns>
public static SqlServerDatabase Initialize(this SqlServerDatabaseInitializer initializer, DbContext context)
{
var connectionString = context.Database.GetConnectionString();

Expand All @@ -21,7 +30,7 @@ public static SqlServerDatabase Initialize<TContext>(this SqlServerDatabaseIniti
var server = new SqlServer(connectionString!);
var database = server.GetDatabase(connectionStringBuilder.InitialCatalog);

if (!initializer.IsDeployed)
if (!initializer.IsInitialized)
{
server.DeleteDatabase(connectionStringBuilder.InitialCatalog);

Expand All @@ -34,7 +43,7 @@ IF SUSER_ID ('{connectionStringBuilder.UserID}') IS NULL
CREATE LOGIN [{connectionStringBuilder.UserID}] WITH PASSWORD = '{connectionStringBuilder.Password}'");
}

initializer.IsDeployed = true;
initializer.IsInitialized = true;
}

database.ClearAllData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
using System.Collections.ObjectModel;
using System.Text;

/// <summary>
/// Represents the differences between 2 databases.
/// </summary>
public class SqlDatabaseComparisonResults
{
internal SqlDatabaseComparisonResults(IList<SqlDatabaseObjectDifferences> objects)
{
this.Objects = new ReadOnlyCollection<SqlDatabaseObjectDifferences>(objects);
}

/// <summary>
/// Gets the list of the database objects differences found.
/// </summary>
public ReadOnlyCollection<SqlDatabaseObjectDifferences> Objects { get; }

/// <inheritdoc />
public override string ToString()
{
var stringBuilder = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
using System.Data;
using System.Text;

/// <summary>
/// Represents a difference between 2 database objects.
/// </summary>
public class SqlDatabaseObjectDifference
{
private readonly object[] keyValue;
Expand All @@ -21,12 +24,24 @@ internal SqlDatabaseObjectDifference(DataRow? source, DataRow? target, SqlDataba
this.keyValue = keyValue;
}

/// <summary>
/// Gets schema information of the source database. If <see langword="null"/> it is mean
/// that the object exists in the target database but does not exists in the source database.
/// </summary>
public DataRow? Source { get; }

/// <summary>
/// Gets schema information of the target database. If <see langword="null"/> it is mean
/// that the object exists in the source database but does not exists in the target database.
/// </summary>
public DataRow? Target { get; }

/// <summary>
/// Gets the of the difference between the <see cref="Source"/> and the <see cref="Target"/>.
/// </summary>
public SqlDatabaseObjectDifferenceType Type { get; }

/// <inheritdoc />
public override string ToString()
{
var keyValueString = string.Join(".", this.keyValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@

namespace PosInformatique.UnitTests.Databases.SqlServer
{
/// <summary>
/// Indicate the difference type between <see cref="SqlDatabaseObjectDifference.Source"/> and <see cref="SqlDatabaseObjectDifference.Target"/>.
/// </summary>
public enum SqlDatabaseObjectDifferenceType
{
/// <summary>
/// Indicates that an object exists in the source database but does not exists in the target database.
/// </summary>
MissingInTarget,

/// <summary>
/// Indicates that an object exists in the target database but does not exists in the source database.
/// </summary>
MissingInSource,

/// <summary>
/// Indicates that the object exists in the two databases but have some different properties.
/// </summary>
Different,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
{
using System.Collections.ObjectModel;

/// <summary>
/// Represents a list of the difference for database object type.
/// </summary>
public sealed class SqlDatabaseObjectDifferences
{
internal SqlDatabaseObjectDifferences(string type, IList<SqlDatabaseObjectDifference> differences)
Expand All @@ -16,10 +19,17 @@ internal SqlDatabaseObjectDifferences(string type, IList<SqlDatabaseObjectDiffer
this.Type = type;
}

/// <summary>
/// Gets the list of the object differences between the two databases.
/// </summary>
public ReadOnlyCollection<SqlDatabaseObjectDifference> Differences { get; }

/// <summary>
/// Gets the type of the object.
/// </summary>
public string Type { get; }

/// <inheritdoc />
public override string ToString()
{
return this.Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace PosInformatique.UnitTests.Databases.SqlServer
{
/// <summary>
/// Allows to compare schema difference between 2 databases.
/// </summary>
public class SqlServerDatabaseComparer
{
private static readonly SqlServerObjectComparer[] Comparers =
Expand All @@ -22,10 +25,12 @@ public class SqlServerDatabaseComparer
new SqlServerViewsComparer(),
];

public SqlServerDatabaseComparer()
{
}

/// <summary>
/// Compares two database and returns the differences found.
/// </summary>
/// <param name="source">First database to compare with <paramref name="target"/>.</param>
/// <param name="target">Second database to compare with <paramref name="source"/>.</param>
/// <returns>The difference between the two databases.</returns>
public SqlDatabaseComparisonResults Compare(SqlServerDatabase source, SqlServerDatabase target)
{
var differences = new List<SqlDatabaseObjectDifferences>();
Expand Down
38 changes: 33 additions & 5 deletions src/UnitTests.Databases.SqlServer/SqlServerDatabaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
{
using System.Globalization;
using System.Text;
using Microsoft.Data.SqlClient;

/// <summary>
/// Contains extensions methods on the <see cref="SqlServerDatabase"/> class.
/// </summary>
public static class SqlServerDatabaseExtensions
{
private const string Tab = " ";
Expand All @@ -24,11 +26,33 @@ public static class SqlServerDatabaseExtensions
typeof(decimal?),
];

/// <summary>
/// Insert data into the table specified by the <paramref name="tableName"/> argument. The row
/// to insert are represents by objects (or anonymous objects) which the property name must match the
/// the column name.
/// </summary>
/// <typeparam name="T">Type of the object which contains the data to insert in the table.</typeparam>
/// <param name="database">SQL Server database which contains the table where the data will be inserted.</param>
/// <param name="tableName">SQL table where the data will be inserted.</param>
/// <param name="objects">Set of object which represents the row to insert. Each object must have property which are mapped to the column to insert.</param>
/// <returns>The number of the rows inserted.</returns>
public static int InsertInto<T>(this SqlServerDatabase database, string tableName, params T[] objects)
{
return InsertInto(database, tableName, false, objects);
}

/// <summary>
/// Insert data into the table specified by the <paramref name="tableName"/> argument. The row
/// to insert are represents by objects (or anonymous objects) which the property name must match the
/// the column name.
/// </summary>
/// <typeparam name="T">Type of the object which contains the data to insert in the table.</typeparam>
/// <param name="database">SQL Server database which contains the table where the data will be inserted.</param>
/// <param name="tableName">SQL table where the data will be inserted.</param>
/// <param name="disableIdentityInsert"><see langword="true"/> to disable auto incrementation of the <c>IDENTITY</c> column. In this case, the object must contains explicitely the value of the <c>IDENTITY</c>
/// column to insert.</param>
/// <param name="objects">Set of object which represents the row to insert. Each object must have property which are mapped to the column to insert.</param>
/// <returns>The number of the rows inserted.</returns>
public static int InsertInto<T>(this SqlServerDatabase database, string tableName, bool disableIdentityInsert, params T[] objects)
{
var builder = new SqlInsertStatementBuilder(tableName);
Expand Down Expand Up @@ -70,6 +94,10 @@ Type t when Array.Exists(AuthorizedNonStringTypes, at => at == t) => builder.Add
return database.ExecuteNonQuery(statement);
}

/// <summary>
/// Clear all in the database.
/// </summary>
/// <param name="database">SQL Server database which the data have to be deleted.</param>
public static void ClearAllData(this SqlServerDatabase database)
{
database.ExecuteNonQuery("EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'");
Expand Down Expand Up @@ -113,15 +141,15 @@ private sealed class SqlInsertStatementBuilder
public SqlInsertStatementBuilder(string tableName)
{
this.tableName = tableName;
this.columns = new();
this.currentRecord = new();
this.records = new();
this.columns = [];
this.currentRecord = [];
this.records = [];
}

public SqlInsertStatementBuilder NewRecord()
{
this.records.Add(this.currentRecord);
this.currentRecord = new();
this.currentRecord = [];

return this;
}
Expand Down
24 changes: 20 additions & 4 deletions src/UnitTests.Databases.SqlServer/SqlServerDatabaseInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,26 @@ namespace PosInformatique.UnitTests.Databases.SqlServer
{
using Microsoft.Data.SqlClient;

/// <summary>
/// Initializer used to initialize the database for the unit tests.
/// Call the <see cref="Initialize(string, string)"/> method to initialize a database from
/// a DACPAC file.
/// </summary>
/// <remarks>The database will be created the call of the <see cref="Initialize(string, string)"/> method. For the next calls
/// the database is preserved but all the data are deleted.</remarks>
public class SqlServerDatabaseInitializer
{
public bool IsDeployed { get; set; }

/// <summary>
/// Gets or sets a value indicating whether if the database has been initialized.
/// </summary>
public bool IsInitialized { get; set; }

/// <summary>
/// Initialize a SQL Server database from a DACPAC file.
/// </summary>
/// <param name="packageName">Full path of the DACPAC file.</param>
/// <param name="connectionString">Connection string to the SQL Server with administrator rights.</param>
/// <returns>An instance of the <see cref="SqlServerDatabase"/> which allows to perform query to initialize the data.</returns>
public SqlServerDatabase Initialize(string packageName, string connectionString)
{
var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
Expand All @@ -20,7 +36,7 @@ public SqlServerDatabase Initialize(string packageName, string connectionString)

SqlServerDatabase database;

if (!this.IsDeployed)
if (!this.IsInitialized)
{
if (!string.IsNullOrWhiteSpace(connectionStringBuilder.UserID))
{
Expand All @@ -31,7 +47,7 @@ IF SUSER_ID ('{connectionStringBuilder.UserID}') IS NULL

database = server.DeployDacPackage(packageName, connectionStringBuilder.InitialCatalog);

this.IsDeployed = true;
this.IsInitialized = true;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 7d2a3ca

Please sign in to comment.