using Furion.DependencyInjection; using Furion.FriendlyException; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Localization; using MySql.Data.MySqlClient; using Newtonsoft.Json.Linq; using RoadFlow.Utility; using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RoadFlow.Data { public class DbConnection:RoadFlowRepository,IDbConnection, ITransient { /// /// 添加一个连接 /// /// 连接实体 /// public override int Add(Model.rf_dbconnection dbConnection) { ClearCache(); dbConnection.ConnString = dbConnection.ConnString.DESEncrypt(); return db.Insertable(dbConnection).ExecuteCommand(); } /// /// 更新连接 /// /// 连接实体 public override int Update(Model.rf_dbconnection dbConnection, bool clearCache = true) { if(clearCache) ClearCache(); dbConnection.ConnString = dbConnection.ConnString.DESEncrypt(); return db.Updateable(dbConnection).ExecuteCommand(); } /// /// 得到所有连接 /// /// public override List GetAll() { return _memoryCache.GetOrCreate(CACHEKEY, v => { var dbConnections = db.Queryable().OrderBy(p => p.Sort).ToList(); foreach (var dbConn in dbConnections) { dbConn.ConnString = dbConn.ConnString.DESDecrypt(); } return dbConnections; }); } /// /// 得到一个表所有字段 /// /// /// /// public List GetTableFields(string id, string tableName) { var conn = GetOneById(id); if (null == conn) { return new List(); } return GetTableFields(conn, tableName); } /// /// 得到一个表所有字段 /// /// /// /// public List GetTableFields(Model.rf_dbconnection conn, string tableName) { List tableFields = new List(); string dbName = string.Empty; if (conn.ConnType.EqualsIgnoreCase("mysql")) { string[] connStringArray = conn.ConnString.Split(';'); foreach (string connString in connStringArray) { string[] connArray = connString.Split('='); if (connArray.Length > 1 && (connArray[0].Trim().Equals("database") || connArray[0].Trim().Equals("db") || connArray[0].Trim().Equals("Initial Catalog"))) { dbName = connArray[1].Trim(); } } } var dt = this.GetTableFields(conn, tableName, dbName); foreach (DataRow dr in dt.Rows) { Model.TableField tableField = new Model.TableField() { FieldName = dr["f_name"].ToString().Trim(), Type = dr["t_name"].ToString(), Size = dr["length"].ToString().ToInt(), IsNull = "1".Equals(dr["is_null"].ToString()), IsDefault = dr["cdefault"].ToString().ToInt(0) != 0, IsIdentity = dr["isidentity"].ToString().ToInt() == 1, DefaultValue = dr["defaultvalue"].ToString(), Comment = dr["comments"].ToString() }; tableFields.Add(tableField); } return tableFields; } /// /// 得到一个表所有字段 /// /// /// 表名 /// 数据库名(MYSQL时需要,防止同一个连接中不同的数据库中有相同的表名的情况。其它数据库为空) /// 返回datatable 列:f_name,t_name,length,is_null,cdefault,isidentity,defaultvalue,comments public DataTable GetTableFields(Model.rf_dbconnection dbConnection, string table, string dbName) { using var conn = dbConnection.GetConn(db); string sql = GetTableFieldsSql(dbConnection, table, dbName); return conn.Ado.GetDataTable(sql); } private string GetTableFieldsSql(Model.rf_dbconnection dbConnection, string tableName, string dbName) { using (var conn = db.GetConnection(dbConnection.Id)) { switch (dbConnection.DbType) { case SqlSugar.DbType.MySql: return "SELECT COLUMN_NAME f_name,DATA_TYPE t_name, CHARACTER_MAXIMUM_LENGTH length " + ",CASE IS_NULLABLE WHEN 'NO' THEN 0 WHEN 'YES' THEN 1 END is_null,COLUMN_DEFAULT cdefault,0 isidentity,COLUMN_DEFAULT defaultvalue,COLUMN_COMMENT comments FROM " + "information_schema.TABLES a " + "LEFT JOIN information_schema.COLUMNS b ON a.table_name = b.TABLE_NAME " + "WHERE a.TABLE_NAME='" + tableName + "'" + (dbName.IsNullOrWhiteSpace() ? "" : " AND a.TABLE_SCHEMA='" + dbName + "' AND b.TABLE_SCHEMA='" + dbName + "'") + " ORDER BY b.ordinal_position"; case SqlSugar.DbType.SqlServer: return string.Format("select a.name as f_name,b.name as t_name,a.prec as [length],a.isnullable as is_null,a.cdefault as cdefault," + "COLUMNPROPERTY(OBJECT_ID('{0}'),a.name,'IsIdentity') as isidentity," + "(select top 1 text from sysobjects d inner join syscolumns e on e.id=d.id inner join syscomments f on f.id=e.cdefault " + "where d.name='{0}' and e.name=a.name) as defaultvalue,cast([value] as varchar(500)) as comments " + "from sys.syscolumns a left join sys.types b on b.user_type_id=a.xtype left join sys.extended_properties x " + "on x.major_id=OBJECT_ID('{0}') and x.minor_id=a.colid " + "where OBJECT_ID('{0}')=id order by a.colid", tableName); case SqlSugar.DbType.Oracle: return string.Format("SELECT user_tab_columns.COLUMN_NAME as f_name," + "user_tab_columns.DATA_TYPE as t_name," + "user_tab_columns.CHAR_LENGTH AS length," + "CASE user_tab_columns.NULLABLE WHEN 'Y' THEN 1 WHEN 'N' THEN 0 END AS is_null," + "user_tab_columns.DATA_DEFAULT AS cdefault," + "0 as isidentity,user_tab_columns.DATA_DEFAULT AS defaultvalue,user_col_comments.comments FROM user_tab_columns,user_col_comments " + "WHERE user_tab_columns.COLUMN_NAME=user_col_comments.COLUMN_NAME " + "and user_tab_columns.TABLE_NAME=user_col_comments.TABLE_NAME " + "and UPPER(user_tab_columns.TABLE_NAME)=UPPER('{0}') " + "and UPPER(user_col_comments.TABLE_NAME)=UPPER('{0}') " + "ORDER BY user_tab_columns.COLUMN_ID", tableName); case SqlSugar.DbType.PostgreSQL: return "select column_name as f_name,udt_name as t_name,character_maximum_length as length,case is_nullable when 'NO' then 0 when 'YES' then 1 end as is_null,column_default as cdefault,case is_identity when 'NO' then 0 when 'YES' then 1 end as isidentity,column_default as defaultvalue,'' as comments from information_schema.columns where table_name='" + tableName.ToLower() + "' order by ordinal_position"; case SqlSugar.DbType.Dm: case SqlSugar.DbType.Kdbndp: case SqlSugar.DbType.Sqlite: return "不支持的连接类型"; } } return ""; } /// /// 得到数据库所有表SQL /// private string GetDbTablesSql(SqlSugar.DbType type,string database) { switch (type) { case SqlSugar.DbType.MySql: return "select TABLE_NAME, TABLE_COMMENT COMMENTS from information_schema.TABLES where TABLE_SCHEMA='" + database + "' and (table_type='BASE TABLE' or table_type='VIEW')"; case SqlSugar.DbType.SqlServer: return "SELECT name TABLE_NAME,(select top 1 cast([value] as varchar) [value] from sys.extended_properties where major_id=sysobjects.id and minor_id=0) COMMENTS from sysobjects WHERE name<>'sysdiagrams' AND (xtype='U' or xtype='V') ORDER BY xtype,name"; case SqlSugar.DbType.Oracle: return "select a.TABLE_NAME,b.COMMENTS from user_tables a,user_tab_comments b WHERE a.TABLE_NAME=b.TABLE_NAME and a.TABLE_NAME not like '%$%' and a.TABLE_NAME not like 'LOGMNR%' and a.TABLE_NAME not like 'HELP%' and a.TABLE_NAME not like 'SPRING%' and a.TABLE_NAME not like 'SQLPLUS%' order by TABLE_NAME"; case SqlSugar.DbType.PostgreSQL: return "select table_name, '' as comments from information_schema.tables where table_catalog='" + database + "' and table_schema='public' and (table_type='BASE TABLE' or table_type='VIEW')"; case SqlSugar.DbType.Dm: case SqlSugar.DbType.Kdbndp: case SqlSugar.DbType.Sqlite: return "不支持的连接类型"; } return ""; } /// /// 得到一个连接所有表 /// /// /// Dictionary(表名, 表说明) public Dictionary GetTables(string id) { Dictionary dict = new Dictionary(); var conn = GetOneById(id); if (null == conn) { return dict; } DataTable dt = this.GetTables(conn); foreach (DataRow dr in dt.Rows) { dict.Add(dr[0].ToString().Trim(), dr[1].ToString()); } return dict; } /// /// 查询一个连接所有表 /// /// /// 表名,表说明 public DataTable GetTables(Model.rf_dbconnection dbConnection) { using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = dbConnection.Id, ConnectionString = dbConnection.ConnString, DbType = dbConnection.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { var prd = c.GetConnection(dbConnection.Id); return prd.Ado.GetDataTable( GetDbTablesSql(dbConnection.DbType, prd.Ado.Connection.Database)); } } /// /// 得到一个字段的值(默认系统连接) /// /// SQL /// 参数 /// public string GetFieldValue(string sql, params object[] objs) { return JObject.FromObject(db.Ado.SqlQuery(sql, objs)).ToString(); } /// /// 得到DATATABLE /// /// /// /// /// /// 排序 f1 desc /// public DataTable GetDataTable(Model.rf_dbconnection dbConnectionModel, string tableName, string primaryKey, string primaryKeyValue, string order = "") { if (null == dbConnectionModel || primaryKeyValue.IsNullOrWhiteSpace() || tableName.IsNullOrWhiteSpace() || primaryKey.IsNullOrWhiteSpace()) { return new DataTable(); } var (sql, param) = GetFieldValueSql(tableName, "*", primaryKey, primaryKeyValue); DataTable dt = GetDataTable(dbConnectionModel, sql, param); if (!order.IsNullOrWhiteSpace()) { dt.DefaultView.Sort = order; return dt.DefaultView.ToTable(); } else { return dt; } } public DataTable GetDataTable(Model.rf_dbconnection conn, string sql, params object[] objs) { using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { var prd = c.GetConnection(conn.Id); List list = new List(); foreach (object o in objs) list.Add((SqlSugar.SugarParameter)o); return prd.Ado.GetDataTable(sql, list); } } /// /// 得到查询一个字段值SQL /// /// /// /// /// /// public (string sql, object[] parameter) GetFieldValueSql(string tableName, string fieldName, string primaryKey, string primaryKeyValue) { string sql = "SELECT " + fieldName + " FROM " + tableName + " WHERE " + primaryKey + " = @primarykeyvalue"; return (sql, new object[] { new SqlSugar.SugarParameter("primarykeyvalue",primaryKeyValue) } ); } /// /// 得到一个字段的值 /// /// 连接ID /// 表名 /// 要查询的字段 /// 主键 /// 主键值 /// public string GetFieldValue(string id, string tableName, string fieldName, string primaryKey, string primaryKeyValue) { var conn = GetOneById(id); if (null == conn) { return string.Empty; } return GetFieldValue(conn, tableName, fieldName, primaryKey, primaryKeyValue); } /// /// 得到一个字段的值 /// /// 连接实体 /// 表名 /// 要查询的字段 /// 主键 /// 主键值 /// public string GetFieldValue(Model.rf_dbconnection dbConnection, string tableName, string fieldName, string primaryKey, string primaryKeyValue) { var sql = GetFieldValueSql(tableName, fieldName, primaryKey, primaryKeyValue); DataTable dataTable = GetDataTable(dbConnection, sql.sql, sql.parameter ); return dataTable.Rows.Count > 0 ? dataTable.Rows[0][0].ToString() : string.Empty; } /// /// 保存数据 /// /// /// /// /// /// 要额外执行的SQL列表 /// 返回数字表示成功(数字是受影响的行数或者自增主键值),其它为错误信息 public string SaveData(Model.rf_dbconnection dbConnection, List<(Dictionary dicts, string tableName, string primaryKey, int flag)> tuples, bool isIdentity = false, string seqName = "", List<(string, SqlSugar.SugarParameter[])> sqlList = null) { return tuples.Count == 0 && (sqlList == null || sqlList.Count == 0) ? "0" : SaveData2(dbConnection, tuples, isIdentity, seqName, sqlList); } /// /// 保存数据 /// /// /// 要额外执行的SQL列表 /// 返回数字表示成功(数字是受影响的行数或者自增主键值),其它为错误信息 public string SaveData2(Model.rf_dbconnection dbConnection, List<(Dictionary dicts, string tableName, string primaryKey, int flag)> tuples, bool isIdentity = false, string seqName = "", List<(string, SqlSugar.SugarParameter[])> sqlList1 = null) { List<(string sql, SqlSugar.SugarParameter[] parameters)> sqlList = new List<(string sql, SqlSugar.SugarParameter[] parameters)>(); foreach (var (dicts, tableName, primaryKey, flag) in tuples) { var (sql, paramArray) = GetSaveDataSql(dicts, tableName, primaryKey, flag); sqlList.Add((sql, paramArray)); } if (sqlList1 != null && sqlList1.Count > 0) { sqlList.AddRange(sqlList1); } using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = dbConnection.Id, ConnectionString = dbConnection.ConnString, DbType = dbConnection.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { var prd = c.GetConnection(dbConnection.Id); prd.Ado.BeginTran(); try { int i = 0; foreach (var (sql, parameter) in sqlList) { i += prd.Ado.ExecuteCommand(sql, parameter); } if (isIdentity && !seqName.IsNullOrWhiteSpace()) { i = prd.Ado.SqlQuery("SELECT @@IDENTITY")[0]; } prd.Ado.CommitTran(); return i.ToString(); } catch (Exception ex) { prd.Ado.RollbackTran(); } } return "-1"; } /// /// 得到保存数据SQL /// /// /// 0删除 1新增 2修改 /// public (string sql, SqlSugar.SugarParameter[] parameter) GetSaveDataSql(Dictionary dicts, string tableName, string primaryKey, int flag) { StringBuilder sqlBuilder = new StringBuilder(); List parameters = new List(); if (0 == flag) { sqlBuilder.Append("DELETE FROM " + tableName); } else if (1 == flag) { sqlBuilder.Append("INSERT INTO " + tableName + "("); foreach (var dict in dicts) { sqlBuilder.Append(dict.Key); if (!dict.Key.Equals(dicts.Last().Key)) { sqlBuilder.Append(","); } } sqlBuilder.Append(") VALUES("); } else if (2 == flag) { sqlBuilder.Append("UPDATE " + tableName + " SET "); } foreach (var dict in dicts) { if (0 == flag) { sqlBuilder.Append(" WHERE " + primaryKey + "=@" + primaryKey); parameters.Add(new SqlSugar.SugarParameter("@" + primaryKey, dicts[primaryKey])); } else if (1 == flag) { parameters.Add(new SqlSugar.SugarParameter("@" + dict.Key, dict.Value)); sqlBuilder.Append("@" + dict.Key); if (!dict.Key.Equals(dicts.Last().Key)) { sqlBuilder.Append(","); } } else if (2 == flag) { parameters.Add(new SqlSugar.SugarParameter("@" + dict.Key, dict.Value)); if (dict.Key.EqualsIgnoreCase(primaryKey)) { continue; } sqlBuilder.Append(dict.Key + "=@" + dict.Key); if (!dict.Key.Equals(dicts.Last().Key)) { sqlBuilder.Append(","); } } } if (1 == flag) { sqlBuilder.Append(")"); } else if (2 == flag) { sqlBuilder.Append(" WHERE " + primaryKey + "=@" + primaryKey); } return (sqlBuilder.ToString(), parameters.ToArray()); } /// /// 判断一个连接是否和系统是一个连接 /// /// /// public bool IsSystemConn(Model.rf_dbconnection connModel) { var con =db.CurrentConnectionConfig; return true; } public int executeSqlByConnection(Model.rf_dbconnection conn, IEnumerable<(string, object[], int)> list, bool trans = true) { using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { if(trans) c.BeginTran(); try { int count = 0; foreach (var (sql, pars, _) in list) count = c.Ado.ExecuteCommand(sql, pars); if (trans) c.CommitTran(); return count; } catch (Exception ex) { if (trans) c.RollbackTran(); throw; } } } public int executeSqlByConnection(Model.rf_dbconnection conn, string sql,params object[] pars) { using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { return c.Ado.ExecuteCommand(sql, pars); } } public int executeSqlByConnection(string connId, List<(string, IEnumerable)> sqls) { var conn = GetOneById(connId); using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { c.Ado.BeginTran(); try { int count = 0; foreach ((string sql, IEnumerable pars) in sqls) { count +=c.Ado.ExecuteCommand(sql, pars); } c.Ado.CommitTran(); return count; } catch (Exception e) { c.Ado.RollbackTran(); throw; } } } public int executeSqlByCurrent(IEnumerable<(string, object[], int)> list,bool trans=true) { if (trans) db.BeginTran(); try { int count = 0; foreach (var (sql, pars, _) in list) count = db.Ado.ExecuteCommand(sql, pars); if (trans) db.CommitTran(); return count; } catch { if (trans) db.RollbackTran(); throw; } } /// /// 测试一个SQL语句是否正确 /// /// 连接ID /// sql语句 /// sql参数 /// public string TestSQL(string id, string sql, object[] parameters = null) { var conn = GetOneById(id); if (conn == null) return "未找到连接实体"; using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { c.Ado.BeginTran(); try { int rtn = c.Ado.ExecuteCommand(sql, parameters); return rtn.ToString(); } catch (Exception ex) { return "SQL:" + sql + " " + ex.Message; } finally { c.Ado.RollbackTran(); } } } /// /// 得到连接类别下拉项(VUE) /// /// public JArray GetConnTypeOptionsVue() { JArray jArray = new JArray(); var array = Enum.GetValues(typeof(ConnType)); foreach (var arr in array) { jArray.Add(new JObject() { { "value", arr.ToString() }, { "title", arr.ToString() } }); } return jArray; } /// /// 测试一个连接 /// /// 连接ID /// 语言包 /// 返回"1"表示正常,其它为错误信息 public string TestConnection(string id, IStringLocalizer localizer = null) { var conn = this.GetOneById(id); if (conn == null) return localizer == null ? "未找到连接" : localizer["NotFoundConnection"].Value; using (SqlSugar.SqlSugarClient c = new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig() { ConfigId = conn.Id, ConnectionString = conn.ConnString, DbType = conn.DbType, IsAutoCloseConnection = true, InitKeyType = SqlSugar.InitKeyType.SystemTable })) { return "1"; } } } /// /// 数据连接类型枚举 /// public enum ConnType { SqlServer, MySql, Oracle, PostgreSql } }