using System; using System.Collections.Generic; using System.Data; using Aitex.Core.RT.Log; using Aitex.Core.Utilities; using Npgsql; namespace Aitex.Core.RT.DBCore { public class PostgresqlDB { private NpgsqlConnection _conn; private string _connectionString; private string _dbName; private Retry _retryConnection = new Retry(); private bool _dbFailed; public bool Open(string connectionString, string dbName) { _connectionString = connectionString; _dbName = dbName; bool result = true; try { if (_conn != null) { _conn.Close(); } _conn = new NpgsqlConnection(connectionString); _conn.Open(); if (!string.IsNullOrEmpty(dbName)) { CreateDBIfNotExisted(dbName); } _dbFailed = false; } catch (Exception ex) { if (_conn != null) { _conn.Close(); _conn = null; } result = false; if (!_dbFailed) { LOG.Write(ex); _dbFailed = true; } } _retryConnection.Result = result; return result; } private bool Open() { return Open(_connectionString, _dbName); } private void PrepareCommand(NpgsqlCommand cmd, NpgsqlConnection conn, string cmdText, params object[] p) { cmd.Parameters.Clear(); cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandType = CommandType.Text; if (p != null) { foreach (object value in p) { cmd.Parameters.AddWithValue(string.Empty, value); } } } private void PrepareCommand(NpgsqlCommand cmd, NpgsqlConnection conn, string cmdText, string[] columnsName, params object[] p) { cmd.Parameters.Clear(); cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandType = CommandType.Text; if (p != null && columnsName != null && p.Length != 0 && columnsName.Length == p.Length) { for (int i = 0; i < p.Length; i++) { cmd.Parameters.AddWithValue(columnsName[i], p[i]); } } } public int ExecuteNonQuery(string cmdText, params object[] p) { try { using NpgsqlCommand npgsqlCommand = new NpgsqlCommand(); PrepareCommand(npgsqlCommand, _conn, cmdText, p); return npgsqlCommand.ExecuteNonQuery(); } catch { Close(); throw; } } public int ExecuteNonQueryWithParam(string cmdText, string[] columnsName, params object[] p) { try { DataSet dataSet = new DataSet(); using (NpgsqlConnection npgsqlConnection = new NpgsqlConnection(_connectionString)) { npgsqlConnection.Open(); npgsqlConnection.ChangeDatabase(_dbName); using NpgsqlCommand npgsqlCommand = new NpgsqlCommand(); try { PrepareCommand(npgsqlCommand, npgsqlConnection, cmdText, columnsName, p); return npgsqlCommand.ExecuteNonQuery(); } catch (Exception ex) { LOG.Error("执行查询出错," + cmdText, ex); } } return 0; } catch { Close(); throw; } } public DataSet ExecuteDataset(string cmdText, params object[] p) { try { DataSet dataSet = new DataSet(); using (NpgsqlConnection npgsqlConnection = new NpgsqlConnection(_connectionString)) { npgsqlConnection.Open(); npgsqlConnection.ChangeDatabase(_dbName); using NpgsqlCommand npgsqlCommand = new NpgsqlCommand(); try { PrepareCommand(npgsqlCommand, npgsqlConnection, cmdText, p); NpgsqlDataAdapter npgsqlDataAdapter = new NpgsqlDataAdapter(npgsqlCommand); npgsqlDataAdapter.Fill(dataSet); } catch (Exception ex) { LOG.Error("执行查询出错," + cmdText, ex); } } return dataSet; } catch (Exception ex2) { LOG.Error("执行查询出错," + cmdText, ex2); } return null; } public NpgsqlDataReader ExecuteReader(string cmdText, params object[] p) { try { using NpgsqlCommand npgsqlCommand = new NpgsqlCommand(); PrepareCommand(npgsqlCommand, _conn, cmdText, p); return npgsqlCommand.ExecuteReader(CommandBehavior.CloseConnection); } catch { Close(); throw; } } public bool ExcuteTransAction(List lstStr) { try { DataSet dataSet = new DataSet(); using NpgsqlConnection npgsqlConnection = new NpgsqlConnection(_connectionString); npgsqlConnection.Open(); npgsqlConnection.ChangeDatabase(_dbName); NpgsqlTransaction npgsqlTransaction = npgsqlConnection.BeginTransaction(); using NpgsqlCommand npgsqlCommand = new NpgsqlCommand(); try { npgsqlCommand.Transaction = npgsqlTransaction; npgsqlCommand.Connection = npgsqlConnection; npgsqlCommand.CommandType = CommandType.Text; for (int i = 0; i < lstStr.Count; i++) { npgsqlCommand.Parameters.Clear(); npgsqlCommand.CommandText = lstStr[i]; npgsqlCommand.ExecuteNonQuery(); } npgsqlTransaction.Commit(); } catch (Exception ex) { npgsqlTransaction.Rollback(); LOG.Error("执行查询出错,", ex); return false; } } catch (Exception ex2) { LOG.Error("执行查询出错,", ex2); return false; } return true; } public bool ActiveConnection() { if (_conn != null && _conn.State == ConnectionState.Open) { return true; } return Open(); } public void Close() { try { if (_conn != null) { _conn.Close(); } _conn = null; _dbFailed = false; } catch (Exception ex) { if (!_dbFailed) { LOG.Write(ex); _dbFailed = true; } } } public void CreateDBIfNotExisted(string db) { NpgsqlDataReader npgsqlDataReader = ExecuteReader($"select datname from pg_catalog.pg_database where datname='{db}'"); if (!npgsqlDataReader.HasRows) { string cmdText = $"\r\n CREATE DATABASE {db}\r\n WITH OWNER = postgres\r\n ENCODING = 'UTF8'\r\n TABLESPACE = pg_default\r\n CONNECTION LIMIT = -1"; ExecuteNonQuery(cmdText); } try { _conn.ChangeDatabase(db); } catch { _conn.Close(); throw; } } public void CreateTableIndexIfNotExisted(string table, string index, string sql) { NpgsqlDataReader npgsqlDataReader = ExecuteReader("select* from pg_indexes where tablename='" + table + "' and indexname = '" + index + "'"); if (!npgsqlDataReader.HasRows) { ExecuteNonQuery(sql); } } public void CreateTableIfNotExisted(string table, Dictionary columns, bool addPID, string primaryKey) { NpgsqlDataReader npgsqlDataReader = ExecuteReader($"select column_name from information_schema.columns where table_name = '{table}'"); if (!npgsqlDataReader.HasRows) { string text = (addPID ? " \"PID\" serial NOT NULL," : ""); foreach (KeyValuePair column in columns) { if (column.Value == typeof(int) || column.Value == typeof(ushort) || column.Value == typeof(short)) { text += $"\"{column.Key}\" integer,"; } else if (column.Value == typeof(double) || column.Value == typeof(float)) { text += $"\"{column.Key}\" real,"; } else if (column.Value == typeof(string)) { text += $"\"{column.Key}\" text,"; } else if (column.Value == typeof(DateTime)) { text += $"\"{column.Key}\" timestamp without time zone,"; } else if (column.Value == typeof(bool)) { text += $"\"{column.Key}\" boolean,"; } else if (column.Value == typeof(byte[])) { text += $"\"{column.Key}\" bytea,"; } } if (string.IsNullOrEmpty(primaryKey)) { if (text.LastIndexOf(',') == text.Length - 1) { text = text.Remove(text.Length - 1); } } else { text += $"CONSTRAINT \"{table}_pkey\" PRIMARY KEY (\"{primaryKey}\" )"; } ExecuteNonQuery($"CREATE TABLE \"{table}\"({text})WITH ( OIDS=FALSE );"); } else { CreateTableColumn(table, columns); } } public void CreateTableColumn(string tableName, Dictionary columns) { try { string cmdText = $"select column_name from information_schema.columns where table_name = '{tableName}';"; NpgsqlCommand npgsqlCommand = new NpgsqlCommand(cmdText, _conn); NpgsqlDataReader npgsqlDataReader = npgsqlCommand.ExecuteReader(); string text = string.Empty; List list = new List(); while (npgsqlDataReader.Read()) { for (int i = 0; i < npgsqlDataReader.FieldCount; i++) { list.Add(npgsqlDataReader[i].ToString()); } } npgsqlDataReader.Close(); if (list.Count > 0) { foreach (KeyValuePair column in columns) { if (!list.Contains(column.Key)) { text = ((!(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))) ? (text + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "text")) : (text + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "integer"))) : (text + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "timestamp without time zone"))) : (text + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "real"))) : (text + string.Format("ALTER TABLE \"{0}\" ADD COLUMN \"{1}\" {2};", tableName, column.Key, "Boolean"))); } } if (!string.IsNullOrEmpty(text)) { try { NpgsqlCommand npgsqlCommand2 = new NpgsqlCommand(text, _conn); npgsqlCommand2.ExecuteNonQuery(); _dbFailed = false; } catch (Exception ex) { if (!_dbFailed) { LOG.Write(ex); _dbFailed = true; } } } } _dbFailed = true; } catch (Exception ex2) { if (!_dbFailed) { LOG.Write(ex2); _dbFailed = true; } } } } }