Add MySQL Database

This commit is contained in:
Alex Hyett 2023-06-30 14:37:13 +01:00
parent ec91d04d0a
commit 146f8f6ff4
12 changed files with 137 additions and 16 deletions

View file

@ -43,7 +43,7 @@ public class LibraryController : ControllerBase
} }
[HttpPost(Name = "AddAuthor")] [HttpPost(Name = "AddAuthor")]
public async Task<AuthorResponse> AddauthorAsync(AuthorRequest authorRequest) public async Task<AuthorResponse> AddAuthorAsync(AuthorRequest authorRequest)
{ {
var author = await _libraryService.AddAuthorAsync(authorRequest.Map()); var author = await _libraryService.AddAuthorAsync(authorRequest.Map());
return author.Map(); return author.Map();

View file

@ -14,6 +14,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\GitHubActionsDemo.Service\GitHubActionsDemo.Service.csproj" /> <ProjectReference Include="..\GitHubActionsDemo.Service\GitHubActionsDemo.Service.csproj" />
<ProjectReference Include="..\GitHubActionsDemo.Persistance\GitHubActionsDemo.Persistance.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -1,4 +1,5 @@
using GitHubActionsDemo.Service; using GitHubActionsDemo.Service.Infrastructure;
using GitHubActionsDemo.Persistance.Infrastructure;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -6,8 +7,11 @@ builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen();
builder.Services.Configure<DbSettings>(builder.Configuration.GetSection("DbSettings"));
// DI // DI
builder.Services.AddScoped<ILibraryService, LibraryService>(); builder.Services.AddServiceDependencies();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
@ -17,6 +21,10 @@ if (app.Environment.IsDevelopment())
app.UseSwaggerUI(); app.UseSwaggerUI();
} }
{
await app.InitDatabase();
}
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.Run(); app.Run();

View file

@ -1,4 +1,8 @@
{ {
"DbSettings": {
"ConnectionString": "Server=localhost; Database=library; Uid=root; Pwd=libraryDbPassword;",
"Database": "library"
},
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",

View file

@ -1,4 +1,8 @@
{ {
"DbSettings": {
"ConnectionString": "Server=localhost; Database=library; Uid=root; Pwd=libraryDbPassword;",
"Database": "library"
},
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",

View file

@ -0,0 +1,79 @@
using Dapper;
using MySql.Data.MySqlClient;
using System.Data;
using GitHubActionsDemo.Persistance.Infrastructure;
using Microsoft.Extensions.Options;
namespace GitHubActionsDemo.Persistance;
public class DbContext : IDbContext
{
private readonly DbSettings _dbSettings;
public DbContext(IOptions<DbSettings> dbSettings)
{
_dbSettings = dbSettings?.Value ?? throw new ArgumentNullException(nameof(dbSettings));
}
public IDbConnection CreateConnection()
{
return new MySqlConnection(_dbSettings.ConnectionString);
}
public async Task Init()
{
await InitDatabase();
await InitTables();
}
private async Task InitDatabase()
{
// create database if it doesn't exist
using var connection = new MySqlConnection(_dbSettings.ConnectionString);
var sql = $"CREATE DATABASE IF NOT EXISTS `{_dbSettings.Database}`;";
await connection.ExecuteAsync(sql);
}
private async Task InitTables()
{
// create tables if they don't exist
using var connection = CreateConnection();
await _initAuthors();
await _initBooks();
async Task _initAuthors()
{
var sql = """
CREATE TABLE IF NOT EXISTS Authors (
AuthorId INT NOT NULL AUTO_INCREMENT,
FirstName VARCHAR(255) NOT NULL,
LastName VARCHAR(255) NOT NULL,
DateCreated DATETIME NOT NULL,
DateModified DATETIME NOT NULL,
PRIMARY KEY (AuthorId)
);
""";
await connection.ExecuteAsync(sql);
}
async Task _initBooks()
{
var sql = """
CREATE TABLE IF NOT EXISTS Books(
BookId INT NOT NULL AUTO_INCREMENT,
Title VARCHAR(255),
AuthorId INT NOT NULL,
Isbn VARCHAR(13) NOT NULL,
DatePublished DATETIME NOT NULL,
DateCreated DATETIME NOT NULL,
DateModified DATETIME NOT NULL,
PRIMARY KEY(BookId),
FOREIGN KEY(AuthorId) REFERENCES Authors(AuthorId)
);
""";
await connection.ExecuteAsync(sql);
}
}
}

View file

@ -7,7 +7,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Dapper" Version="2.0.143" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.5" />
<PackageReference Include="MySql.Data" Version="8.0.33" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -0,0 +1,9 @@
using System.Data;
namespace GitHubActionsDemo.Persistance;
public interface IDbContext
{
IDbConnection CreateConnection();
Task Init();
}

View file

@ -0,0 +1,7 @@
namespace GitHubActionsDemo.Persistance.Infrastructure;
public class DbSettings
{
public string ConnectionString { get; set; }
public string Database { get; set; }
}

View file

@ -1,13 +1,20 @@
using GitHubActionsDemo.Persistance; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace GitHubActionsDemo.Service.Infrastructure namespace GitHubActionsDemo.Persistance.Infrastructure;
public static class InfrastructureExtensions
{ {
public static class InfrastructureExtensions public static IServiceCollection AddPersistanceDependencies(this IServiceCollection services)
{ {
public static IServiceCollection AddPersistanceDependencies(this IServiceCollection services) return services.AddSingleton<IDbContext, DbContext>()
{ .AddScoped<ILibraryRespository, LibraryRespository>();
return services.AddSingleton<ILibraryRespository, LibraryRespository>(); }
}
public static async Task InitDatabase(this WebApplication app)
{
using var scope = app.Services.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<IDbContext>();
await context.Init();
} }
} }

View file

@ -1,4 +1,4 @@
using GitHubActionsDemo.Persistance; using GitHubActionsDemo.Persistance.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace GitHubActionsDemo.Service.Infrastructure namespace GitHubActionsDemo.Service.Infrastructure
@ -8,8 +8,8 @@ namespace GitHubActionsDemo.Service.Infrastructure
public static IServiceCollection AddServiceDependencies(this IServiceCollection services) public static IServiceCollection AddServiceDependencies(this IServiceCollection services)
{ {
return services return services
.AddScoped<ILibraryService, LibraryService>() .AddPersistanceDependencies()
.AddPersistanceDependencies(); .AddScoped<ILibraryService, LibraryService>();
} }
} }
} }

View file

@ -34,6 +34,6 @@ public class LibraryService : ILibraryService
public async Task<IEnumerable<Book>> GetBooksAsync(int page, int pageSize) public async Task<IEnumerable<Book>> GetBooksAsync(int page, int pageSize)
{ {
var books = await _libraryRepository.GetBooksAsync(page, pageSize); var books = await _libraryRepository.GetBooksAsync(page, pageSize);
return books.Select(book => book.Map()); return books?.Select(book => book.Map()) ?? new List<Book>();
} }
} }