从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
using BaseOUDAL;
|
||||
using YLErp.Commons;
|
||||
|
||||
namespace YLErp.Modules.AppModule.UpgradModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库结构及数据升级服务
|
||||
/// </summary>
|
||||
public class DbUpdateService
|
||||
{
|
||||
const int UpState_Fail = -1;
|
||||
const int UpState_Done = 1;
|
||||
const int UpState_Pending = 0;
|
||||
|
||||
const string UpType_DbUpdate = "DbUpdate";
|
||||
const string ResNameSpacePrefix = "YLErp.Resources.DbUpdate.Ver";
|
||||
|
||||
#region----获取资源文件列表----
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源文件列表
|
||||
/// </summary>
|
||||
public static List<DbUpdateDto> GetUpdateList()
|
||||
{
|
||||
var upList = new List<DbUpdateDto>();
|
||||
var assembly = typeof(YLErp.Resources.PlaceHolder).Assembly;
|
||||
|
||||
foreach (var resName in assembly.GetManifestResourceNames())
|
||||
{
|
||||
//YLErp.Resources.DbUpdate.Ver_3._17.prod.sql
|
||||
|
||||
if (!resName.StartsWith(ResNameSpacePrefix))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var upkey = resName.Substring(ResNameSpacePrefix.Length, resName.Length - ResNameSpacePrefix.Length - 4);
|
||||
var strArr = upkey.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var version = string.Join(".", strArr.Take(strArr.Length - 1).Select(n => n.Substring(1)).ToArray());
|
||||
|
||||
var dto = new DbUpdateDto
|
||||
{
|
||||
UpKey = upkey,
|
||||
Version = version,
|
||||
DbSchema = strArr[^1],
|
||||
UpResult = "未执行"
|
||||
};
|
||||
|
||||
upList.Add(dto);
|
||||
}
|
||||
|
||||
var dic = GetLogs();
|
||||
|
||||
foreach (var dto in upList)
|
||||
{
|
||||
if (dic.TryGetValue(dto.UpKey, out var a))
|
||||
{
|
||||
dto.UpState = a.UpState;
|
||||
dto.UpResult = a.UpResult;
|
||||
}
|
||||
}
|
||||
|
||||
return upList.OrderByDescending(x => x.Version + ".").ThenBy(n => n.DbSchema).ToList();
|
||||
}
|
||||
|
||||
private static Dictionary<string, InnerDbLog> GetLogs()
|
||||
{
|
||||
InnerDbLog[] getLogs(DbSet<SysUpdateLog> dbset)
|
||||
{
|
||||
var startDate = DateTime.Today.AddMonths(-6);
|
||||
|
||||
var baseQry = from a in dbset
|
||||
where a.CreateTime > startDate && a.UpType == UpType_DbUpdate
|
||||
select a;
|
||||
|
||||
var groupQry = from a in baseQry
|
||||
group a by a.UpKey into g
|
||||
select new { id = g.Max(n => n.id) };
|
||||
|
||||
var listQry = from g in groupQry
|
||||
join a in baseQry on g.id equals a.id
|
||||
select new InnerDbLog
|
||||
{
|
||||
UpKey = a.UpKey,
|
||||
UpResult = a.UpResult,
|
||||
UpState = a.UpState
|
||||
};
|
||||
|
||||
return listQry.ToArray();
|
||||
}
|
||||
|
||||
var list = new List<InnerDbLog>(100);
|
||||
|
||||
using (var db = DbContextFactory.GetYLDbContext())
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
using (var db = DbContextFactory.GetErpBaseContext())
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
using (var db = DbContextFactory.GetClientDbContext(OptUserInfo.SystemUser))
|
||||
{
|
||||
list.AddRange(getLogs(db.SysUpdateLogs));
|
||||
}
|
||||
|
||||
return CollectionHelper.ToDictionary2(list, n => n.UpKey, n => n, StringComparer.OrdinalIgnoreCase, useFirst: true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region----执行数据库脚本升级----
|
||||
|
||||
/// <summary>
|
||||
/// 执行数据库脚本升级
|
||||
/// </summary>
|
||||
public static List<DbUpdateResult> ExecuteUpdate(IEnumerable<string> upKeyList, bool onlyUpdateDone)
|
||||
{
|
||||
var resultList = new List<DbUpdateResult>();
|
||||
|
||||
var exelist = upKeyList.OrderBy(n => n.ToLowerInvariant()).ToArray();
|
||||
|
||||
foreach (var upkey in exelist)
|
||||
{
|
||||
var result = InnerExecuteUpdate(upkey, onlyUpdateDone);
|
||||
|
||||
resultList.Add(result);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行单个更新
|
||||
/// </summary>
|
||||
private static DbUpdateResult InnerExecuteUpdate(string upkey, bool onlyUpdateDone)
|
||||
{
|
||||
var result = new DbUpdateResult { UpKey = upkey, UpState = UpState_Fail };
|
||||
|
||||
if (string.IsNullOrEmpty(upkey))
|
||||
{
|
||||
result.UpResult = "upkey是空值";
|
||||
return result;
|
||||
}
|
||||
|
||||
result.UpState = UpState_Pending;
|
||||
|
||||
var sqlText = string.Empty;
|
||||
|
||||
if (onlyUpdateDone)
|
||||
{
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "手动更新为已执行";
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlText = GetResourceContent(upkey);
|
||||
|
||||
if (sqlText == null)
|
||||
{
|
||||
result.UpState = UpState_Fail;
|
||||
result.UpResult = "没有找到升级脚本";
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(sqlText))
|
||||
{
|
||||
sqlText = string.Empty;
|
||||
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "升级脚本为空";
|
||||
}
|
||||
}
|
||||
|
||||
using (var db = getDbContext(upkey))
|
||||
{
|
||||
if (db == null)
|
||||
{
|
||||
result.UpResult = "未从upkey中解析出正确的数据库";
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result.UpState == UpState_Pending)
|
||||
{
|
||||
try
|
||||
{
|
||||
var changes = db.Database.ExecuteSqlRaw(sqlText);
|
||||
|
||||
result.UpState = UpState_Done;
|
||||
result.UpResult = "执行成功,受影响的行数:" + changes;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.UpState = UpState_Fail;
|
||||
result.UpResult = ex.Messages();
|
||||
}
|
||||
}
|
||||
|
||||
var dblog = new SysUpdateLog()
|
||||
{
|
||||
UpKey = upkey,
|
||||
UpType = UpType_DbUpdate,
|
||||
|
||||
UpState = result.UpState,
|
||||
UpResult = result.UpResult,
|
||||
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
|
||||
db.SysUpdateLogs.Add(dblog);
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
DBContextBase getDbContext(string upkey)
|
||||
{
|
||||
var index = upkey.LastIndexOf('.');
|
||||
var dbSchema = upkey.Substring(index + 1);
|
||||
|
||||
return (dbSchema?.ToLowerInvariant()) switch
|
||||
{
|
||||
"admin" => DbContextFactory.GetErpBaseContext(),
|
||||
"client" => DbContextFactory.GetClientDbContext(OptUserInfo.SystemUser),
|
||||
"prod" => DbContextFactory.GetYLDbContext(),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 查看数据库脚本升级内容
|
||||
/// </summary>
|
||||
public static string GetUpdateContent(IEnumerable<string> upKeyList)
|
||||
{
|
||||
if (upKeyList is null || !upKeyList.Any())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var sb = StringBuilderPool.Acquire();
|
||||
|
||||
var exelist = upKeyList.OrderBy(n =>
|
||||
{
|
||||
var index = n.LastIndexOf('.');
|
||||
return n.Substring(0, index + 1);
|
||||
}).ToArray();
|
||||
|
||||
foreach (var upkey in exelist)
|
||||
{
|
||||
var sqlText = GetResourceContent(upkey);
|
||||
|
||||
sb.AppendLine("-- -----------------------------------------------------------")
|
||||
.Append("-- V").Append(upkey.Replace("_", "")).AppendLine()
|
||||
.AppendLine("-- -----------------------------------------------------------");
|
||||
|
||||
if (sqlText == null)
|
||||
{
|
||||
sb.Append("-- !!!没有找到升级脚本:").Append(upkey).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(sqlText);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.Release();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回资源文件内容,如果是null表示资源不存在
|
||||
/// </summary>
|
||||
private static string GetResourceContent(string upkey)
|
||||
{
|
||||
var resName = string.Concat(ResNameSpacePrefix, upkey, ".sql");
|
||||
|
||||
var assembly = typeof(Resources.PlaceHolder).Assembly;
|
||||
|
||||
using var s = assembly.GetManifestResourceStream(resName);
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using var sr = new StreamReader(s);
|
||||
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
|
||||
class InnerDbLog
|
||||
{
|
||||
public string UpKey { get; set; }
|
||||
|
||||
public string UpResult { get; set; }
|
||||
|
||||
public int UpState { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user