Skip to content

Commit

Permalink
Support SQL Server
Browse files Browse the repository at this point in the history
  • Loading branch information
ousiax committed Dec 23, 2023
1 parent c43ef31 commit 8909b89
Show file tree
Hide file tree
Showing 16 changed files with 313 additions and 7 deletions.
15 changes: 15 additions & 0 deletions leo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leo.Wpf.App", "src\Leo.Wpf.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Leo.Wpf.App.Tests", "test\Leo.Wpf.App.Tests\Leo.Wpf.App.Tests.csproj", "{592FA109-B0F2-40F6-8C9F-2DB738109A37}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Leo.Web.Data.SqlServer", "src\Leo.Web.Data.SqlServer\Leo.Web.Data.SqlServer.csproj", "{F78EED74-EA60-4915-B8BF-E4718A7B03B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -171,6 +173,18 @@ Global
{592FA109-B0F2-40F6-8C9F-2DB738109A37}.Release|x64.Build.0 = Release|Any CPU
{592FA109-B0F2-40F6-8C9F-2DB738109A37}.Release|x86.ActiveCfg = Release|Any CPU
{592FA109-B0F2-40F6-8C9F-2DB738109A37}.Release|x86.Build.0 = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|x64.ActiveCfg = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|x64.Build.0 = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|x86.ActiveCfg = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Debug|x86.Build.0 = Debug|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|Any CPU.Build.0 = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|x64.ActiveCfg = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|x64.Build.0 = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|x86.ActiveCfg = Release|Any CPU
{F78EED74-EA60-4915-B8BF-E4718A7B03B1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -187,6 +201,7 @@ Global
{37EAACD0-5191-4033-9BE6-13B93436FC2B} = {3B193AA2-A718-4DBD-9B15-B02A4403628B}
{43C50767-3488-4E68-82BA-247B52AB178E} = {E719A028-C79F-4B69-A87B-614DD4CC5748}
{592FA109-B0F2-40F6-8C9F-2DB738109A37} = {3B193AA2-A718-4DBD-9B15-B02A4403628B}
{F78EED74-EA60-4915-B8BF-E4718A7B03B1} = {E719A028-C79F-4B69-A87B-614DD4CC5748}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DA7F0677-1F7B-476F-A1BF-A55979EDF2E5}
Expand Down
1 change: 1 addition & 0 deletions src/Leo.Web.Api/Leo.Web.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<ItemGroup>
<ProjectReference Include="..\Leo.Web.Data.SQLite\Leo.Web.Data.SQLite.csproj" />
<ProjectReference Include="..\Leo.Web.Data.SqlServer\Leo.Web.Data.SqlServer.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 9 additions & 1 deletion src/Leo.Web.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ public Startup(IConfiguration configuration)

public void ConfigureServices(IServiceCollection services)
{
services.AddDataServices();
var dbEngine = Configuration.GetValue<string>("Database.Engine");
if (dbEngine == null || string.Equals(dbEngine, "mssql", StringComparison.OrdinalIgnoreCase))
{
Leo.Web.Data.SqlServer.ServiceCollectionExtensions.AddDataServices(services);
}
else
{
services.AddDataServices();
}
services.AddControllers(options =>
{
options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Dapper;
using Dapper;
using Leo.Web.Data.Services;
using Leo.Web.Data.SQLite.Repositories;
using Leo.Web.Data.SQLite.TypeHandlers;
using Leo.Web.Data.SqlServer.Repositories;
using Microsoft.Extensions.DependencyInjection;

namespace Leo.Web.Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Leo.Data.Domain.Entities;
using System.Data;

namespace Leo.Web.Data.SQLite.Repositories
namespace Leo.Web.Data.SqlServer.Repositories
{
internal sealed class CustomerDetailRepository : ICustomerDetailRepository
{
Expand Down
2 changes: 1 addition & 1 deletion src/Leo.Web.Data.SQLite/Repositories/CustomerRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Leo.Data.Domain.Entities;
using System.Data;

namespace Leo.Web.Data.SQLite.Repositories
namespace Leo.Web.Data.SqlServer.Repositories
{
internal sealed class CustomerRepository : ICustomerRepository
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Leo.Web.Data.Services;
using Leo.Web.Data.SqlServer.Repositories;
using Microsoft.Extensions.DependencyInjection;

namespace Leo.Web.Data.SqlServer
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDataServices(this IServiceCollection services)
{
services.AddSingleton<IDbConnectionFactory, DbConnectionFactory>();
services.AddScoped<IDatabaseService, DatabaseService>();
services.AddScoped<ICustomerRepository, CustomerRepository>();
services.AddScoped<ICustomerDetailRepository, CustomerDetailRepository>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddCQRS();
return services;
}
}
}
22 changes: 22 additions & 0 deletions src/Leo.Web.Data.SqlServer/Leo.Web.Data.SqlServer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Leo.Web.Data\Leo.Web.Data.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Alyio.Extensions" Version="2.3.0" />
<PackageReference Include="Dapper" Version="2.1.21" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Dapper;
using Leo.Data.Domain.Entities;

namespace Leo.Web.Data.SqlServer.Repositories
{
internal sealed class CustomerDetailRepository : ICustomerDetailRepository
{
private readonly IDbConnectionFactory _dbConnectionManager;

public CustomerDetailRepository(IDbConnectionFactory dbConnectionManager)
{
_dbConnectionManager = dbConnectionManager;
}

public async Task<Guid> CreateAsync(CustomerDetail detail)
{
detail.Id = Guid.NewGuid();

var parameters = new DynamicParameters();
parameters.Add("id", detail.Id);
parameters.Add("customer_id", detail.CustomerId);
parameters.Add("date", detail.Date);
parameters.Add("item", detail.Item);
parameters.Add("count", detail.Count);
parameters.Add("height", detail.Height);
parameters.Add("weight", detail.Weight);
parameters.Add("created_at", detail.CreatedAt);
parameters.Add("created_by", detail.CreatedBy);
var commandText = "INSERT INTO customer_detail (id, customer_id, date, item, count, height, weight,"
+ "created_at, created_by) "
+ "VALUES (@id, @customer_id, @date, @item, @count, @height, @weight, "
+ "@created_at, @created_by)";
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
await conn.ExecuteAsync(cmdDef).ConfigureAwait(false);
return detail.Id;
}

public async Task<CustomerDetail?> GetByIdAsync(Guid id)
{
var commandText = "SELECT * FROM customer_detail WHERE id = @id";
var parameters = new DynamicParameters();
parameters.Add("id", id);
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
return await conn.QueryFirstOrDefaultAsync<CustomerDetail>(cmdDef).ConfigureAwait(false);
}

public async Task<IEnumerable<CustomerDetail>> GetByCustomerIdAsync(Guid customerId)
{
var commandText = "SELECT * FROM customer_detail WHERE customer_id = @customer_id";
var parameters = new DynamicParameters();
parameters.Add("customer_id", customerId);
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
return await conn.QueryAsync<CustomerDetail>(cmdDef).ConfigureAwait(false);
}
}
}
77 changes: 77 additions & 0 deletions src/Leo.Web.Data.SqlServer/Repositories/CustomerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Dapper;
using Leo.Data.Domain.Entities;

namespace Leo.Web.Data.SqlServer.Repositories
{
internal sealed class CustomerRepository : ICustomerRepository
{
private readonly IDbConnectionFactory _dbConnectionManager;

public CustomerRepository(IDbConnectionFactory dbConnectionManager)
{
_dbConnectionManager = dbConnectionManager;
}

public async Task<Customer?> GetAsync(Guid id)
{
var commandText = "SELECT * FROM customer "
+ "WHERE id = @id";
var parameters = new DynamicParameters();
parameters.Add("id", id);
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
return await conn.QueryFirstOrDefaultAsync<Customer>(cmdDef).ConfigureAwait(false);
}

public async Task<IEnumerable<Customer>> GetAsync()
{
var commandText = "SELECT * FROM customer";
var cmdDef = new CommandDefinition(commandText: commandText);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
return await conn.QueryAsync<Customer>(cmdDef).ConfigureAwait(false);
}

public async Task<Guid> CreateAsync(Customer customer)
{
customer.Id = Guid.NewGuid();

var commandText = "INSERT INTO customer (id, name, phone, gender, birthday, cardno,"
+ "created_at, created_by) "
+ "VALUES (@id, @name, @phone, @gender, @birthday, @cardno, "
+ "@created_at, @created_by)";
var parameters = new DynamicParameters();
parameters.Add("id", customer.Id);
parameters.Add("name", customer.Name);
parameters.Add("phone", customer.Phone);
parameters.Add("gender", customer.Gender);
parameters.Add("birthday", customer.Birthday);
parameters.Add("cardno", customer.CardNo);
parameters.Add("created_at", customer.CreatedAt);
parameters.Add("created_by", customer.CreatedBy); ;
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
await conn.ExecuteAsync(cmdDef).ConfigureAwait(false);
return customer.Id;
}

public async Task UpdateAsync(Customer customer)
{
var commandText = "UPDATE customer "
+ "SET name=@name, phone=@phone, gender=@gender, birthday=@birthday, cardno=@cardno, "
+ "updated_at = @updated_at, updated_by = @updated_by "
+ "WHERE id=@id";
var parameters = new DynamicParameters();
parameters.Add("id", customer.Id);
parameters.Add("name", customer.Name);
parameters.Add("phone", customer.Phone);
parameters.Add("gender", customer.Gender);
parameters.Add("birthday", customer.Birthday);
parameters.Add("cardno", customer.CardNo);
parameters.Add("updated_at", customer.UpdatedAt);
parameters.Add("updated_by", customer.UpdatedBy);
var cmdDef = new CommandDefinition(commandText, parameters);
using var conn = await _dbConnectionManager.OpenAsync().ConfigureAwait(false);
await conn.ExecuteAsync(cmdDef).ConfigureAwait(false);
}
}
}
37 changes: 37 additions & 0 deletions src/Leo.Web.Data.SqlServer/SQL/Scripts/customers.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
-- USE [Customers];
-- GO

DROP TABLE IF EXISTS [dbo].[customer];
GO
CREATE TABLE [dbo].[customer]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[name] NVARCHAR(50) NOT NULL,
[phone] NVARCHAR(20) NOT NULL,
[gender] NVARCHAR(10) NULL,
[birthday] DATETIME NULL,
[cardno] NVARCHAR(50) NULL,
[created_at] DATETIME NULL,
[created_by] NVARCHAR(50) NULL,
[updated_at] DATETIME NULL,
[updated_by] NVARCHAR(50) NULL
);
GO

DROP TABLE IF EXISTS [dbo].[customer_detail];
GO
CREATE TABLE [dbo].[customer_detail]
(
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
[customer_id] UNIQUEIDENTIFIER NOT NULL,
[date] DATE NOT NULL,
[item] NVARCHAR(50) NOT NULL,
[count] INT NULL,
[height] NUMERIC(18, 2) NULL,
[weight] NUMERIC(18, 2) NULL,
[created_at] DATETIME NULL,
[created_by] NVARCHAR(50) NULL,
[updated_at] DATETIME NULL,
[updated_by] NVARCHAR(50) NULL
);
GO
10 changes: 10 additions & 0 deletions src/Leo.Web.Data.SqlServer/Services/DatabaseService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Leo.Web.Data.Services
{
internal class DatabaseService : IDatabaseService
{
public Task InitializeAsync()
{
return Task.CompletedTask;
}
}
}
36 changes: 36 additions & 0 deletions src/Leo.Web.Data.SqlServer/Services/DbConnectionFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using System.Data.Common;

namespace Leo.Web.Data.Services
{
internal class DbConnectionFactory : IDbConnectionFactory
{
private readonly IConfiguration _configuration;

public DbConnectionFactory(IConfiguration configuration)
{
_configuration = configuration;
}

public DbConnection Open()
{
var conn = GetDbConnection();
conn.Open();
return conn;
}

public async Task<DbConnection> OpenAsync()
{
var conn = GetDbConnection();
await conn.OpenAsync().ConfigureAwait(false);

return conn;
}

private SqlConnection GetDbConnection()
{
return new SqlConnection(_configuration.GetConnectionString("mssql"));
}
}
}
17 changes: 17 additions & 0 deletions src/Leo.Web.Data.SqlServer/Services/UnitOfWork.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Leo.Web.Data.Services
{
internal sealed class UnitOfWork : IUnitOfWork
{
public UnitOfWork(
ICustomerRepository customerRepository,
ICustomerDetailRepository customerDetailRepository)
{
CustomerRepository = customerRepository;
CustomerDetailRepository = customerDetailRepository;
}

public ICustomerRepository CustomerRepository { get; }

public ICustomerDetailRepository CustomerDetailRepository { get; }
}
}
4 changes: 3 additions & 1 deletion src/Leo.Web.Host/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"Microsoft.AspNetCore": "Warning"
}
},
"Database.Engine": "mssql",
"ConnectionStrings": {
"sqlite": "Data Source=db.web.sqlite"
"sqlite": "Data Source=db.web.sqlite",
"mssql": "Data Source=local.io;Initial Catalog=Customers;User ID=sa;Password=<YourStrong@Passw0rd>;;Encrypt=False"
},
"AzureADJwt": {
"Audience": "747e8097-3a12-4b89-90e3-eef72a4f91b7",
Expand Down
4 changes: 3 additions & 1 deletion src/Leo.Wpf.App/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"Microsoft.AspNetCore": "Warning"
}
},
"Database.Engine": "mssql",
"ConnectionStrings": {
"sqlite": "Data Source=db.sqlite"
"sqlite": "Data Source=db.sqlite",
"mssql": "Data Source=local.io;Initial Catalog=Customers;User ID=sa;Password=<YourStrong@Passw0rd>;Encrypt=False"
},
"WebHostAddressOptions": {
"Paths": {
Expand Down

0 comments on commit 8909b89

Please sign in to comment.