This commit is contained in:
2025-05-07 18:02:53 +08:00
parent 9a9fd29e1e
commit 084e7b8bbb
14 changed files with 78 additions and 33 deletions

View File

@@ -3,6 +3,7 @@
public record InstallCommand( public record InstallCommand(
string DatabaseType, string DatabaseType,
string DatabaseServer, string DatabaseServer,
string DatabaseVersion,
string DatabaseUser, string DatabaseUser,
string DatabasePassword, string DatabasePassword,
string DatabaseName, string DatabaseName,
@@ -13,7 +14,6 @@
public class InstallCommandHandler( public class InstallCommandHandler(
IConnectionStringProvider connectionStringProvider, IConnectionStringProvider connectionStringProvider,
IHttpContextAccessor accessor,
IMigratorProvider migratorProvider, IMigratorProvider migratorProvider,
IWebHostEnvironment env, IWebHostEnvironment env,
IConfigurationService configurationService, IConfigurationService configurationService,
@@ -26,7 +26,6 @@
private readonly IConfigurationService _configurationService = configurationService; private readonly IConfigurationService _configurationService = configurationService;
private readonly IWebHostEnvironment _env = env; private readonly IWebHostEnvironment _env = env;
private readonly IFileService _fileService = fileService; private readonly IFileService _fileService = fileService;
private readonly IHttpContextAccessor _accessor = accessor;
public async Task<InstallCommandResponse> Handle(InstallCommand request, CancellationToken cancellationToken) public async Task<InstallCommandResponse> Handle(InstallCommand request, CancellationToken cancellationToken)
{ {
if (!string.IsNullOrEmpty(_settings.ConnectionString) && !string.IsNullOrEmpty(_settings.DatabaseType) && !string.IsNullOrEmpty(_settings.DatabaseName)) if (!string.IsNullOrEmpty(_settings.ConnectionString) && !string.IsNullOrEmpty(_settings.DatabaseType) && !string.IsNullOrEmpty(_settings.DatabaseName))
@@ -49,11 +48,11 @@
Enum.TryParse(request.DatabaseType, out DatabaseTypeEnum databaseType); Enum.TryParse(request.DatabaseType, out DatabaseTypeEnum databaseType);
var databaseServer = request.DatabaseServer; var databaseServer = request.DatabaseServer;
var databaseName = request.DatabaseName; var databaseName = request.DatabaseName;
var databaseVersion = request.DatabaseVersion;
var settings = new BlogSettings(); var settings = new BlogSettings();
settings.Url = _accessor.HttpContext?.GetCurrentDomain() ?? "";
settings.DatabaseVersion = databaseVersion;
settings.DatabaseName = databaseName; settings.DatabaseName = databaseName;
settings.DatabaseType = databaseType.ToString(); settings.DatabaseType = databaseType.ToString();
settings.ConnectionString = _connectionStringProvider.GetConnectionString(databaseType, databaseServer, databaseName, request.DatabaseUser, request.DatabasePassword); settings.ConnectionString = _connectionStringProvider.GetConnectionString(databaseType, databaseServer, databaseName, request.DatabaseUser, request.DatabasePassword);

View File

@@ -91,19 +91,23 @@
<option value="PostgreSql">PostgreSQL</option> <option value="PostgreSql">PostgreSQL</option>
</select> </select>
</div> </div>
<div class="form-group" > <div class="form-group" x-show="data.databaseType && data.databaseType=='MySql'">
<label>数据库版本:</label>
<input type="text" class="form-control" x-model="data.databaseVersion" placeholder="请填写数据库版本,如 8.4.5">
</div>
<div class="form-group">
<label>数据库地址:</label> <label>数据库地址:</label>
<input type="text" class="form-control" x-model="data.databaseServer" placeholder="请输入您的数据库地址"> <input type="text" class="form-control" x-model="data.databaseServer" placeholder="请输入您的数据库地址">
</div> </div>
<div class="form-group" > <div class="form-group">
<label>数据库用户名:</label> <label>数据库用户名:</label>
<input type="text" class="form-control" x-model="data.databaseUser" placeholder="请输入您的数据库用户名"> <input type="text" class="form-control" x-model="data.databaseUser" placeholder="请输入您的数据库用户名">
</div> </div>
<div class="form-group" > <div class="form-group">
<label>数据库密码:</label> <label>数据库密码:</label>
<input type="text" class="form-control" x-model="data.databasePassword" placeholder="请输入您的数据库密码"> <input type="text" class="form-control" x-model="data.databasePassword" placeholder="请输入您的数据库密码">
</div> </div>
<div class="form-group" > <div class="form-group">
<label>数据库名称:</label> <label>数据库名称:</label>
<input type="text" class="form-control" x-model="data.databaseName" placeholder="请输入您的数据库名称"> <input type="text" class="form-control" x-model="data.databaseName" placeholder="请输入您的数据库名称">
</div> </div>

View File

@@ -1,6 +1,4 @@
using Microsoft.AspNetCore.Http; namespace Yes.Blog
namespace Yes.Blog
{ {
public static class DependencyInjection public static class DependencyInjection
{ {

View File

@@ -1,7 +1,4 @@
 
using Yes.Application.Installs;
namespace Yes.Blog.Endpoints.Blogs namespace Yes.Blog.Endpoints.Blogs
{ {
public class InstallEndpoint : BlogEndpointScheme, IEndpoint public class InstallEndpoint : BlogEndpointScheme, IEndpoint
@@ -11,6 +8,7 @@ namespace Yes.Blog.Endpoints.Blogs
public record Request( public record Request(
string DatabaseType, string DatabaseType,
string DatabaseServer, string DatabaseServer,
string DatabaseVersion,
string DatabaseUser, string DatabaseUser,
string DatabasePassword, string DatabasePassword,
string DatabaseName, string DatabaseName,

View File

@@ -42,3 +42,6 @@ global using Yes.Infrastructure.Authorizations;
global using Yes.Infrastructure.Middlewares; global using Yes.Infrastructure.Middlewares;
global using Yes.Infrastructure.ViewEngine; global using Yes.Infrastructure.ViewEngine;
global using IResult = Yes.Domain.Core.Models.IResult; global using IResult = Yes.Domain.Core.Models.IResult;
global using Yes.Application.Installs;
global using Scalar.AspNetCore;

View File

@@ -1,7 +1,3 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;
namespace Yes.Blog namespace Yes.Blog
{ {

View File

@@ -2,13 +2,13 @@
{ {
public class BlogSettings public class BlogSettings
{ {
public string ConnectionString { get; set; } public string ConnectionString { get; set; } = "";
public string DatabaseName { get; set; } public string DatabaseName { get; set; } = "";
public string DatabaseType { get; set; }
public string DatabaseType { get; set; } = "";
public string DatabaseVersion { get; set; } = "";
public string Name { get; set; } = "我的博客"; public string Name { get; set; } = "我的博客";
public string Logo { get; set; } = ""; public string Logo { get; set; } = "";

View File

@@ -8,7 +8,7 @@ namespace Yes.Domain.Core.Data
DatabaseTypeEnum GetDatabaseType(); DatabaseTypeEnum GetDatabaseType();
string GetDatabaseVersion();
string GetConnectionStringWithoutDatabase(DatabaseTypeEnum databaseType, string connectionString); string GetConnectionStringWithoutDatabase(DatabaseTypeEnum databaseType, string connectionString);

View File

@@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Http.Extensions; 
namespace Yes.Infrastructure.Authorizations namespace Yes.Infrastructure.Authorizations
{ {

View File

@@ -29,6 +29,11 @@
return databaseType; return databaseType;
} }
public string GetDatabaseVersion()
{
return _settings.DatabaseVersion;
}
public string GetConnectionStringWithoutDatabase(DatabaseTypeEnum databaseType, string connectionString) public string GetConnectionStringWithoutDatabase(DatabaseTypeEnum databaseType, string connectionString)
{ {
var builder = ConnectionStringBuilderFactory.CreateStringBuilder(databaseType, connectionString); var builder = ConnectionStringBuilderFactory.CreateStringBuilder(databaseType, connectionString);

View File

@@ -5,12 +5,13 @@
private readonly string _connectionString; private readonly string _connectionString;
private readonly DatabaseTypeEnum _databaseType; private readonly DatabaseTypeEnum _databaseType;
private readonly string _databaseVersion;
public BlogDbContext(IConnectionStringProvider connectionStringProvider) public BlogDbContext(IConnectionStringProvider connectionStringProvider)
{ {
_connectionString = connectionStringProvider.GetConnectionString(); _connectionString = connectionStringProvider.GetConnectionString();
_databaseType = connectionStringProvider.GetDatabaseType(); _databaseType = connectionStringProvider.GetDatabaseType();
_databaseVersion = connectionStringProvider.GetDatabaseVersion();
} }
@@ -20,7 +21,7 @@
_ = _databaseType switch _ = _databaseType switch
{ {
DatabaseTypeEnum.SqlServer => builder.UseSqlServer(_connectionString), DatabaseTypeEnum.SqlServer => builder.UseSqlServer(_connectionString),
DatabaseTypeEnum.MySql => builder.UseMySql(_connectionString, MySqlServerVersion.AutoDetect(_connectionString)), DatabaseTypeEnum.MySql => builder.UseMySql(_connectionString, string.IsNullOrEmpty(_databaseVersion) ? MySqlServerVersion.AutoDetect(_connectionString) : new MySqlServerVersion(_databaseVersion)),
DatabaseTypeEnum.PostgreSQL => builder.UseNpgsql(_connectionString), DatabaseTypeEnum.PostgreSQL => builder.UseNpgsql(_connectionString),
_ => throw new DatabaseNotSupportedException() _ => throw new DatabaseNotSupportedException()

View File

@@ -43,4 +43,7 @@ global using Yes.Infrastructure.Authorizations.Identity;
global using Yes.Infrastructure.Authorizations.Identity.Authroizations; global using Yes.Infrastructure.Authorizations.Identity.Authroizations;
global using Yes.Infrastructure.Authorizations.Identity.Context; global using Yes.Infrastructure.Authorizations.Identity.Context;
global using Yes.Infrastructure.Data.DbContexts; global using Yes.Infrastructure.Data.DbContexts;
global using Yes.Infrastructure.Migrator.Migrations; global using Yes.Infrastructure.Migrator.Migrations;
global using MySql.Data.MySqlClient;
global using Npgsql;
global using Microsoft.AspNetCore.Http.Extensions;

View File

@@ -27,7 +27,7 @@
return databaseType switch return databaseType switch
{ {
DatabaseTypeEnum.SqlServer => builder.AddSqlServer(), DatabaseTypeEnum.SqlServer => builder.AddSqlServer(),
DatabaseTypeEnum.MySql => builder.AddMySql8().AddMySql5().AddMySql4(), DatabaseTypeEnum.MySql => builder.AddMySql(),
DatabaseTypeEnum.PostgreSQL => builder.AddPostgres(), DatabaseTypeEnum.PostgreSQL => builder.AddPostgres(),
_ => throw new DatabaseNotSupportedException() _ => throw new DatabaseNotSupportedException()

View File

@@ -1,4 +1,6 @@
namespace Yes.Infrastructure.Migrator.Providers 
namespace Yes.Infrastructure.Migrator.Providers
{ {
public class MigratorProvider : IMigratorProvider public class MigratorProvider : IMigratorProvider
{ {
@@ -70,14 +72,50 @@
{ {
case DatabaseTypeEnum.SqlServer: case DatabaseTypeEnum.SqlServer:
var connection = new SqlConnection(connectionStringWithoutDatabase); using (var connection = new SqlConnection(connectionStringWithoutDatabase))
var records = connection.Query($"SELECT name FROM sys.databases WHERE name = '{dbName}';");
if (!records.Any())
{ {
connection.Execute($"CREATE DATABASE {dbName}"); var records = connection.Query($"SELECT name FROM sys.databases WHERE name = '{dbName}';");
if (!records.Any())
{
connection.Execute($"CREATE DATABASE {dbName}");
}
} }
break; break;
case DatabaseTypeEnum.PostgreSQL:
using (var connection = new NpgsqlConnection(connectionStringWithoutDatabase))
{
var exists = connection.ExecuteScalar<bool>(
"SELECT EXISTS(SELECT 1 FROM pg_database WHERE datname = @dbName)",
new { dbName }
);
if (!exists)
{
connection.Execute($"CREATE DATABASE \"{dbName}\" ENCODING = 'UTF8'");
}
}
break;
case DatabaseTypeEnum.MySql:
using (var connection = new MySqlConnection(connectionStringWithoutDatabase)) // 需要 MySql.Data NuGet 包
{
// 参数化查询
var records = connection.Query<string>(
"SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = @dbName",
new { dbName }
);
if (!records.Any())
{
// 指定字符集和排序规则(推荐)
connection.Execute($@"
CREATE DATABASE `{dbName}`
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci");
}
}
break;
} }