Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/Aitex/Core/RT/DBCore/DatabaseManager.cs

443 lines
14 KiB
C#
Raw 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 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 = "sicdatabase";
private IDataBase _dataBase;
private string _sqlFile = PathManager.GetCfgDir() + "DBModel.sql";
private PeriodicJob _monitorJob;
private DataBaseCleaner _databaseCleaner = new DataBaseCleaner();
private FixSizeQueue<string> _sqlQueue = new FixSizeQueue<string>(1000);
public void Initialize()
{
DB.Manager = this;
_dataBase = new PostgreSQLHelper(_dbName);
CreateDataBase();
ExecuteScript(_sqlFile);
UpdateTable();
_monitorJob = new PeriodicJob(100, Monitor,"DataBaseManager", true);
_databaseCleaner.Initialize();
}
/// <summary>
/// 创建数据库
/// </summary>
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);
}
}
/// <summary>
/// 执行SQL脚本
/// </summary>
/// <param name="sqlFile"></param>
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);
}
}
/// <summary>
/// 创建Table
/// </summary>
/// <param name="tableName"></param>
/// <param name="columns"></param>
/// <param name="addPID"></param>
/// <param name="primaryKey"></param>
public void CreateTable(string tableName, Dictionary<string, Type> 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);
}
//列名
foreach (KeyValuePair<string, Type> column in columns)
{
sql += _dataBase.GetSqlByNameType(column.Key, column.Value);
}
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<string, Type>
//{
// {"rootname",typeof(string) },
// {"recipename",typeof(string)},
// {"filedetail",typeof(byte[]) }
//});
//AlterTableColumn("carrier_data", new Dictionary<string, string>
//{
// {"rootname","rootname1" },
// {"recipename","recipename1"},
// {"filedetail","filedetail1" }
//});
//DeleteTableColumn("carrier_data", new List<string>
//{
// "rootname1",
// "recipename1",
// "filedetail1"
//});
}
/// <summary>
/// 新增Table列名
/// </summary>
/// <param name="tableName"></param>
/// <param name="columns"></param>
public void AddTableColumn(string tableName, Dictionary<string, Type> columns)
{
string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';";
DbDataReader dataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
while (dataReader.Read())
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
list.Add(dataReader[i].ToString());
}
}
if (list.Count > 0)
{
foreach (KeyValuePair<string, Type> 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);
}
}
}
/// <summary>
/// 更新Table列名
/// </summary>
/// <param name="tableName"></param>
/// <param name="columns"></param>
public void AlterTableColumn(string tableName, Dictionary<string, string> columns)
{
string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';";
DbDataReader dataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
while (dataReader.Read())
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
list.Add(dataReader[i].ToString());
}
}
if (list.Count > 0)
{
foreach (KeyValuePair<string, string> 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<string> columns)
{
string sql = $"select column_name from information_schema.columns where table_name = '{tableName}';";
DbDataReader dataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
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<string> 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;
_databaseCleaner?.Terminate();
}
/// <summary>
/// DataTable转成List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public IList<T> DataTableToList<T>(DataTable dt) where T : new()
{
IList<T> list = new List<T>();
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;
}
/// <summary>
/// DataTable转成T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public T DataTableToObject<T>(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;
}
}
}