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

423 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;
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 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, "DBJob", true);
_databaseCleaner.Initialize();
}
/// <summary>
/// 创建数据库
/// </summary>
public void CreateDataBase()
{
try
{
object obj = _dataBase.ExecuteScalar($"select datname from pg_catalog.pg_database where datname='{_dbName}'");
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, bool addPID, string primaryKey)
{
DbDataReader dataReader = _dataBase.ExecuteReader($"select column_name from information_schema.columns where table_name = '{tableName}'");
if (!dataReader.HasRows)
{
string sql = addPID ? " \"PID\" serial NOT NULL," : "";
//列名
foreach (KeyValuePair<string, Type> column in columns)
{
if (column.Value == typeof(int) || column.Value == typeof(ushort) || column.Value == typeof(short))
{
sql += $"\"{column.Key}\" integer,";
}
else if (column.Value == typeof(double) || column.Value == typeof(float))
{
sql += $"\"{column.Key}\" real,";
}
else if (column.Value == typeof(string))
{
sql += $"\"{column.Key}\" text,";
}
else if (column.Value == typeof(DateTime))
{
sql += $"\"{column.Key}\" timestamp without time zone,";
}
else if (column.Value == typeof(bool))
{
sql += $"\"{column.Key}\" boolean,";
}
else if (column.Value == typeof(byte[]))
{
sql += $"\"{column.Key}\" bytea,";
}
}
//主键
if (string.IsNullOrEmpty(primaryKey))
{
if (sql.LastIndexOf(',') == sql.Length - 1)
{
sql = sql.Remove(sql.Length - 1);
}
}
else
{
sql += $"CONSTRAINT \"{tableName}_pkey\" PRIMARY KEY (\"{primaryKey}\" )";
}
_dataBase.ExecuteNonQuery($"CREATE TABLE \"{tableName}\"({sql})WITH ( OIDS=FALSE );");
}
}
private void UpdateTable()
{
//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 npgsqlDataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
while (npgsqlDataReader.Read())
{
for (int i = 0; i < npgsqlDataReader.FieldCount; i++)
{
list.Add(npgsqlDataReader[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 npgsqlDataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
while (npgsqlDataReader.Read())
{
for (int i = 0; i < npgsqlDataReader.FieldCount; i++)
{
list.Add(npgsqlDataReader[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 npgsqlDataReader = _dataBase.ExecuteReader(sql);
string cmdText = string.Empty;
List<string> list = new List<string>();
while (npgsqlDataReader.Read())
{
for (int i = 0; i < npgsqlDataReader.FieldCount; i++)
{
list.Add(npgsqlDataReader[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 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 object ExecuteScalar(string sql)
{
return _dataBase.ExecuteScalar(sql);
}
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 false;
}
if (_sqlQueue.TryDequeue(out string sql))
{
_dataBase.ExecuteNonQuery(sql);
}
return true;
}
catch (Exception ex)
{
LOG.Error(ex.Message, ex);
return false;
}
}
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;
}
}
}