tijian_tieying/web/cyqdata-master/DAL/DalCreate.cs
2025-02-20 12:14:39 +08:00

414 lines
16 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Text;
using CYQ.Data.Tool;
using System.Threading;
using System.IO;
namespace CYQ.Data
{
/// <summary>
/// 数据库类型操作类
/// </summary>
internal class DalCreate
{
private const string SqlClient = "System.Data.SqlClient";
private const string OleDb = "System.Data.OleDb";
private const string OracleClient = "System.Data.OracleClient";
private const string SQLiteClient = "System.Data.SQLite";
private const string MySqlClient = "MySql.Data.MySqlClient";
private const string SybaseClient = "Sybase.Data.AseClient";
private const string PostgreClient = "System.Data.NpgSqlClient";
private const string TxtClient = "CYQ.Data.TxtClient";
private const string XmlClient = "CYQ.Data.XmlClient";
private const string XHtmlClient = "CYQ.Data.XHtmlClient";
/// <summary>
/// 简单工厂Factory Method
/// </summary>
/// <param name="dbConn"></param>
/// <returns></returns>
public static DbBase CreateDal(string dbConn)
{
DbBase db = GetDbBaseBy(GetConnObject(dbConn));
if (db.connObject.Master.ConfigName != dbConn && dbConn.EndsWith("Conn"))//需要切换配置。
{
DbResetResult result = db.ChangeDatabase(dbConn.Substring(0, dbConn.Length - 4));
if (result == DbResetResult.Yes) // 写入缓存
{
if (!connDicCache.ContainsKey(dbConn))
{
connDicCache.Set(dbConn, db.connObject);
}
}
}
return db;
//ConnEntity cEntity = GetConnString(dbConn);
//DbBase db = GetDbBaseBy(cEntity.Conn, cEntity.ProviderName);
//db.connObject = cEntity;
//return db;
}
public static DalType GetDalTypeByConn(string conn)
{
return GetConnBean(conn).ConnDalType;
}
public static DalType GetDalTypeByReaderName(string typeName)
{
switch (typeName.Replace("DataReader", "").ToLower())
{
case "oracle":
return DalType.Oracle;
case "sql":
return DalType.MsSql;
case "sqlite":
return DalType.SQLite;
case "oledb":
return DalType.Access;
case "mysql":
return DalType.MySql;
case "odbc":
case "ase":
return DalType.Sybase;
case "PgSql":
case "Npgsql":
return DalType.PostgreSQL;
default:
return DalType.None;
}
}
public static string GetProvider(string connString)
{
connString = connString.ToLower().Replace(" ", "");//去掉空格
if (connString.Contains("initialcatalog=") || connString.Contains("port=1433"))
{
return SqlClient;
}
else if (connString.Contains("microsoft.jet.oledb.4.0") || connString.Contains("microsoft.ace.oledb") || connString.Contains(".mdb"))
{
return OleDb;
}
else if (connString.Contains("provider=msdaora") || connString.Contains("provider=oraoledb.oracle")
|| connString.Contains("description=") || connString.Contains("fororacle"))
{
return OracleClient;
}
else if (connString.Contains("failifmissing=") || (connString.StartsWith("datasource=") && connString.EndsWith(".db")))
{
return SQLiteClient;
}
else if (connString.Contains("convertzerodatetime") || (connString.Contains("host=") && connString.Contains("port=") && connString.Contains("database=")))
{
return MySqlClient;
}
else if (connString.Contains("provider=ase") || (connString.Contains("datasource=") && connString.Contains("port=") && connString.Contains("database=")))
{
return SybaseClient;
}
else if (connString.Contains("port=5432"))
{
return PostgreClient;
}
else if (connString.Contains("txtpath="))
{
return TxtClient;
}
else if (connString.Contains("xmlpath="))
{
return XmlClient;
}
else
{
//postgre和mssql的链接语句一样这里用database=和uid=顺序来决定database写在后面的为postgre
int dbIndex = connString.IndexOf("database=", StringComparison.OrdinalIgnoreCase);
int uid = connString.IndexOf("uid=", StringComparison.OrdinalIgnoreCase);
if (uid > 0 && uid < dbIndex && File.Exists(AppConfig.RunPath + "Npgsql.dll"))
{
return PostgreClient;
}
return SqlClient;
}
}
public static DalType GetDalType(string providerName)
{
switch (providerName)
{
case SqlClient:
return DalType.MsSql;
case OleDb:
return DalType.Access;
case OracleClient:
return DalType.Oracle;
case SQLiteClient:
return DalType.SQLite;
case MySqlClient:
return DalType.MySql;
case SybaseClient:
return DalType.Sybase;
case PostgreClient:
return DalType.PostgreSQL;
case TxtClient:
return DalType.Txt;
case XmlClient:
return DalType.Xml;
}
return (DalType)Error.Throw(string.Format("GetDalType:{0} No Be Support Now!", providerName));
}
private static DbBase GetDbBaseBy(ConnObject co)
{
string providerName = co.Master.ProviderName;
//License.Check(providerName);//框架模块授权检测。
switch (providerName)
{
case SqlClient:
return new MsSqlDal(co);
case OleDb:
return new OleDbDal(co);
case OracleClient:
return new OracleDal(co);
case SQLiteClient:
return new SQLiteDal(co);
case MySqlClient:
return new MySQLDal(co);
case SybaseClient:
return new SybaseDal(co);
case PostgreClient:
return new PostgreDal(co);
case TxtClient:
case XmlClient:
return new NoSqlDal(co);
}
return (DbBase)Error.Throw(string.Format("GetHelper:{0} No Be Support Now!", providerName));
}
#region
/*
private static MDictionary<string, ConnEntity> connCache = new MDictionary<string, ConnEntity>();
internal static ConnEntity GetConnString(string dbConn) // 思考备份链接的问题。=》下一步思考读写分离的问题。
{
if (connCache.ContainsKey(dbConn))
{
return connCache[dbConn];
}
ConnEntity cEntity = new ConnEntity();
cEntity.Conn = string.IsNullOrEmpty(dbConn) ? AppConfig.DB.DefaultConn : dbConn;
if (cEntity.Conn.Length < 32 && cEntity.Conn.Split(' ').Length == 1)//配置项
{
if (ConfigurationManager.ConnectionStrings[cEntity.Conn] == null && cEntity.Conn != AppConfig.DB.DefaultConn)
{
cEntity.Conn = AppConfig.DB.DefaultConn;//转取默认配置;
if (cEntity.Conn.Length >= 32 || cEntity.Conn.Trim().Contains(" "))
{
goto er;
}
}
if (ConfigurationManager.ConnectionStrings[cEntity.Conn] != null)
{
string p = string.Empty, c = string.Empty;
#region 获取备份链接
string bakKey = cEntity.Conn + "_Bak";
if (ConfigurationManager.ConnectionStrings[cEntity.Conn + "_Bak"] == null && cEntity.Conn == AppConfig.DB.DefaultConn && AppConfig.DB.DefaultConnBak != cEntity.Conn + "_Bak")
{
bakKey = AppConfig.DB.DefaultConnBak;
}
string connBak = AppConfig.GetConn(bakKey, out p);
if (connBak.Length >= 32 || connBak.Trim().Contains(" "))//如果有完整的数据库链接
{
cEntity.ConnBak = AppConfig.GetConn(bakKey, out p);
cEntity.ProviderNameBak = p;
}
#endregion
cEntity.Conn = AppConfig.GetConn(cEntity.Conn, out p);
cEntity.ProviderName = p;
}
else
{
Error.Throw(string.Format("Can't find the connection key '{0}' from web.config!", cEntity.Conn));
}
}
else if (cEntity.Conn == AppConfig.DB.DefaultConn && string.IsNullOrEmpty(cEntity.ConnBak))
{
string connBak = AppConfig.GetConn(AppConfig.DB.DefaultConnBak);//先赋默认备份值。
if (connBak.Length >= 32 || connBak.Trim().Contains(" "))//如果有完整的数据库链接
{
cEntity.ConnBak = connBak;
}
}
er:
if (string.IsNullOrEmpty(cEntity.ProviderName))
{
cEntity.ProviderName = GetProvider(cEntity.Conn);
cEntity.ConnDalType = GetDalType(cEntity.ProviderName);
}
if (string.IsNullOrEmpty(cEntity.ProviderNameBak) && !string.IsNullOrEmpty(cEntity.ConnBak))
{
cEntity.ProviderNameBak = DalCreate.GetProvider(cEntity.ConnBak);
cEntity.ConnBakDalType = GetDalType(cEntity.ProviderNameBak);
}
cEntity.Conn = string.Format(cEntity.Conn, AppConfig.WebRootPath);
cEntity.ConnBak = string.Format(cEntity.ConnBak ?? string.Empty, AppConfig.WebRootPath);
if (!connCache.ContainsKey(dbConn))
{
connCache.Set(dbConn, cEntity);
}
return cEntity;
}
*/
#endregion
internal static string FormatConn(DalType dal, string connString)
{
if (dal != DalType.Access)
{
string conn = connString.ToLower();
int index = conn.IndexOf("provider");
if (index > -1 && index < connString.Length - 5 && (connString[index + 8] == '=' || connString[index + 9] == '='))
{
int end = conn.IndexOf(';', index);
if (end > index)
{
connString = connString.Remove(index, end - index + 1);
}
}
}
return connString;
}
/// <summary>
/// 所有链接的对象集合
/// </summary>
private static MDictionary<string, ConnObject> connDicCache = new MDictionary<string, ConnObject>(StringComparer.OrdinalIgnoreCase);
internal static ConnObject GetConnObject(string dbConn)
{
dbConn = string.IsNullOrEmpty(dbConn) ? AppConfig.DB.DefaultConn : dbConn;
if (dbConn.EndsWith("_Bak")) { dbConn = dbConn.Replace("_Bak", ""); }
if (connDicCache.ContainsKey(dbConn))
{
return connDicCache[dbConn];
}
ConnBean cbMaster = GetConnBean(dbConn);
if (cbMaster == null)
{
string errMsg = string.Format("Can't find the connection key '{0}' from web.config or app.config!", dbConn);
if (dbConn == AppConfig.DB.DefaultConn)
{
Error.Throw(errMsg);
}
else
{
ConnBean cb = GetConnBean(AppConfig.DB.DefaultConn);
if (cb != null)
{
cbMaster = cb.Clone();//获取默认的值。
}
else
{
Error.Throw(errMsg);
}
}
}
ConnObject co = new ConnObject();
co.Master = cbMaster;
if (dbConn != null && dbConn.Length < 32 && !dbConn.Trim().Contains(" ")) // 为configKey
{
ConnBean coBak = GetConnBean(dbConn + "_Bak");
if (coBak != null && coBak.ProviderName == cbMaster.ProviderName)
{
co.BackUp = coBak;
}
for (int i = 1; i < 1000; i++)
{
ConnBean cbSlave = GetConnBean(dbConn + "_Slave" + i);
if (cbSlave == null)
{
break;
}
cbSlave.IsSlave = true;
co.Slave.Add(cbSlave);
}
}
if (!connDicCache.ContainsKey(dbConn) && co.Master.ConfigName == dbConn) // 非一致的,由外面切换后再缓存
{
connDicCache.Set(dbConn, co);
}
return co;
}
private static ConnBean GetConnBean(string dbConn)
{
string provider;
string conn = string.Format(AppConfig.GetConn(dbConn, out provider), AppConfig.WebRootPath);
if (string.IsNullOrEmpty(conn))
{
return null;
}
ConnBean cb = new ConnBean();
cb.ConfigName = dbConn;
cb.Conn = conn;
if (string.IsNullOrEmpty(provider))
{
provider = GetProvider(cb.Conn);
}
cb.ProviderName = provider;
cb.ConnDalType = GetDalType(provider);
return cb;
}
/// <summary>
/// 定时检测异常的链接是否恢复。
/// </summary>
/// <param name="threadID"></param>
public static void CheckConnIsOk(object threadID)
{
while (true)
{
Thread.Sleep(3000);
if (connDicCache.Count > 0)
{
try
{
string[] items = new string[connDicCache.Count];
connDicCache.Keys.CopyTo(items, 0);
foreach (string key in items)
{
ConnObject obj = connDicCache[key];
if (obj != null)
{
if (!obj.Master.IsOK) { obj.Master.TryTestConn(); }
if (obj.BackUp != null && !obj.BackUp.IsOK) { obj.BackUp.TryTestConn(); }
if (obj.Slave != null && obj.Slave.Count > 0)
{
for (int i = 0; i < obj.Slave.Count; i++)
{
if (!obj.Slave[i].IsOK)
{
obj.Slave[i].TryTestConn();
}
}
}
}
}
items = null;
}
catch
{
}
}
}
}
}
}