You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

569 lines
24 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using Mesnac.Basic;
using System.Text;
using System.IO;
using System.Xml;
using System.Windows.Forms;
using System.Reflection;
using System.Data.Common;
using ICSharpCode.Core;
using ICSharpCode.Data.Core;
using ICSharpCode.Data.Core.Common;
using ICSharpCode.Data.Core.Interfaces;
using ICSharpCode.Data.Core.DatabaseObjects;
using ICSharpCode.Data.Core.Enums;
using Mesnac.Codd.Session;
namespace Mesnac.Basic
{
public delegate void CallBackDelegate(); //回调方法
/// <summary>
/// 数据源工厂
/// </summary>
public class DataSourceFactory
{
private static DataSourceFactory instance = null; //保存工厂实例
private Dictionary<string, DataSourceItem> _dataSources = null; //保存数据源
private TreeNode root = null;
public event EventHandler DataSourceRefresh;
private DataSourceFactory()
{
this.root = new TreeNode();
root.Text = StringParser.Parse(ResourceService.GetString("Mesnac_Basic_DataSourceFactory_Root_Text")); //"数据源列表";
}
/// <summary>
/// 工厂实例
/// </summary>
public static DataSourceFactory Instance
{
get
{
if (instance == null)
{
instance = new DataSourceFactory();
}
return instance;
}
}
/// <summary>
/// 把内存中的数据源数据保存只文件
/// </summary>
/// <param name="fileName">要保存数据源信息的文件名</param>
public void RefreshDataFromFile(string fileName, params CallBackDelegate[] callBack)
{
if (System.IO.File.Exists(fileName))
{
this._dataSources = XmlHandler.ParseFromDataSourceXml(fileName);
//触发事件
if (DataSourceRefresh != null)
{
DataSourceRefresh(this, EventArgs.Empty);
}
//
if (Mesnac.Basic.AppConfigHelper.GetAppSettingValue("IsLoadDataSourceTree", true))
{
new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
{
LanguageHelper.RefreshCultureInfo();
this.GenerateDataSourceTree();
foreach (CallBackDelegate call in callBack)
{
call();
}
})).Start(); //异步生成数据源树
}
}
else
{
this._dataSources = new Dictionary<string, DataSourceItem>();
}
}
/// <summary>
/// 把文件中的内容读取至内存
/// </summary>
/// <param name="fileName">保存数据源信息的文件名</param>
public void RefreshDataToFile(string fileName, params CallBackDelegate[] callBack)
{
if (this._dataSources != null)
{
XmlHandler.GenerateDataSourceXml(this._dataSources, fileName);
new System.Threading.Thread(new System.Threading.ThreadStart(delegate() {
LanguageHelper.RefreshCultureInfo();
this.GenerateDataSourceTree();
foreach (CallBackDelegate call in callBack)
{
call();
}
})).Start(); //异步生成数据源树
}
}
/// <summary>
/// 数据源信息
/// </summary>
public Dictionary<string, DataSourceItem> DataSources
{
get
{
return this._dataSources;
}
}
/// <summary>
/// 数据源树
/// </summary>
public TreeNode Root
{
get { return this.root; }
}
/// <summary>
/// 生成数据源树
/// </summary>
public void GenerateDataSourceTree()
{
lock (this)
{
try
{
DateTime begin = DateTime.Now;
ICSharpCode.Core.LoggingService<DataSourceFactory>.Debug("GenerateDataSourceTree begin");
this.root.Nodes.Clear();
this.root = new TreeNode();
this.root.Text = StringParser.Parse(ResourceService.GetString("Mesnac_Basic_DataSourceFactory_Root_Text")); //"数据源列表";
if (this._dataSources != null)
{
TreeNode nodeDataSource = null;
int cnt = 0;
DataSourceItem[] dataSourceArr = new DataSourceItem[this._dataSources.Count];
this._dataSources.Values.CopyTo(dataSourceArr, 0);
foreach (DataSourceItem dataSourceItem in dataSourceArr)
{
nodeDataSource = new TreeNode();
nodeDataSource.Text = dataSourceItem.Name;
nodeDataSource.ToolTipText = dataSourceItem.Driver;
#region 数据源处理
//string driverAssembly = dataSourceItem.DriverAssembly;//.Split( new char[] { ',' } )[ 0 ];
//string driverClass = dataSourceItem.DriverClass;
//System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(driverAssembly, driverClass) as System.Runtime.Remoting.ObjectHandle;
string driverAssembly = dataSourceItem.DriverAssembly.IndexOf(",") > 0 ? dataSourceItem.DriverAssembly.Split(new char[] { ',' })[0] : dataSourceItem.DriverAssembly;//.Split( new char[] { ',' } )[ 0 ];
string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
path = new System.IO.FileInfo(path).Directory.FullName;
path = Path.Combine(path, "DynamicLib", "DataBaseDriver", driverAssembly + ".dll");
string driverClass = dataSourceItem.DriverClass;
System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstanceFrom(path, driverClass) as System.Runtime.Remoting.ObjectHandle;
IDatabaseDriver driver = obj.Unwrap() as IDatabaseDriver;
IDatasource ds = driver.CreateNewIDatasource(dataSourceItem.Server, dataSourceItem.UserName, dataSourceItem.Password);
driver.PopulateDatabases(ds);
IDatabase database = null;
if (ds.Databases != null)
{
foreach (IDatabase db in ds.Databases)
{
if (db.ToString() == dataSourceItem.Database)
{
database = db;
break;
}
}
if (database != null)
{
database.LoadDatabase();
TreeNode nodeTables = new TreeNode();
nodeTables.Text = StringParser.Parse(ResourceService.GetString("Mesnac_Basic_DataSourceFactory_nodeTables_Text")); //"数据表";
TreeNode nodeTable = null;
foreach (ITable table in database.Tables)
{
nodeTable = new TreeNode();
nodeTable.Text = table.TableName;
TreeNode nodeColumn = null;
foreach (IColumn col in table.Items)
{
nodeColumn = new TreeNode();
nodeColumn.Text = col.Name;
nodeTable.Nodes.Add(nodeColumn);
}
nodeTables.Nodes.Add(nodeTable);
}
TreeNode nodeViews = new TreeNode();
nodeViews.Text = StringParser.Parse(ResourceService.GetString("Mesnac_Basic_DataSourceFactory_nodeViews_Text")); //"视图";
TreeNode nodeView = null;
if (database.Views != null && database.Views.Count > 0)
{
foreach (IView view in database.Views)
{
nodeView = new TreeNode();
nodeView.Text = view.Name;
TreeNode nodeColumn = null;
foreach (IColumn col in view.Items)
{
nodeColumn = new TreeNode();
nodeColumn.Text = col.Name;
nodeView.Nodes.Add(nodeColumn);
}
nodeViews.Nodes.Add(nodeView);
}
}
TreeNode nodeProcedures = new TreeNode();
nodeProcedures.Text = StringParser.Parse(ResourceService.GetString("Mesnac_Basic_DataSourceFactory_nodeProcedures_Text")); //"存储过程";
TreeNode nodeProcedure = null;
if (database.Procedures != null && database.Procedures.Count > 0)
{
foreach (IProcedure procedure in database.Procedures)
{
nodeProcedure = new TreeNode();
nodeProcedure.Text = procedure.Name;
nodeProcedures.Nodes.Add(nodeProcedure);
}
}
nodeDataSource.Nodes.Add(nodeTables);
nodeDataSource.Nodes.Add(nodeViews);
nodeDataSource.Nodes.Add(nodeProcedures);
}
}
#endregion
cnt++;
if (cnt > dataSourceArr.Length)
break;
this.root.Nodes.Add(nodeDataSource);
}
}
TimeSpan ts = DateTime.Now - begin;
ICSharpCode.Core.LoggingService<DataSourceFactory>.Debug("GenerateDataSourceTree end complete = " + ts);
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Error("获取数据源列表失败:" + ex.Message, ex);
}
}
}
/// <summary>
/// 添加数据源
/// </summary>
/// <param name="name"></param>
/// <param name="item"></param>
public void Add(string name, DataSourceItem item)
{
if (this._dataSources == null)
{
this._dataSources = new Dictionary<string, DataSourceItem>();
}
if (!this.IsExists(name))
{
this._dataSources.Add(name, item);
//触发事件
if (DataSourceRefresh != null)
{
DataSourceRefresh(this, EventArgs.Empty);
}
}
}
/// <summary>
/// 移除数据源
/// </summary>
/// <param name="name"></param>
public void Remove(string name)
{
if (this.IsExists(name))
{
this._dataSources.Remove(name);
//触发事件
if (DataSourceRefresh != null)
{
DataSourceRefresh(this, EventArgs.Empty);
}
}
}
/// <summary>
/// 修改数据源
/// </summary>
/// <param name="name"></param>
/// <param name="newItem"></param>
public void Modify(string name, DataSourceItem newItem)
{
if (this._dataSources == null)
{
this._dataSources = new Dictionary<string, DataSourceItem>();
}
if (this.IsExists(name))
{
this._dataSources[name] = newItem;
//触发事件
if (DataSourceRefresh != null)
{
DataSourceRefresh(this, EventArgs.Empty);
}
}
}
/// <summary>
/// 获取下一个可用的数据源名称
/// </summary>
/// <returns></returns>
public string GetNextDataSourceName()
{
int i = 1;
if (this._dataSources == null)
{
return "DataSource1";
}
else
{
while (this._dataSources.ContainsKey("DataSource" + i))
{
i++;
}
}
return "DataSource" + i;
}
/// <summary>
/// 判断指定名称的数据源是否存在
/// </summary>
/// <param name="dataSourceName">要判断的数据源名称</param>
/// <returns>存在返回true否则返回false</returns>
public bool IsExists(string dataSourceName)
{
if (this._dataSources == null)
{
return false;
}
else
{
if (this._dataSources.ContainsKey(dataSourceName))
{
return true;
}
else
{
return false;
}
}
}
#region DbHelper
/// <summary>
/// 创建数据提供程序工厂对象
/// </summary>
/// <param name="assemblyFile">数据提供程序工厂类所在的程序集文件路径</param>
/// <param name="providerName">数据提供程序工厂类名称</param>
/// <param name="connectionString">数据库连接字符串</param>
/// <returns></returns>
public DbProviderFactory CreateDbProviderFactory(string assemblyFile, string providerName)
{
try
{
DbProviderFactory factory = null;
Assembly assemblyInstance = Assembly.LoadFrom(assemblyFile);
Type providerFactoryType = assemblyInstance.GetType(providerName);
FieldInfo factoryInstance = providerFactoryType.GetField("Instance");
if (factoryInstance != null)
{
factory = factoryInstance.GetValue(null) as DbProviderFactory;
//ICSharpCode.Core.LoggingService<DataSourceFactory>.Debug("创建DbProviderFactory成功!");
}
return factory;
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Error("创建DbProviderFactory错误" + ex.Message);
return null;
}
}
/// <summary>
/// 获取操作系统位版本32位、64位
/// </summary>
/// <returns>返回操作系统版本32、64</returns>
public string GetWinVersion()
{
bool type;
type = Environment.Is64BitOperatingSystem;
if (type)
{
return "64";
}
else
{
return "32";
}
}
/// <summary>
/// 获取DbHelper
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public DbHelper GetDbHelper(DataSourceItem item)
{
string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
path = new System.IO.FileInfo(path).Directory.FullName;
DbProviderFactory dbProviderFactory = null;
if (item.Driver.Replace(" ", "").ToLower() == "mssqlserver")
{
string constr = "Persist Security Info=True;Password=" + item.Password
+ ";User ID=" + item.UserName + ";Initial Catalog=" + item.Database
+ ";Data Source=" + item.Server + ";Connection Timeout=" + item.ConnectionTimeout;
string assemblyFile = Path.Combine(path, "DynamicLib", "DataBase", "SQLServer", "System.Data.dll");
if (!File.Exists(assemblyFile))
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Warn("获取SQLServer连接失败缺少依赖文件" + assemblyFile);
return null;
}
dbProviderFactory = this.CreateDbProviderFactory(assemblyFile, "System.Data.SqlClient.SqlClientFactory");
DbSession dbsession = new DbSession(dbProviderFactory, constr);
DbHelper Result = new DbHelper(dbsession);
return Result;
}
else if (item.Driver.Replace(" ", "").ToLower() == "oracle")
{
string constr = "Data Source={0};Persist Security Info=True;User ID={1};Password={2}";
constr = String.Format(constr, item.Server, item.UserName, item.Password);
string assemblyFile = Path.Combine(path, "DynamicLib", "DataBase", "Oracle", "Oracle.ManagedDataAccess.dll");
if (!File.Exists(assemblyFile))
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Warn("获取Oracle连接失败缺少依赖文件" + assemblyFile);
return null;
}
dbProviderFactory = this.CreateDbProviderFactory(assemblyFile, "Oracle.ManagedDataAccess.Client.OracleClientFactory");
DbSession dbsession = new DbSession(dbProviderFactory, constr);
DbHelper Result = new DbHelper(dbsession);
return Result;
}
else if (item.Driver.Replace(" ", "").ToLower() == "mysql")
{
string constr = "Persist Security Info=True;Password=" + item.Password
+ ";User ID=" + item.UserName + ";Initial Catalog=" + item.Database
+ ";Data Source=" + item.Server;
string assemblyFile = Path.Combine(path, "DynamicLib", "DataBase", "MySql", "MySql.Data.dll");
if (!File.Exists(assemblyFile))
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Warn("获取MySql连接失败缺少依赖文件" + assemblyFile);
return null;
}
//DbSession dbsession = new DbSession(MySql.Data.MySqlClient.MySqlClientFactory.Instance, constr);
dbProviderFactory = this.CreateDbProviderFactory(assemblyFile, "MySql.Data.MySqlClient.MySqlClientFactory");
DbSession dbsession = new DbSession(dbProviderFactory, constr);
DbHelper Result = new DbHelper(dbsession);
return Result;
}
else if (item.Driver.Replace(" ", "").ToLower() == "access")
{
string constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + item.Server
+ ";User ID=" + item.UserName + ";Jet OLEDB:Database Password=" + item.Password;
DbSession dbsession = new DbSession(System.Data.OleDb.OleDbFactory.Instance, constr);
DbHelper Result = new DbHelper(dbsession);
return Result;
}
else
{
string constr = "Persist Security Info=True;Password=" + item.Password
+ ";User ID=" + item.UserName + ";Initial Catalog=" + item.Database
+ ";Data Source=" + item.Server;
string assemblyFile = Path.Combine(path, "DynamicLib", "DataBase", "SQLServer", "System.Data.dll");
if (!File.Exists(assemblyFile))
{
ICSharpCode.Core.LoggingService<DataSourceFactory>.Warn("获取SQLServer连接失败缺少依赖文件" + assemblyFile);
return null;
}
//DbSession dbsession = new DbSession(MySql.Data.MySqlClient.MySqlClientFactory.Instance, constr);
dbProviderFactory = this.CreateDbProviderFactory(assemblyFile, "System.Data.SqlClient.SqlClientFactory");
DbSession dbsession = new DbSession(dbProviderFactory, constr);
DbHelper Result = new DbHelper(dbsession);
return Result;
}
}
public DbHelper GetDbHelper(string dbName)
{
DataSourceItem item;
if (DataSourceFactory.Instance.DataSources != null && DataSourceFactory.Instance.DataSources.TryGetValue(dbName, out item))
{
return GetDbHelper(item);
}
return null;
}
/// <summary>
/// 获取数据源组
/// </summary>
/// <param name="dbType"></param>
/// <returns></returns>
public DataSourceItem GetDataSourceItem(MCDbType dbType)
{
string dbName = this.GetDataSourceName(dbType);
DataSourceItem item;
if (DataSourceFactory.Instance.DataSources != null && DataSourceFactory.Instance.DataSources.TryGetValue(dbName, out item))
{
return item;
}
return null;
}
public DbHelper GetDbHelper(MCDbType dbType)
{
string dbName = this.GetDataSourceName(dbType);
return this.GetDbHelper(dbName);
}
#region GetConfigValue
/// <summary>
/// 数据库枚举类型
/// </summary>
public enum MCDbType
{
/// <summary>
/// 本地库
/// </summary>
Local,
/// <summary>
/// 本地曲线库
/// </summary>
Curve,
/// <summary>
/// MES中间数据库
/// </summary>
MesInterface
/// <summary>
/// 回放数据库
/// </summary>
//BackView
}
/// <summary>
/// 根据数据枚举类型获取数据源名称的方法
/// </summary>
/// <param name="dbtype">数据库枚举类型对象</param>
/// <returns>返回对应的数据源名称</returns>
public string GetDataSourceName(MCDbType dbtype)
{
switch (dbtype)
{
case MCDbType.Local:
return RunSchema.Instance.GetConfigValue("DataSource.Local", "DataSource1");
case MCDbType.Curve:
return RunSchema.Instance.GetConfigValue("DataSource.Curve", "DataSource2");
case MCDbType.MesInterface:
return RunSchema.Instance.GetConfigValue("DataSource.MesInterface", "DataSource3");
default:
return RunSchema.Instance.GetConfigValue("DataSource.Local", "DataSource1");
}
}
#endregion
#endregion
}
}