Skip to content

Commit

Permalink
Added MySQL
Browse files Browse the repository at this point in the history
  • Loading branch information
adimiko committed Feb 9, 2024
1 parent 30f35a4 commit 1a71136
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageVersion Include="Dapper" Version="2.1.28" />
<PackageVersion Include="MySqlConnector" Version="2.3.5" />
<PackageVersion Include="Npgsql" Version="8.0.1" />
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
<PackageVersion Include="Testcontainers.MsSql" Version="3.6.0" />
<PackageVersion Include="Testcontainers.MySql" Version="3.6.0" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="3.7.0" />
<!-- Test references -->
<PackageVersion Include="xunit" Version="2.5.0" />
Expand Down
14 changes: 14 additions & 0 deletions TransactionContext.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionContext.SqlServe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionContext.SqlServer.Tests", "tests\TransactionContext.SqlServer.Tests\TransactionContext.SqlServer.Tests.csproj", "{6807862B-1C93-4669-9764-E09F3516C021}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionContext.MySql", "source\TransactionContext.MySql\TransactionContext.MySql.csproj", "{51BACCCA-9C40-4765-99BB-FC706E289521}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionContext.MySql.Tests", "tests\TransactionContext.MySql.Tests\TransactionContext.MySql.Tests.csproj", "{2D129245-CB43-4937-A6AC-6D8F54F4B355}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -55,6 +59,14 @@ Global
{6807862B-1C93-4669-9764-E09F3516C021}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6807862B-1C93-4669-9764-E09F3516C021}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6807862B-1C93-4669-9764-E09F3516C021}.Release|Any CPU.Build.0 = Release|Any CPU
{51BACCCA-9C40-4765-99BB-FC706E289521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51BACCCA-9C40-4765-99BB-FC706E289521}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51BACCCA-9C40-4765-99BB-FC706E289521}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51BACCCA-9C40-4765-99BB-FC706E289521}.Release|Any CPU.Build.0 = Release|Any CPU
{2D129245-CB43-4937-A6AC-6D8F54F4B355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D129245-CB43-4937-A6AC-6D8F54F4B355}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D129245-CB43-4937-A6AC-6D8F54F4B355}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D129245-CB43-4937-A6AC-6D8F54F4B355}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -67,6 +79,8 @@ Global
{8239CE17-8D34-4344-8F67-A071C393F8AD} = {5A6575AC-81E5-4E97-909F-BBE634A2BD14}
{1FD6D29F-8D6F-479E-8AAA-6D024F3D6579} = {6004A5FC-0B64-464C-977A-5E721E8567B7}
{6807862B-1C93-4669-9764-E09F3516C021} = {5A6575AC-81E5-4E97-909F-BBE634A2BD14}
{51BACCCA-9C40-4765-99BB-FC706E289521} = {6004A5FC-0B64-464C-977A-5E721E8567B7}
{2D129245-CB43-4937-A6AC-6D8F54F4B355} = {5A6575AC-81E5-4E97-909F-BBE634A2BD14}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {48C38B93-C350-4CC9-BCDD-CE256D01DD7E}
Expand Down
19 changes: 19 additions & 0 deletions source/TransactionContext.MySql/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using MySqlConnector;
using System.Data.Common;
using TransactionContext.Configurators;
using TransactionContext.MySql.Internals;

namespace TransactionContext.MySql
{
public static class Extensions
{
public static void UseMySql(
this IDbProviderConfigurator configurator,
string connectionString)
{
configurator.Services.AddSingleton<IDbConnectionFactory>(new MySqlConnectionFactory(connectionString));
configurator.Services.AddScoped<DbBatch, MySqlBatch>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Data.Common;
using MySqlConnector;

namespace TransactionContext.MySql.Internals
{
internal sealed class MySqlConnectionFactory : IDbConnectionFactory
{
private readonly string _connectionString;

public MySqlConnectionFactory(string connectionString) => _connectionString = connectionString;

public DbConnection Create() => new MySqlConnection(_connectionString);
}
}
17 changes: 17 additions & 0 deletions source/TransactionContext.MySql/TransactionContext.MySql.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MySqlConnector" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TransactionContext\TransactionContext.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Dapper;
using TransactionContext.MySql.Tests.SeedWork;
using TransactionContext.Tests.SeedWork;
using Xunit;

namespace TransactionContext.MySql.Tests
{
public sealed class MySqlTransactionContextTests : MySqlContainerTest
{
[Fact]
public async Task BasicTest()
{
// Arrange
const int numberOfCustomers = 100;

for (var i = 0; i < numberOfCustomers; i++)
{
var customerId = Guid.NewGuid();
var orderId = Guid.NewGuid();

TransactionContext.Add(CustomerSQL.Insert, new { CustomerId = customerId, Name = $"name{i}" });
TransactionContext.Add(OrderSQL.Insert, new { OrderId = orderId, CustomerId = customerId });

TransactionContext.Add(OrderItemSQL.Insert, new { OrderItemId = Guid.NewGuid(), OrderId = orderId, Name = $"Name{i}", Amount = i + 1 });
TransactionContext.Add(OrderItemSQL.Insert, new { OrderItemId = Guid.NewGuid(), OrderId = orderId, Name = $"Name{i}", Amount = i + 1 });
TransactionContext.Add(OrderItemSQL.Insert, new { OrderItemId = Guid.NewGuid(), OrderId = orderId, Name = $"Name{i}", Amount = i + 1 });
TransactionContext.Add(OrderItemSQL.Insert, new { OrderItemId = Guid.NewGuid(), OrderId = orderId, Name = $"Name{i}", Amount = i + 1 });
}

// Act
await TransactionContext.Commit();

// Assert
const string selectCustomersSql = "SELECT CustomerId, Name FROM Customers";
using var connection = DbConnectionFactory.Create();
var customers = await connection.QueryAsync<Customer>(selectCustomersSql);

const string selectOrdersSql = "SELECT OrderId, CustomerId FROM Orders";
var orders = await connection.QueryAsync<Order>(selectOrdersSql);

const string selectOrderItemssSql = "SELECT OrderItemId, OrderId, Name, Amount FROM OrderItems";
var orderItems = await connection.QueryAsync<Order>(selectOrderItemssSql);

Assert.Equal(numberOfCustomers, customers.Count());
Assert.Equal(numberOfCustomers, orders.Count());
Assert.Equal(4 * numberOfCustomers, orderItems.Count());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Dapper;
using Microsoft.Extensions.DependencyInjection;
using System;
using Testcontainers.MySql;
using Xunit;

namespace TransactionContext.MySql.Tests.SeedWork
{
public abstract class MySqlContainerTest : IAsyncLifetime
{
private readonly MySqlContainer _container = new MySqlBuilder().Build();

protected ITransactionContext TransactionContext { get; private set; }

Check warning on line 13 in tests/TransactionContext.MySql.Tests/SeedWork/MySqlContainerTest.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'TransactionContext' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

protected IDbConnectionFactory DbConnectionFactory { get; private set; }

Check warning on line 15 in tests/TransactionContext.MySql.Tests/SeedWork/MySqlContainerTest.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'DbConnectionFactory' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public async Task InitializeAsync()
{
await _container.StartAsync();

var connectionString = _container.GetConnectionString();

IServiceCollection services = new ServiceCollection();

services.AddTransactionContext(x => x.UseMySql(connectionString));

var provider = services.BuildServiceProvider();

TransactionContext = provider.GetRequiredService<ITransactionContext>();
DbConnectionFactory = provider.GetRequiredService<IDbConnectionFactory>();

await CreateDb();
}

public Task DisposeAsync()
{
return _container.DisposeAsync().AsTask();
}

private Task CreateDb()
{
const string customerSql = "CREATE TABLE IF NOT EXISTS Customers(CustomerId CHAR(36), Name VARCHAR(100))";
const string orderSql = "CREATE TABLE IF NOT EXISTS Orders(OrderId CHAR(36), CustomerId CHAR(36))";
const string orderItemSql = "CREATE TABLE IF NOT EXISTS OrderItems(OrderItemId CHAR(36), OrderId CHAR(36), Name VARCHAR(100), Amount INT)";

TransactionContext.Add(customerSql);
TransactionContext.Add(orderSql);
TransactionContext.Add(orderItemSql);

return TransactionContext.Commit();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Testcontainers.MySql" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\source\TransactionContext.MySql\TransactionContext.MySql.csproj" />
<ProjectReference Include="..\TransactionContext.Tests.SeedWork\TransactionContext.Tests.SeedWork.csproj" />
</ItemGroup>

</Project>

0 comments on commit 1a71136

Please sign in to comment.