using CYQ.Data.Tool;
using System.Collections.Generic;
using System.Configuration;
using System.Threading;
namespace CYQ.Data.SQL
{
///
/// 管理数据库(N个库)
///
internal partial class DBSchema
{
///
/// 首次初始化的数据库。
///
private static MDictionary _DBScheams = new MDictionary();
///
/// 获取所有表架构(如果未缓存完成,会重新读取完整后才进行返回(有阻塞可能)
///
public static MDictionary DBScheams
{
get
{
if (!IsInitDBCompleted)
{
InitDBSchemasAgain();
}
return _DBScheams;
}
}
///
/// 获取(并缓存)数据库的“表、视图、存储过程”名称列表。
///
public static DBInfo GetSchema(string conn)
{
ConnBean cb = ConnBean.Create(conn);
if (cb != null)
{
string hash = cb.GetHashKey();
if (!_DBScheams.ContainsKey(hash))
{
DBInfo dbSchema = null;
lock (cb)
{
if (!_DBScheams.ContainsKey(hash))
{
dbSchema = GetSchemaDic(cb.ConnName, false);
}
}
if (dbSchema != null && !_DBScheams.ContainsKey(hash))
{
_DBScheams.Add(hash, dbSchema);
}
}
if (_DBScheams.ContainsKey(hash))
{
return _DBScheams[hash];
}
}
return null;
}
private static DBInfo GetSchemaDic(string conn, bool isIgnoreCache)
{
DBInfo info = new DBInfo();
using (DalBase dal = DalCreate.CreateDal(conn))
{
info.ConnName = dal.ConnObj.Master.ConnName;
info.ConnString = dal.ConnObj.Master.ConnStringOrg;
info.DataBaseName = dal.DataBaseName;
info.DataBaseType = dal.DataBaseType;
Dictionary tables = dal.GetTables(isIgnoreCache);
if (tables != null && tables.Count > 0)
{
MDictionary dic = new MDictionary();
foreach (KeyValuePair item in tables)
{
string hash = TableInfo.GetHashKey(item.Key);
if (!dic.ContainsKey(hash))
{
dic.Add(hash, new TableInfo(item.Key, "U", item.Value, info));
}
}
info.Tables = dic;
}
if (isIgnoreCache)//延迟加载。
{
info.isGetVersion = true;
info.DataBaseVersion = dal.Version;
Dictionary views = dal.GetViews(isIgnoreCache);
if (views != null && views.Count > 0)
{
MDictionary dic = new MDictionary();
foreach (KeyValuePair item in views)
{
string hash = TableInfo.GetHashKey(item.Key);
if (!dic.ContainsKey(hash))
{
dic.Add(hash, new TableInfo(item.Key, "V", item.Value, info));
}
}
info.isGetViews = true;
info.Views = dic;
}
Dictionary procs = dal.GetProcs(isIgnoreCache);
if (procs != null && procs.Count > 0)
{
MDictionary dic = new MDictionary();
foreach (KeyValuePair item in procs)
{
string hash = TableInfo.GetHashKey(item.Key);
if (!dic.ContainsKey(hash))
{
dic.Add(hash, new TableInfo(item.Key, "P", item.Value, info));
}
}
info.isGetProcs = true;
info.Procs = dic;
}
}
}
return info;
}
///
/// 移除数据库缓存
///
///
public static void Remove(string key)
{
_DBScheams.Remove(key);
}
///
/// 清空所有数据库缓存
///
public static void Clear()
{
_DBScheams.Clear();
}
}
///
/// 初始化。
///
internal partial class DBSchema
{
internal static bool IsInitDBCompleted
{
get
{
return _InitFlag <= 0;
}
}
private static int _InitFlag = 1;
///
/// 初始化 基础表结构,只运行1次
///
public static void InitDBSchemasOnStart()
{
List connNames = new List();
foreach (ConnectionStringSettings item in ConfigurationManager.ConnectionStrings)
{
if (!string.IsNullOrEmpty(item.Name) && item.Name.ToLower().EndsWith("conn"))
{
connNames.Add(item.Name);
}
}
_InitFlag = connNames.Count;
if (connNames.Count > 0)
{
foreach (string item in connNames)
{
Thread thread = new Thread(new ParameterizedThreadStart(InitDBSchemaByThreadWork));
thread.Start(item);
}
}
}
private static void InitDBSchemaByThreadWork(object conn)
{
ConnBean cb = ConnBean.Create(conn.ToString());
if (cb == null) { return; }
string key = cb.GetHashKey();
DBInfo info = GetSchemaDic(cb.ConnName, true);
if (!_DBScheams.ContainsKey(key))
{
_DBScheams.Add(key, info);
}
_InitFlag--;
Thread.Sleep(100);//等待其它线程处理完。
var tables = info.Tables;
//初始化表结构
if (tables != null && tables.Count > 0)
{
var keys = tables.GetKeys();
foreach (var tableKey in keys)
{
if (tables.ContainsKey(tableKey))
{
var table = tables[tableKey];
if (table != null)
{
table.Reflesh();
Thread.Sleep(1);
}
}
}
}
var views = info.Views;
if (views != null && views.Count > 0)
{
var keys = views.GetKeys();
foreach (var viewKey in keys)
{
if (views.ContainsKey(viewKey))
{
var view = views[viewKey];
if (view != null)
{
view.Reflesh();
Thread.Sleep(1);
}
}
}
}
}
private static readonly object oo = new object();
public static void InitDBSchemasAgain()
{
if (!IsInitDBCompleted)
{
List connNames = new List();
foreach (ConnectionStringSettings item in ConfigurationManager.ConnectionStrings)
{
if (!string.IsNullOrEmpty(item.Name) && item.Name.ToLower().EndsWith("conn"))
{
connNames.Add(item.Name);
}
}
if (connNames.Count > 0)
{
lock (oo)
{
foreach (string item in connNames)
{
if (IsInitDBCompleted)
{
break;
}
GetSchema(item);
}
}
}
_InitFlag = 0;
}
}
}
}