using MySqlConnector;
using System.Collections.Concurrent;
using System.Text.RegularExpressions;
namespace YLErp.BLL
{
///
/// 跨库 SQL 的物理库名解析器:代码里只写逻辑连接名(appsettings ConnectionStrings 的 key,
/// 与 Java @Mapper 指定数据源名同语义),物理库名由各环境连接串的 database= 决定——
/// 同一逻辑库在不同环境库名不同(如 bigdata 在测试环境为 glms_bigdata),SQL 中硬编码库名会跨环境失败。
/// 用法:{@DbSchema.Of("bigdata")}.mf_fundarchives(返回带反引号的库名,可直接内插)。
/// 仅标识自家的 appsettings 连接串,值不来自用户输入;仍做 \w+ 白名单校验防御配置笔误。
///
public static class DbSchema
{
private static readonly ConcurrentDictionary Cache = new();
private static readonly Regex SafeIdentifier = new(@"^\w+$", RegexOptions.Compiled);
///
/// 取逻辑连接名对应的物理库名(形如 `glms_bigdata`,含反引号)。配置缺失或库名非法立即抛错——
/// 跨库 SQL 拼错库名在运行期才暴露更难排查,配置错误应尽早失败。
///
public static string Of(string connectionKey)
{
return Cache.GetOrAdd(connectionKey, key =>
{
var connectionString = AppManager.GetConnectionString(key);
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new InvalidOperationException($"跨库SQL依赖的连接串未配置:{key}");
}
var database = new MySqlConnectionStringBuilder(connectionString).Database;
if (string.IsNullOrWhiteSpace(database) || !SafeIdentifier.IsMatch(database))
{
throw new InvalidOperationException($"连接串 {key} 缺少 database 或库名非法:{database}");
}
return "`" + database + "`";
});
}
}
}