Skip to content

Commit

Permalink
Add database connection validation and reorganize project structure
Browse files Browse the repository at this point in the history
The code adds a validation for database connections along with appropriate error handling. It also refactors the codebase structure including string extension methods that have been moved to a new folder. Furthermore, test project references have been updated and new configuration files added.
  • Loading branch information
Gary Woodfine committed Mar 26, 2024
1 parent 93f0c32 commit 777bb1d
Show file tree
Hide file tree
Showing 18 changed files with 253 additions and 47 deletions.
15 changes: 15 additions & 0 deletions src/Configuration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,19 @@
<None Include="../icon.png" Pack="true" PackagePath="\" />
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="ConfigurationErrors.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ConfigurationErrors.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Compile Update="ConfigurationErrors.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ConfigurationErrors.resx</DependentUpon>
</Compile>
</ItemGroup>
</Project>
54 changes: 54 additions & 0 deletions src/ConfigurationErrors.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions src/ConfigurationErrors.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>

<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">

</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DatabaseConnectionError" xml:space="preserve">
<value>The connection to the database failed. Review your connection string information and ensure it valid or that you have access to the database server. </value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Threenine.Configurations.PostgreSql;
using Threenine.Database.Extensions;
using Threenine.Models;

namespace Threenine.Database.Configuration.PostgreSql;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Threenine.Database.Extensions;
using Threenine.Models;

namespace Threenine.Configurations.PostgreSql;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Threenine.Database.Extensions;
using Threenine.Models;

namespace Threenine.Configurations.SqlServer;
Expand Down
1 change: 1 addition & 0 deletions src/Configurations/SqlServer/ValueListTypeConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Threenine.Database.Extensions;
using Threenine.Models;

namespace Threenine.Configurations.SqlServer;
Expand Down
5 changes: 5 additions & 0 deletions src/Exceptions/DatabaseConfigurationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System;

namespace Threenine.Database.Exceptions;

public class DatabaseConfigurationException(string message) : Exception(message);
5 changes: 5 additions & 0 deletions src/Exceptions/DatabaseConnectionStringException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System;

namespace Threenine.Exceptions;

public class DatabaseConnectionStringException(string message) : Exception(message);
26 changes: 26 additions & 0 deletions src/Extensions/ConnectionStringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Data.Common;
using Threenine.Database.Exceptions;

namespace Threenine.Database.Extensions;

public static class ConnectionStringExtensions
{
public static bool Validate(this string connectionString)
{
try
{
var factory = DbProviderFactories.GetFactory(connectionString);
using var connection = factory.CreateConnection();
if (connection == null)
throw new DatabaseConfigurationException(ConfigurationErrors.DatabaseConnectionError);

connection.Open();
return true;
}
catch (Exception e)

Check warning on line 21 in src/Extensions/ConnectionStringExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used

Check warning on line 21 in src/Extensions/ConnectionStringExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used

Check warning on line 21 in src/Extensions/ConnectionStringExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used
{
throw new DatabaseConfigurationException(ConfigurationErrors.DatabaseConnectionError);
}
}
}
27 changes: 27 additions & 0 deletions src/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text;

namespace Threenine.Database.Extensions;

public static class StringExtensions
{
public static string ToSnakeCase(this string text)
{
var sb = new StringBuilder();
sb.Append(char.ToLowerInvariant(text[0]));
for (var i = 1; i < text.Length; ++i)
{
var c = text[i];
if (char.IsUpper(c))
{
sb.Append('_');
sb.Append(char.ToLowerInvariant(c));
}
else
{
sb.Append(c);
}
}

return sb.ToString();
}
}
22 changes: 0 additions & 22 deletions src/StringExtensions.cs

This file was deleted.

28 changes: 28 additions & 0 deletions src/Validators/ConnectionsStrings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Data.Common;
using Threenine.Database;
using Threenine.Database.Exceptions;
using Threenine.Exceptions;

namespace Threenine.Validators;

public class ConnectionsStrings
{
public bool Validate(string connectionString)
{
try
{
var factory = DbProviderFactories.GetFactory(connectionString);
using var connection = factory.CreateConnection();
if (connection == null)
throw new DatabaseConfigurationException(ConfigurationErrors.DatabaseConnectionError);

connection.Open();
return true;
}
catch (Exception e)

Check warning on line 23 in src/Validators/ConnectionsStrings.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used

Check warning on line 23 in src/Validators/ConnectionsStrings.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used

Check warning on line 23 in src/Validators/ConnectionsStrings.cs

View workflow job for this annotation

GitHub Actions / build

The variable 'e' is declared but never used
{
throw new DatabaseConfigurationException(ConfigurationErrors.DatabaseConnectionError);
}
}
}
33 changes: 33 additions & 0 deletions tests/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"/>
<PropertyGroup>
<IsPackable>False</IsPackable>
<IsTestProject>true</IsTestProject>
<RootNamespace>Threenine.Database.Configuration.Tests</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" />
<PackageReference Include="FluentValidation"/>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions"/>
<PackageReference Include="FluentAssertions"/>
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="NSubstitute"/>
<PackageReference Include="xunit"/>
<PackageReference Include="xunit.runner.visualstudio"/>
<PackageReference Include="NBuilder"/>
<PackageReference Include="Moq"/>
<PackageReference Include="Shouldly"/>
<PackageReference Include="coverlet.collector"/>
<PackageReference Include="coverlet.msbuild"/>
</ItemGroup>


<ItemGroup>
<Using Include="Xunit"/>
<Using Include="FluentAssertions"/>
<Using Include="NSubstitute"/>
<Using Include="Shouldly"/>

</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions tests/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.3" />
<PackageVersion Include="Npgsql" Version="8.0.2" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="3.8.0" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="FluentValidation" Version="11.9.0" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.0" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="xunit" Version="2.6.6" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
<PackageVersion Include="NBuilder" Version="6.1.0" />
<PackageVersion Include="Moq" Version="4.20.70" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.0" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions tests/Unit/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"/>

</Project>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Threenine;
using Threenine.Database.Extensions;
using Xunit;

namespace Unit.Tests;
namespace Unit.Tests.Extensions;

public class StringExtensionTests
{
Expand Down
25 changes: 2 additions & 23 deletions tests/Unit/Unit.csproj
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<IsPackable>false</IsPackable>
<RootNamespace>Unit.Tests</RootNamespace>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.10" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="NBuilder" Version="6.1.0" />
<PackageReference Include="Shouldly" Version="4.0.3" />
<PackageReference Include="Threenine.Data" Version="3.2.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\..\src\Configuration.csproj" />
Expand Down

0 comments on commit 777bb1d

Please sign in to comment.