ZhiYeJianKang_PeiXun/cyqdata-master/SQL/Schema/CrossDB.cs
2025-02-20 15:41:53 +08:00

390 lines
14 KiB
C#

using CYQ.Data.Tool;
using System;
using System.Collections.Generic;
using System.Text;
namespace CYQ.Data.SQL
{
/// <summary>
/// 处理跨库访问
/// </summary>
internal class CrossDB
{
public static string GetConnByEnum(Enum tableNameObj)
{
if (tableNameObj == null) { return null; }
string connName = string.Empty;
Type t = tableNameObj.GetType();
string enumName = t.Name;
if (enumName != "TableNames" && enumName != "ViewNames" && enumName != "ProcNames")
{
if (enumName.Length > 1 && enumName[1] == '_')
{
connName = enumName.Substring(2, enumName.Length - 6) + "Conn";
}
else
{
string[] items = t.FullName.Split('.');
if (items.Length > 1)
{
connName = items[items.Length - 2] + "Conn";
items = null;
}
}
}
if (!string.IsNullOrEmpty(connName) && !string.IsNullOrEmpty(AppConfig.GetConn(connName)))
{
return connName;
}
return null;
}
public static string GetConn(string nameOrSql, out string fixName, string priorityConn)
{
string dbName;
return GetConn(nameOrSql, out fixName, priorityConn, out dbName);
}
/// <summary>
/// 获得最优(可能会切换数据库)链接的配置或语句。
/// </summary>
/// <param name="nameOrSql">表名、视图名、存储过程名</param>
/// <returns></returns>
public static string GetConn(string nameOrSql, out string fixName, string priorityConn, out string dbName)
{
string firstTableName = null;
string conn = null;
nameOrSql = nameOrSql.Trim();
fixName = nameOrSql;
dbName = string.Empty;
if (nameOrSql.IndexOf(' ') == -1)//单表。
{
#region
if (nameOrSql.IndexOf('.') > -1) //dbname.tablename
{
string[] items = nameOrSql.Split('.');
dbName = items[0];
conn = dbName + "Conn";
fixName = SqlFormat.NotKeyword(items[items.Length - 1]);
}
else
{
firstTableName = SqlFormat.NotKeyword(nameOrSql);
}
#endregion
}
else
{
if (nameOrSql[0] == '(') // 视图
{
int index = nameOrSql.LastIndexOf(')');
string viewSQL = nameOrSql;
string startSql = viewSQL.Substring(0, index + 1);//a部分
viewSQL = viewSQL.Substring(index + 1).Trim();//b部分。ddd.v_xxx
if (viewSQL.Contains(".") && !viewSQL.Contains(" "))//修改原对像
{
string[] items = viewSQL.Split('.');
fixName = startSql + " " + items[items.Length - 1];
conn = items[0] + "Conn";
}
else
{
firstTableName = GetFirstTableNameFromSql(startSql);
}
}
else
{
//sql 语句
firstTableName = GetFirstTableNameFromSql(nameOrSql);
fixName = SqlCreate.SqlToViewSql(nameOrSql);//Sql修正为视图
}
}
if (!string.IsNullOrEmpty(firstTableName))
{
TableInfo info = GetTableInfoByName(firstTableName, priorityConn);
if (info != null && info.DBInfo != null)
{
if (nameOrSql == firstTableName)
{
fixName = info.Name;
}
conn = info.DBInfo.ConnName;
}
}
return string.IsNullOrEmpty(conn) ? priorityConn : conn;
}
/// <summary>
/// 获得数据库名称。
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string GetDBName(string name)
{
TableInfo info = GetTableInfoByName(name);
if (info != null && info.DBInfo != null)
{
return info.DBInfo.DataBaseName;
}
return "";
}
public static string GetFixName(string name, string conn)
{
TableInfo info = GetTableInfoByName(name, conn);
if (info != null)
{
return info.Name;
}
return name;
}
public static TableInfo GetTableInfoByName(string name)
{
return GetTableInfoByName(name, null);
}
/// <summary>
/// 获得数据库表相关信息(会搜寻最新数据库内容)
/// </summary>
/// <param name="conn">指定时优先寻找。</param>
/// <param name="name">表名</param>
/// <returns></returns>
public static TableInfo GetTableInfoByName(string name, string conn)
{
if (!string.IsNullOrEmpty(name))
{
var dbScheams = DBSchema.DBScheams;
name = SqlFormat.NotKeyword(name);
string tableHash = TableInfo.GetHashKey(name);
if (!string.IsNullOrEmpty(conn))
{
string dbHash = ConnBean.GetHashKey(conn);
if (dbScheams.Count > 0 && dbScheams.ContainsKey(dbHash))
{
TableInfo info = dbScheams[dbHash].GetTableInfoByHash(tableHash);
if (info != null)
{
return info;
}
}
else
{
DBInfo dbInfo = DBSchema.GetSchema(conn);
if (dbInfo != null)
{
TableInfo info = dbInfo.GetTableInfoByHash(tableHash);
if (info != null)
{
return info;
}
}
}
}
else
{
DBInfo dbInfo = DBSchema.GetSchema(AppConfig.DB.DefaultConn);//优先取默认链接
if (dbInfo != null)
{
TableInfo info = dbInfo.GetTableInfoByHash(tableHash);
if (info != null)
{
return info;
}
}
}
List<string> keys = dbScheams.GetKeys();
foreach (string key in keys)
{
if (dbScheams.ContainsKey(key))
{
TableInfo info = dbScheams[key].GetTableInfoByHash(tableHash);
if (info != null)
{
return info;
}
}
}
}
return null;
}
/// <summary>
/// 是否存在指定的表名、视图名、存储过程名
/// </summary>
/// <param name="conn"></param>
/// <returns></returns>
public static bool Exists(string name, string type, string conn)
{
string newName = name;
string newConn = GetConn(newName, out newName, conn);
if (string.IsNullOrEmpty(conn) || (name.Contains("..") && newConn.StartsWith(name.Split('.')[0])))//已指定链接,则不切换链接
{
conn = newConn;
}
//if (DBSchema.DBScheams.Count == 0 && !string.IsNullOrEmpty(conn))
//{
// DBSchema.GetSchema(conn);
//}
if (!string.IsNullOrEmpty(newName))// && DBSchema.DBScheams.Count > 0
{
var dbScheams = DBSchema.DBScheams;
string tableHash = TableInfo.GetHashKey(newName);
if (!string.IsNullOrEmpty(conn))
{
string dbHash = ConnBean.GetHashKey(conn);
if (dbScheams.ContainsKey(dbHash))
{
var db = dbScheams[dbHash];
TableInfo info = db.GetTableInfoByHash(tableHash, type);
if (info == null && type == "U")
{
db.Reflesh(type);//刷新缓存,重新获取
info = db.GetTableInfoByHash(tableHash, type);
}
if (info != null)
{
return true;
}
}
else
{
DBInfo dbInfo = DBSchema.GetSchema(conn);
if (dbInfo != null)
{
TableInfo info = dbInfo.GetTableInfoByHash(tableHash, type);
if (info != null)
{
return true;
}
}
}
}
else
{
List<string> keys = dbScheams.GetKeys();
foreach (string key in keys)
{
if (dbScheams.ContainsKey(key))
{
TableInfo info = dbScheams[key].GetTableInfoByHash(tableHash, type);
if (info != null)
{
return true;
}
}
}
}
}
return false;
}
public static bool Remove(string name, string type, string conn)
{
var dbScheams = DBSchema.DBScheams;
if (!string.IsNullOrEmpty(name) && dbScheams.Count > 0)
{
string newName = name;
string newConn = GetConn(newName, out newName, conn);//可能移到别的库去?
if (string.IsNullOrEmpty(conn) || (name.Contains("..") && newConn.StartsWith(name.Split('.')[0])))//已指定链接,则不切换链接
{
conn = newConn;
}
string tableHash = TableInfo.GetHashKey(newName);
if (!string.IsNullOrEmpty(conn))
{
string dbHash = ConnBean.GetHashKey(conn);
if (dbScheams.ContainsKey(dbHash))
{
if (dbScheams[dbHash].Remove(tableHash, type))
{
dbScheams[dbHash].Reflesh(type);
return true;
}
}
}
else
{
List<string> keys = dbScheams.GetKeys();
foreach (string key in keys)
{
if (dbScheams[key].Remove(tableHash, type))
{
dbScheams[key].Reflesh(type);
return true;
}
}
}
}
return false;
}
public static bool Add(string name, string type, string conn)
{
var dbScheams = DBSchema.DBScheams;
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(type) && dbScheams.Count > 0)
{
string newName = name;
string newConn = GetConn(newName, out newName, conn);
if (string.IsNullOrEmpty(conn) || (name.Contains("..") && newConn.StartsWith(name.Split('.')[0])))//已指定链接,则不切换链接
{
conn = newConn;
}
string tableHash = TableInfo.GetHashKey(newName);
string dbHash = ConnBean.GetHashKey(conn);
if (dbScheams.ContainsKey(dbHash))
{
dbScheams[dbHash].Reflesh(type);
return dbScheams[dbHash].Add(tableHash, type, newName);
}
}
return false;
}
private static string GetFirstTableNameFromSql(string sql)
{
//获取原始表名
string[] items = sql.Replace("\r", " ").Replace("\n", " ").Replace("\t", " ").Split(' ');
if (items.Length == 1) { return sql; }//单表名
if (items.Length > 3) // 总是包含空格的select * from xxx
{
bool startFrom = false;
foreach (string item in items)
{
if (!string.IsNullOrEmpty(item))
{
if (item.ToLower() == "from")
{
startFrom = true;
}
else if (startFrom)
{
if (item[0] == '(')
{
startFrom = false;
}
else
{
string name = item.Split(')')[0];
if (name.IndexOf('.') > -1)
{
if (name.ToLower().StartsWith("dbo."))
{
return name.Substring(4);
}
startFrom = false;
}
else
{
return name;
}
}
}
}
}
return "";
}
return sql;
}
}
}