using Aitex.Common.Util; using Aitex.Core.RT.Log; using Aitex.Core.Util; using System; using System.Collections.Generic; using System.Data.Common; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Npgsql; namespace Aitex.Core.RT.DBCore { public class DataBaseManager : IDataBaseManager { private string _dbName = "sicdb"; private IDataBase _dataBase; private string _sqlFile = PathManager.GetCfgDir() + "DBModel.sql"; private PeriodicJob _monitorJob; private FixSizeQueue _sqlQueue = new FixSizeQueue(1000); public void Initialize() { DB.Manager = this; _dataBase = new PostgreSQLHelper(_dbName); CreateDataBase(); ExecuteScript(_sqlFile); UpdateTable(); _monitorJob = new PeriodicJob(100, Monitor,"DataBaseManager", true); } /// /// 创建数据库 /// public void CreateDataBase() { try { object obj = _dataBase.ExecuteScalar($"select datname from pg_catalog.pg_database where datname='{_dbName}'", false); if (obj == null) { string cmdText = $"CREATE DATABASE {_dbName} WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = pg_default CONNECTION LIMIT = -1"; _dataBase.ExecuteNonQuery(cmdText, false); } } catch (Exception ex) { LOG.Error(ex.Message, ex); } } /// /// 执行SQL脚本 /// /// private void ExecuteScript(string sqlFile) { if (string.IsNullOrEmpty(sqlFile) || !File.Exists(sqlFile)) { LOG.Warning("没有更新Sql数据库,文件:" + sqlFile); return; } try { using StreamReader streamReader = new StreamReader(sqlFile); string cmdText = streamReader.ReadToEnd(); _dataBase.ExecuteNonQuery(cmdText); LOG.Info("Database updated by sql file " + sqlFile); } catch (Exception ex) { LOG.Error(ex.Message, ex); } } /// /// 创建Table /// /// /// /// /// public void CreateTable(string tableName, Dictionary columns, string primaryKey, Type primaryKeyType) { string sql = ""; DbDataReader dataReader = _dataBase.ExecuteReader($"select column_name from information_schema.columns where table_name = '{tableName}'"); if (!dataReader.HasRows) { if (!string.IsNullOrEmpty(primaryKey) && primaryKeyType != null && !columns.Keys.Contains(primaryKey)) { sql += _dataBase.GetSqlByNameType(primaryKey, primaryKeyType); sql += ','; } //列名 foreach (KeyValuePair column in columns) { sql += _dataBase.GetSqlByNameType(column.Key, column.Value); sql += ','; } if (string.IsNullOrEmpty(sql)) { return; } //主键 if (!string.IsNullOrEmpty(primaryKey)) { sql += $"CONSTRAINT \"{tableName}_pkey\" PRIMARY KEY (\"{primaryKey}\" )"; } else { if (!string.IsNullOrEmpty(sql) && sql.LastIndexOf(',') == sql.Length - 1) { sql = sql.Remove(sql.Length - 1); } } sql = $"CREATE TABLE \"{tableName}\"({sql}) WITH ( OIDS=FALSE );"; sql += $"ALTER TABLE \"{tableName}\" OWNER TO postgres;"; //表的Select权限授权给postgres用户 sql += $"GRANT SELECT ON TABLE \"{tableName}\" TO postgres;"; _dataBase.ExecuteNonQuery(sql); } } public void CreateTableIndex(string table, string index, string sql) { DbDataReader dataReader = _dataBase.ExecuteReader("select* from pg_indexes where tablename='" + table + "' and indexname = '" + index + "'"); if (!dataReader.HasRows) { ExecuteNonQuery(sql); } } private void UpdateTable() { CreateTableIndex("recipe_step_data", "recipe_step_data_idx1", "CREATE INDEX recipe_step_data_idx1 ON public.recipe_step_data USING btree(\"process_data_guid\", \"step_number\");"); CreateTableIndex("step_fdc_data", "step_fdc_data_idx1", "CREATE INDEX step_fdc_data_idx1 ON public.step_fdc_data USING btree(\"process_data_guid\", \"step_number\");"); CreateTableIndex("lot_wafer_data", "lot_wafer_data_idx1", "CREATE INDEX lot_wafer_data_idx1 ON public.lot_wafer_data USING btree(lot_data_guid COLLATE pg_catalog.\"default\", wafer_data_guid COLLATE pg_catalog.\"default\");"); //AddTableColumn("carrier_data", new Dictionary //{ // {"rootname",typeof(string) }, // {"recipename",typeof(string)}, // {"filedetail",typeof(byte[]) } //}); //AlterTableColumn("carrier_data", new Dictionary //{ // {"rootname","rootname1" }, // {"recipename","recipename1"}, // {"filedetail","filedetail1" } //}); //DeleteTableColumn("carrier_data", new List //{ // "rootname1", // "recipename1", // "filedetail1" //}); } /// /// 新增Table列名 /// /// /// public void AddTableColumn(string tableName, Dictionary columns) { string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';"; DbDataReader dataReader = _dataBase.ExecuteReader(sql); string cmdText = string.Empty; List list = new List(); while (dataReader.Read()) { for (int i = 0; i < dataReader.FieldCount; i++) { list.Add(dataReader[i].ToString()); } } if (list.Count > 0) { foreach (KeyValuePair column in columns) { if (!list.Contains(column.Key)) { cmdText = ((!(column.Value == typeof(bool))) ? ((!(column.Value == typeof(double)) && !(column.Value == typeof(float))) ? ((!(column.Value == typeof(DateTime))) ? ((!(column.Value == typeof(int)) && !(column.Value == typeof(ushort)) && !(column.Value == typeof(short))) ? (cmdText + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "text")) : (cmdText + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "integer"))) : (cmdText + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "timestamp without time zone"))) : (cmdText + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "real"))) : (cmdText + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "Boolean"))); } } if (!string.IsNullOrEmpty(cmdText)) { _dataBase.ExecuteNonQuery(cmdText); } } } /// /// 更新Table列名 /// /// /// public void AlterTableColumn(string tableName, Dictionary columns) { string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';"; DbDataReader dataReader = _dataBase.ExecuteReader(sql); string cmdText = string.Empty; List list = new List(); while (dataReader.Read()) { for (int i = 0; i < dataReader.FieldCount; i++) { list.Add(dataReader[i].ToString()); } } if (list.Count > 0) { foreach (KeyValuePair column in columns) { if (list.Contains(column.Key)) { cmdText += $"ALTER TABLE \"{tableName}\" RENAME COLUMN \"{column.Key}\" TO {column.Value};"; } } if (!string.IsNullOrEmpty(cmdText)) { _dataBase.ExecuteNonQuery(cmdText); } } } public void DeleteTableColumn(string tableName, List columns) { string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';"; DbDataReader dataReader = _dataBase.ExecuteReader(sql); string cmdText = string.Empty; List list = new List(); while (dataReader.Read()) { for (int i = 0; i < dataReader.FieldCount; i++) { list.Add(dataReader[i].ToString()); } } if (list.Count > 0) { foreach (string column in columns) { if (list.Contains(column)) { cmdText += $"ALTER TABLE \"{tableName}\" DROP COLUMN \"{column}\";"; } } if (!string.IsNullOrEmpty(cmdText)) { _dataBase.ExecuteNonQuery(cmdText); } } } public string GetSqlByNameType(string name, Type type) { return _dataBase.GetSqlByNameType(name, type); } public void InsertSql(string sql) { _sqlQueue.Enqueue(sql); } public DbDataReader ExecuteReader(string sql) { return _dataBase.ExecuteReader(sql); } public int ExecuteNonQuery(string sql, bool isChangeDB = true) { return _dataBase.ExecuteNonQuery(sql, isChangeDB); } public int ExecuteNonQuery(string sql, string[] columnsName, params object[] args) { return _dataBase.ExecuteNonQuery(sql, columnsName, args); } public object ExecuteScalar(string sql, bool isChangeDB = true) { return _dataBase.ExecuteScalar(sql, isChangeDB); } public DataSet ExecuteDataSet(string sql) { return _dataBase.ExecuteDataSet(sql); } public DataTable ExecuteDataTable(string sql) { return _dataBase.ExecuteDataTable(sql); } public bool ExcuteTransAction(List sqlList) { return _dataBase.ExcuteTransAction(sqlList); } private bool Monitor() { try { if (_sqlQueue.Count == 0) { return true; } if (_sqlQueue.TryDequeue(out string sql)) { _dataBase.ExecuteNonQuery(sql); } return true; } catch (Exception ex) { LOG.Error(ex.Message, ex); return true; } } public void Terminate() { _monitorJob?.Stop(); _monitorJob = null; } /// /// DataTable转成List /// /// /// /// public IList DataTableToList(DataTable dt) where T : new() { IList list = new List(); Type type = typeof(T); foreach (DataRow dr in dt.Rows) { T t = new T(); PropertyInfo[] properties = t.GetType().GetProperties(); foreach (PropertyInfo pi in properties) { if (dt.Columns.Contains(pi.Name)) { if (!pi.CanWrite) { continue; } object value = dr[pi.Name]; if (value != DBNull.Value) { pi.SetValue(t, value, null); } } } list.Add(t); } return list; } /// /// DataTable转成T /// /// /// /// public T DataTableToObject(DataTable dt) where T : new() { T t = new T(); if (dt.Rows == null || dt.Rows.Count == 0) { return t; } DataRow dr = dt.Rows[0]; PropertyInfo[] properties = t.GetType().GetProperties(); foreach (PropertyInfo pi in properties) { if (dt.Columns.Contains(pi.Name)) { if (!pi.CanWrite) { continue; } object value = dr[pi.Name]; if (value != DBNull.Value) { pi.SetValue(t, value, null); } } } return t; } public string GetLocalDictionary() { return _dataBase.GetLocalDictionary(); } } }