feat(#I12XDG): 自动建库

#Comment
comment #I12XDG

#Issue
link #I12XDG
This commit is contained in:
Argo Zhang 2019-10-01 22:50:57 +08:00
parent d2e5122a1d
commit acebe33cad
No known key found for this signature in database
GPG Key ID: 152E398953DDF19F
7 changed files with 162 additions and 1 deletions

View File

@ -1,5 +1,9 @@
# init sqlserver database
$startPath = "Z:\src\Longbow\BootstrapAdmin\DatabaseScripts\SqlServer"
$startPath = $args[0]
if ($startPath -eq $null) {
$startPath = "Z:\src\Longbow\BootstrapAdmin\db\SqlServer"
}
$sqlInstance = "localhost"
$outFile = join-path $startPath "output.log"
$sqlFile = join-path $startPath "Install.sql"

View File

@ -0,0 +1,24 @@
using Bootstrap.DataAccess.Helper;
namespace Microsoft.AspNetCore.Builder
{
/// <summary>
/// 自动生成数据库扩展操作类
/// </summary>
public static class AutoGenerateDatabaseExtensions
{
/// <summary>
/// 自动生成数据库中间件
/// </summary>
/// <param name="app"></param>
public static IApplicationBuilder UseAutoGenerateDatabase(this IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
AutoDbHelper.CheckDB();
await next();
});
return app;
}
}
}

View File

@ -23,6 +23,7 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Sentry.AspNetCore" Version="2.0.0-beta4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc3" />
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
</ItemGroup>
<ItemGroup>

View File

@ -115,6 +115,7 @@ namespace Bootstrap.Admin
app.UseHttpsRedirection();
app.UseResponseCompression();
app.UseStaticFiles();
app.UseAutoGenerateDatabase();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

View File

@ -19,6 +19,7 @@
{
"Enabled": false,
"ProviderName": "SqlServer",
"SqlFolder": "Z:\\src\\Longbow\\BootstrapAdmin\\db\\SqlServer",
"ConnectionStrings": {
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
}
@ -26,6 +27,7 @@
{
"Enabled": true,
"ProviderName": "Sqlite",
"SqlFolder": "Z:\\src\\Longbow\\BootstrapAdmin\\db\\SQLite",
"ConnectionStrings": {
"ba": "Data Source=BootstrapAdmin.db;"
}
@ -33,6 +35,7 @@
{
"Enabled": false,
"ProviderName": "MySql",
"SqlFolder": "Z:\\src\\Longbow\\BootstrapAdmin\\db\\MySQL",
"ConnectionStrings": {
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
}
@ -48,6 +51,7 @@
"Enabled": false,
"Widget": "Bootstrap.DataAccess.MongoDB",
"ProviderName": "MongoDB",
"SqlFolder": "Z:\\src\\Longbow\\BootstrapAdmin\\db\\MongoDB",
"ConnectionStrings": {
"ba": "mongodb://localhost:27017/BootstrapAdmin"
}

View File

@ -0,0 +1,114 @@
using Longbow.Configuration;
using Microsoft.Extensions.Configuration;
using PetaPoco;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Bootstrap.DataAccess
{
/// <summary>
/// 数据库自动生成实体类
/// </summary>
public class AutoDB
{
private static bool _init = false;
private static object _locker = new object();
/// <summary>
/// 数据库检查方法
/// </summary>
public void CheckDB()
{
if (_init) return;
// 阻止所有线程继续往下运行,等待数据库检查
lock (_locker)
{
if (_init) return;
// 数据检查
Check();
}
}
private void Check()
{
var dbSection = ConfigurationManager.GetSection("DB").GetChildren().FirstOrDefault(c => c.GetValue("Enabled", false));
if (dbSection == null)
{
_init = true;
return;
}
var folder = dbSection["SqlFolder"];
if (folder.IsNullOrEmpty())
{
_init = true;
return;
}
var db = Longbow.Data.DbManager.Create();
CheckDbExists(db, folder);
_init = true;
}
private void CheckDbExists(IDatabase db, string folder)
{
db.CommandTimeout = 5000;
switch (db.Provider.GetType().Name)
{
case "SQLiteDatabaseProvider":
if (db.ExecuteScalar<int>("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='Users'") == 0) GenerateSQLiteDB(db, folder);
break;
case "SqlServerDatabaseProvider":
var newDB = ModifyConnectionString(db);
if (newDB.ExecuteScalar<int?>("select COUNT(1) from sys.databases where name = N'BootstrapAdmin'") == 0) GenerateSqlServer(folder);
break;
case "MySqlDatabaseProvider":
case "MariaDbDatabaseProvider":
if (db.ExecuteScalar<int>("select count(*) from information_schema.tables where table_name ='Users' and Table_Schema = 'BootstrapAdmin'") == 0) GenerateMySql(folder);
break;
}
}
private IDatabase ModifyConnectionString(IDatabase db)
{
var conn = db.ConnectionString;
var newsegs = new List<string>();
var segs = conn.SpanSplit(";");
segs.ForEach(s =>
{
if (s.StartsWith("Initial Catalog", StringComparison.OrdinalIgnoreCase)) newsegs.Add("Initial Catalog=master");
else newsegs.Add(s);
});
var provider = db.Provider;
db.Dispose();
return new Database(string.Join(";", newsegs), provider);
}
private void GenerateSQLiteDB(IDatabase db, string folder)
{
var initFile = Path.Combine(folder, "Install.sql");
var sql = File.ReadAllText(initFile);
db.Execute(sql);
initFile = Path.Combine(folder, "InitData.sql");
sql = File.ReadAllText(initFile);
db.Execute(sql);
}
private void GenerateSqlServer(string folder)
{
var psi = new ProcessStartInfo("powershell", Path.Combine(folder, $"install.ps1 \"{folder}\""));
var p = Process.Start(psi);
p.WaitForExit();
}
private void GenerateMySql(string folder)
{
// 没有环境暂时未写代码
}
}
}

View File

@ -0,0 +1,13 @@
namespace Bootstrap.DataAccess.Helper
{
/// <summary>
/// 数据库自动生成帮助类
/// </summary>
public static class AutoDbHelper
{
/// <summary>
/// 数据库检查方法
/// </summary>
public static void CheckDB() => DbContextManager.Create<AutoDB>()?.CheckDB();
}
}