From dbb1945b033daed935cff120b6250fed598a80ea Mon Sep 17 00:00:00 2001 From: "guoshun.du" Date: Fri, 20 Sep 2024 15:52:10 +0800 Subject: [PATCH] =?UTF-8?q?*=E5=A2=9E=E5=8A=A0TDSQLForPGODBC=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TDSQLForPGODBCAdapter.cs | 157 ++ .../SqlSugar.TDSQLForPGODBC.csproj | 13 + .../CodeFirst/TDSQLForPGODBCCodeFirst.cs | 90 + .../TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs | 158 ++ .../DbFirst/TDSQLForPGODBCDbFirst.cs | 11 + .../TDSQLForPGODBCDbMaintenance.cs | 613 ++++++ .../Insertable/TDSQLForPGODBCInserttable.cs | 105 + .../Queryable/TDSQLForPGODBCQueryable.cs | 69 + .../SqlBuilder/TDSQLForPGODBCBuilder.cs | 128 ++ .../SqlBuilder/TDSQLForPGODBCDeleteBuilder.cs | 7 + .../TDSQLForPGODBCExpressionContext.cs | 497 +++++ .../SqlBuilder/TDSQLForPGODBCFastBuilder.cs | 169 ++ .../SqlBuilder/TDSQLForPGODBCInsertBuilder.cs | 196 ++ .../SqlBuilder/TDSQLForPGODBCQueryBuilder.cs | 130 ++ .../SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs | 280 +++ .../TDSQLForPG/TDSQLForPGODBCProvider.cs | 370 ++++ .../Tools/ErrorMessage.cs | 64 + .../Tools/ExpressionConst.cs | 20 + .../Tools/FileHelper.cs | 70 + .../Tools/UtilConstants.cs | 79 + .../Tools/UtilExtensions.cs | 37 + .../Tools/UtilMethods.cs | 1751 +++++++++++++++++ .../Tools/ValidateExtensions.cs | 172 ++ .../Utilities/UtilConvert.cs | 192 ++ .../SugarProvider/SqlSugarAccessory.cs | 4 + Src/Asp.NetCore2/SqlSugar/Enum/DbType.cs | 1 + Src/Asp.NetCore2/SqlSugarCore.sln | 31 +- Src/Asp.NetCore2/TDSQLForPGOBDCTest/Config.cs | 31 + .../TDSQLForPGOBDCTest/Program.cs | 51 + .../TDSQLForPGOBDCTest.csproj | 15 + .../TDSQLForPGOBDCTest/TSYS_USER.cs | 58 + 31 files changed, 5568 insertions(+), 1 deletion(-) create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/DataTableExtensions/TDSQLForPGODBCAdapter.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/SqlSugar.TDSQLForPGODBC.csproj create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/CodeFirst/TDSQLForPGODBCCodeFirst.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbFirst/TDSQLForPGODBCDbFirst.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Insertable/TDSQLForPGODBCInserttable.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Queryable/TDSQLForPGODBCQueryable.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCDeleteBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCFastBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCQueryBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/TDSQLForPGODBCProvider.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ErrorMessage.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ExpressionConst.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/FileHelper.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilExtensions.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ValidateExtensions.cs create mode 100644 Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Utilities/UtilConvert.cs create mode 100644 Src/Asp.NetCore2/TDSQLForPGOBDCTest/Config.cs create mode 100644 Src/Asp.NetCore2/TDSQLForPGOBDCTest/Program.cs create mode 100644 Src/Asp.NetCore2/TDSQLForPGOBDCTest/TDSQLForPGOBDCTest.csproj create mode 100644 Src/Asp.NetCore2/TDSQLForPGOBDCTest/TSYS_USER.cs diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/DataTableExtensions/TDSQLForPGODBCAdapter.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/DataTableExtensions/TDSQLForPGODBCAdapter.cs new file mode 100644 index 000000000..fd0a67525 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/DataTableExtensions/TDSQLForPGODBCAdapter.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Odbc; +using System.Text; +namespace SqlSugar.TDSQLForPGODBC +{ + /// + /// 数据填充器 + /// + public class TDSQLForPGODBCAdapter : IDataAdapter + { + private OdbcCommand command; + private string sql; + private OdbcConnection _sqlConnection; + + /// + /// SqlDataAdapter + /// + /// + public TDSQLForPGODBCAdapter(OdbcCommand command) + { + this.command = command; + } + + public TDSQLForPGODBCAdapter() + { + + } + + /// + /// SqlDataAdapter + /// + /// + /// + public TDSQLForPGODBCAdapter(string sql, OdbcConnection _sqlConnection) + { + this.sql = sql; + this._sqlConnection = _sqlConnection; + } + + /// + /// SelectCommand + /// + public OdbcCommand SelectCommand + { + get + { + if (this.command == null) + { + var conn = (OdbcConnection)this._sqlConnection; + this.command = conn.CreateCommand(); + this.command.CommandText = sql; + } + return this.command; + } + set + { + this.command = value; + } + } + + /// + /// Fill + /// + /// + public void Fill(DataTable dt) + { + if (dt == null) + { + dt = new DataTable(); + } + var columns = dt.Columns; + var rows = dt.Rows; + using (var dr = command.ExecuteReader()) + { + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + } + dt.AcceptChanges(); + } + + /// + /// Fill + /// + /// + public void Fill(DataSet ds) + { + if (ds == null) + { + ds = new DataSet(); + } + using (var dr = command.ExecuteReader()) + { + do + { + var dt = new DataTable(); + var columns = dt.Columns; + var rows = dt.Rows; + for (int i = 0; i < dr.FieldCount; i++) + { + string name = dr.GetName(i).Trim(); + if (dr.GetFieldType(i).Name == "DateTime") + { + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, UtilConstants.DateType)); + else + { + columns.Add(new DataColumn(name + i, UtilConstants.DateType)); + } + } + else + { + if (!columns.Contains(name)) + columns.Add(new DataColumn(name, dr.GetFieldType(i))); + else + { + columns.Add(new DataColumn(name + i, dr.GetFieldType(i))); + } + } + } + + while (dr.Read()) + { + DataRow daRow = dt.NewRow(); + for (int i = 0; i < columns.Count; i++) + { + daRow[columns[i].ColumnName] = dr.GetValue(i); + } + dt.Rows.Add(daRow); + } + dt.AcceptChanges(); + ds.Tables.Add(dt); + } while (dr.NextResult()); + } + } + } + +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/SqlSugar.TDSQLForPGODBC.csproj b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/SqlSugar.TDSQLForPGODBC.csproj new file mode 100644 index 000000000..aa1d81576 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/SqlSugar.TDSQLForPGODBC.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.1 + enable + + + + + + + + diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/CodeFirst/TDSQLForPGODBCCodeFirst.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/CodeFirst/TDSQLForPGODBCCodeFirst.cs new file mode 100644 index 000000000..72ce7d6d3 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/CodeFirst/TDSQLForPGODBCCodeFirst.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCCodeFirst : CodeFirstProvider + { + protected override void ExistLogicEnd(List dbColumns) + { + foreach (EntityColumnInfo column in dbColumns) + { + if (column.DefaultValue != null) + { + this.Context.DbMaintenance.AddDefaultValue(column.DbTableName,column.DbColumnName,column.DefaultValue.ToSqlValue()); + } + } + } + public override void NoExistLogic(EntityInfo entityInfo) + { + var tableName = GetTableName(entityInfo); + //Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1"); + List columns = new List(); + if (entityInfo.Columns.HasValue()) + { + foreach (var item in entityInfo.Columns.Where(it=>it.IsIgnore==false)) + { + DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item); + columns.Add(dbColumnInfo); + } + if (entityInfo.IsCreateTableFiledSort) + { + columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList(); + } + } + columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList(); + this.Context.DbMaintenance.CreateTable(tableName, columns,true); + } + protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + var propertyType = UtilMethods.GetUnderType(item.PropertyInfo); + var result = new DbColumnInfo() + { + TableId = entityInfo.Columns.IndexOf(item), + DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName, + IsPrimarykey = item.IsPrimarykey, + IsIdentity = item.IsIdentity, + TableName = tableName, + IsNullable = item.IsNullable, + DefaultValue = item.DefaultValue, + ColumnDescription = item.ColumnDescription, + Length = item.Length, + CreateTableFieldSort = item.CreateTableFieldSort + }; + if (propertyType == UtilConstants.DecType) + { + result.Scale = item.DecimalDigits; + result.DecimalDigits = item.DecimalDigits; + } + GetDbType(item, propertyType, result); + if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0) + { + result.Length = 1; + } + return result; + } + + protected override void ConvertColumns(List dbColumns) + { + foreach (var item in dbColumns) + { + if (item.DataType == "DateTime") + { + item.Length = 0; + } + } + } + + protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item) + { + this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item)); + if (!item.IsPrimarykey) + this.Context.DbMaintenance.DropConstraint(tableName,null); + if (item.IsPrimarykey) + this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName); + } + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs new file mode 100644 index 000000000..37272a18f --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCDbBind : DbBindProvider + { + public override string GetDbTypeName(string csharpTypeName) + { + if (csharpTypeName == UtilConstants.ByteArrayType.Name) + return "bytea"; + if (csharpTypeName.ToLower() == "int32") + csharpTypeName = "int"; + if (csharpTypeName.ToLower() == "int16") + csharpTypeName = "short"; + if (csharpTypeName.ToLower() == "int64") + csharpTypeName = "long"; + if (csharpTypeName.ToLower().IsIn("boolean", "bool")) + csharpTypeName = "bool"; + if (csharpTypeName == "DateTimeOffset") + csharpTypeName = "DateTime"; + var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + if (mappings != null && mappings.Count > 0) + return mappings.First().Key; + else + return "varchar"; + } + public override string GetPropertyTypeName(string dbTypeName) + { + dbTypeName = dbTypeName.ToLower(); + var propertyTypes = MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName || it.Key.ToLower() == dbTypeName); + if (propertyTypes == null) + { + return "other"; + } + else if (dbTypeName == "xml" || dbTypeName == "string"|| dbTypeName == "jsonb"|| dbTypeName == "json") + { + return "string"; + }else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + { + return "char"; + } + if (dbTypeName == "byte[]") + { + return "byte[]"; + } + else if (propertyTypes == null || propertyTypes.Count() == 0) + { + if (dbTypeName.StartsWith("_")) + { + var dbTypeName2 = dbTypeName.TrimStart('_'); + return MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName2 || it.Key.ToLower() == dbTypeName2).Select(it => it.Value + "[]").First(); + } + Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); + return null; + } + else if (propertyTypes.First().Value == CSharpDataType.byteArray) + { + return "byte[]"; + } + else + { + return propertyTypes.First().Value.ToString(); + } + } + public override List> MappingTypes + { + get + { + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (extService != null && extService.AppendDataReaderTypeMappings.HasValue()) + { + return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList(); + } + else + { + return MappingTypesConst; + } + } + } + public static List> MappingTypesConst = new List>(){ + + new KeyValuePair("int2",CSharpDataType.@short), + //new KeyValuePair("int1",CSharpDataType.@byte), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("smallint",CSharpDataType.@byte), + new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("serial",CSharpDataType.@int), + new KeyValuePair("integer",CSharpDataType.@int), + new KeyValuePair("int8",CSharpDataType.@long), + new KeyValuePair("long",CSharpDataType.@long), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("float4",CSharpDataType.@float), + new KeyValuePair("float4",CSharpDataType.Single), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("float8",CSharpDataType.@double), + new KeyValuePair("double precision",CSharpDataType.@int), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("path",CSharpDataType.@decimal), + new KeyValuePair("point",CSharpDataType.@decimal), + new KeyValuePair("polygon",CSharpDataType.@decimal), + + new KeyValuePair("boolean",CSharpDataType.@bool), + new KeyValuePair("bool",CSharpDataType.@bool), + new KeyValuePair("box",CSharpDataType.@bool), + new KeyValuePair("bytea",CSharpDataType.byteArray), + + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("clob",CSharpDataType.@string), + new KeyValuePair("nvarchar2",CSharpDataType.@string), + new KeyValuePair("varchar2",CSharpDataType.@string), + new KeyValuePair("character varying",CSharpDataType.@string), + new KeyValuePair("geometry",CSharpDataType.@string), + new KeyValuePair("name",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("character",CSharpDataType.@string), + new KeyValuePair("cidr",CSharpDataType.@string), + new KeyValuePair("circle",CSharpDataType.@string), + new KeyValuePair("tsquery",CSharpDataType.@string), + new KeyValuePair("tsvector",CSharpDataType.@string), + new KeyValuePair("txid_snapshot",CSharpDataType.@string), + new KeyValuePair("uuid",CSharpDataType.Guid), + new KeyValuePair("xml",CSharpDataType.@string), + new KeyValuePair("json",CSharpDataType.@string), + + new KeyValuePair("interval",CSharpDataType.@decimal), + new KeyValuePair("lseg",CSharpDataType.@decimal), + new KeyValuePair("macaddr",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("timestamp with time zone",CSharpDataType.DateTime), + new KeyValuePair("timestamptz",CSharpDataType.DateTime), + new KeyValuePair("timestamp without time zone",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("time with time zone",CSharpDataType.DateTime), + new KeyValuePair("timetz",CSharpDataType.DateTime), + new KeyValuePair("time without time zone",CSharpDataType.DateTime), + + new KeyValuePair("bit",CSharpDataType.byteArray), + new KeyValuePair("bit varying",CSharpDataType.byteArray), + new KeyValuePair("varbit",CSharpDataType.@byte), + new KeyValuePair("time",CSharpDataType.TimeSpan), + new KeyValuePair("public.geometry",CSharpDataType.@object), + new KeyValuePair("inet",CSharpDataType.@object) + }; + public override List StringThrow + { + get + { + return new List() { "int32", "datetime", "decimal", "double", "byte" }; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbFirst/TDSQLForPGODBCDbFirst.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbFirst/TDSQLForPGODBCDbFirst.cs new file mode 100644 index 000000000..3d973fe53 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbFirst/TDSQLForPGODBCDbFirst.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCDbFirst : DbFirstProvider + { + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs new file mode 100644 index 000000000..e86932bb3 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs @@ -0,0 +1,613 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetDataBaseSql + { + get + { + return "SELECT datname FROM pg_database"; + } + } + protected override string GetColumnInfosByTableNameSql + { + get + { + string schema = GetSchema(); + string sql = @"select cast (pclass.oid as int4) as TableId,cast(ptables.tablename as varchar) as TableName, + pcolumn.column_name as DbColumnName,pcolumn.udt_name as DataType, + CASE WHEN pcolumn.numeric_scale >0 THEN pcolumn.numeric_precision ELSE pcolumn.character_maximum_length END as Length, + pcolumn.column_default as DefaultValue, + pcolumn.numeric_scale as DecimalDigits, + pcolumn.numeric_scale as Scale, + col_description(pclass.oid, pcolumn.ordinal_position) as ColumnDescription, + case when pkey.colname = pcolumn.column_name + then true else false end as IsPrimaryKey, + case when pcolumn.column_default like 'nextval%' + then true else false end as IsIdentity, + case when pcolumn.is_nullable = 'YES' + then true else false end as IsNullable + from (select * from pg_tables where upper(tablename) = upper('{0}') and schemaname='" + schema + @"') ptables inner join pg_class pclass + on ptables.tablename = pclass.relname inner join (SELECT * + FROM information_schema.columns where table_schema='" + schema + @"' + ) pcolumn on pcolumn.table_name = ptables.tablename and upper(pcolumn.table_name) = upper('{0}') + left join ( + select pg_class.relname,pg_attribute.attname as colname from + pg_constraint inner join pg_class + on pg_constraint.conrelid = pg_class.oid + inner join pg_attribute on pg_attribute.attrelid = pg_class.oid + and pg_attribute.attnum = pg_constraint.conkey[1] + inner join pg_type on pg_type.oid = pg_attribute.atttypid + where pg_constraint.contype='p' + ) pkey on pcolumn.table_name = pkey.relname + order by table_catalog, table_schema, ordinal_position"; + return sql; + } + } + + protected override string GetTableInfoListSql + { + get + { + var schema = GetSchema(); + return @"select cast(relname as varchar) as Name, + cast(obj_description(c.oid,'pg_class') as varchar) as Description from pg_class c + inner join + pg_namespace n on n.oid = c.relnamespace and nspname='" + schema + @"' + inner join + pg_tables z on z.tablename=c.relname + where relkind in('p', 'r') and relname not like 'pg\_%' and relname not like 'sql\_%' and schemaname='" + schema + "' order by relname"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema()+"' "; + } + } + #endregion + + #region DDL + protected override string CreateDataBaseSql + { + get + { + return "CREATE DATABASE {0}"; + } + } + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return "mysqldump.exe {0} -uroot -p > {1} "; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "create table {0} as (select * from {1} limit {2} offset 0)"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "ALTER TABLE {0} RENAME {1} TO {2}"; + } + } + protected override string AddColumnRemarkSql => "comment on column {1}.{0} is '{2}'"; + + protected override string DeleteColumnRemarkSql => "comment on column {1}.{0} is ''"; + + protected override string IsAnyColumnRemarkSql { get { throw new NotSupportedException(); } } + + protected override string AddTableRemarkSql => "comment on table {0} is '{1}'"; + + protected override string DeleteTableRemarkSql => "comment on table {0} is ''"; + + protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } } + + protected override string RenameTableSql => "alter table {0} rename to {1}"; + + protected override string CreateIndexSql + { + get + { + return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})"; + } + } + protected override string AddDefaultValueSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}"; + } + } + protected override string IsAnyIndexSql + { + get + { + return " SELECT count(1) WHERE upper('{0}') IN ( SELECT upper(indexname) FROM pg_indexes )"; + } + } + protected override string IsAnyProcedureSql => throw new NotImplementedException(); + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select 1 from information_schema.columns limit 1 offset 0"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "DEFAULT NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "serial"; + } + } + #endregion + + #region Methods + public override List GetDbTypes() + { + var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT data_type +FROM information_schema.columns"); + result.Add("varchar"); + result.Add("timestamp"); + result.Add("uuid"); + result.Add("int2"); + result.Add("int4"); + result.Add("int8"); + result.Add("time"); + result.Add("date"); + result.Add("float8"); + result.Add("float4"); + result.Add("json"); + result.Add("jsonp"); + return result.Distinct().ToList(); + } + public override List GetTriggerNames(string tableName) + { + return this.Context.Ado.SqlQuery(@"SELECT tgname +FROM pg_trigger +WHERE tgrelid = '"+tableName+"'::regclass"); + } + public override List GetFuncList() + { + return this.Context.Ado.SqlQuery(" SELECT routine_name\r\nFROM information_schema.routines\r\nWHERE lower( routine_schema ) = '" + GetSchema().ToLower() + "' AND routine_type = 'FUNCTION' "); + } + public override List GetIndexList(string tableName) + { + var sql = $"SELECT indexname, indexdef FROM pg_indexes WHERE upper(tablename) = upper('{tableName}') AND upper(schemaname) = upper('{GetSchema()}')"; + return this.Context.Ado.SqlQuery(sql); + } + public override List GetProcList(string dbName) + { + var sql = $"SELECT proname FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = '{dbName}'"; + return this.Context.Ado.SqlQuery(sql); + } + public override bool AddDefaultValue(string tableName, string columnName, string defaultValue) + { + if (defaultValue?.StartsWith("'")==true&& defaultValue?.EndsWith("'") == true&& defaultValue?.Contains("(") == false + &&!defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql,this.SqlBuilder.GetTranslationColumnName( tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue.EqualCase("current_timestamp") || defaultValue.EqualCase("current_date")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue ); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.Contains("(") == false + && !defaultValue.EqualCase("'current_timestamp'") && !defaultValue.EqualCase("'current_date'")) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), "'"+defaultValue+"'"); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.ToLower()?.Contains("cast(") == true && defaultValue?.StartsWith("'") == true && defaultValue?.EndsWith("'") == true) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.Replace("''","'").TrimEnd('\'').TrimStart('\'')); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else if (defaultValue?.ToLower()?.Contains("now()") == true) + { + string sql = string.Format(AddDefaultValueSql, this.SqlBuilder.GetTranslationColumnName(tableName), this.SqlBuilder.GetTranslationColumnName(columnName), defaultValue.TrimEnd('\'').TrimStart('\'')); + return this.Context.Ado.ExecuteCommand(sql) > 0; + } + else + { + return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue); + } + } + + public override bool RenameTable(string oldTableName, string newTableName) + { + return base.RenameTable(this.SqlBuilder.GetTranslationTableName(oldTableName), this.SqlBuilder.GetTranslationTableName(newTableName)); + } + + public override bool AddColumnRemark(string columnName, string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string sql = string.Format(this.AddColumnRemarkSql, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), tableName, description); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + public override bool AddTableRemark(string tableName, string description) + { + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + return base.AddTableRemark(tableName, description); + } + public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo) + { + ConvertCreateColumnInfo(columnInfo); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + string sql = GetUpdateColumnSql(tableName, columnInfo); + this.Context.Ado.ExecuteCommand(sql); + var isnull = columnInfo.IsNullable?" DROP NOT NULL ": " SET NOT NULL "; + this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}",tableName,columnName, isnull)); + return true; + } + + protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo) + { + string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + tableName = this.SqlBuilder.GetTranslationTableName(tableName); + string dataSize = GetSize(columnInfo); + string dataType = columnInfo.DataType; + if (!string.IsNullOrEmpty(dataType)) + { + dataType = " type " + dataType; + } + string nullType = ""; + string primaryKey = null; + string identity = null; + string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity); + return result; + } + + /// + ///by current connection string + /// + /// + /// + public override bool CreateDatabase(string databaseName, string databaseDirectory = null) + { + if (databaseDirectory != null) + { + if (!FileHelper.IsExistDirectory(databaseDirectory)) + { + FileHelper.CreateDirectory(databaseDirectory); + } + } + var oldDatabaseName = this.Context.Ado.Connection.Database; + var connection = this.Context.CurrentConnectionConfig.ConnectionString; + connection = connection.Replace(oldDatabaseName, "postgres"); + var newDb = new SqlSugarClient(new ConnectionConfig() + { + DbType = this.Context.CurrentConnectionConfig.DbType, + IsAutoCloseConnection = true, + ConnectionString = connection + }); + if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) + { + var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel==DbType.Vastbase; + var dbcompatibility = ""; + if (isVast) + { + dbcompatibility=" dbcompatibility = 'PG'"; + } + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft+databaseName+this.SqlBuilder.SqlTranslationRight, databaseDirectory)+ dbcompatibility); + } + return true; + } + public override bool AddRemark(EntityInfo entity) + { + var db = this.Context; + var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList(); + + foreach (var item in columns) + { + if (item.ColumnDescription != null) + { + db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription); + + } + } + //table remak + if (entity.TableDescription != null) + { + db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription); + } + return true; + } + public override bool CreateTable(string tableName, List columns, bool isCreatePrimaryKey = true) + { + if (columns.HasValue()) + { + foreach (var item in columns) + { + ConvertCreateColumnInfo(item); + if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0) + { + if (item.DataType?.ToLower() != "uuid") + { + item.Length = 10; + } + } + } + } + string sql = GetCreateTableSql(tableName, columns); + string primaryKeyInfo = null; + if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey) + { + primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower(isAutoToLowerCodeFirst))))); + + } + sql = sql.Replace("$PrimaryKey", primaryKeyInfo); + this.Context.Ado.ExecuteCommand(sql); + return true; + } + protected override bool IsAnyDefaultValue(string tableName, string columnName, List columns) + { + var defaultValue = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.CurrentCultureIgnoreCase)).First().DefaultValue; + if (defaultValue?.StartsWith("NULL::") == true) + { + return false; + } + return defaultValue.HasValue(); + } + protected override string GetCreateTableSql(string tableName, List columns) + { + List columnArray = new List(); + Check.Exception(columns.IsNullOrEmpty(), "No columns found "); + foreach (var item in columns) + { + string columnName = item.DbColumnName; + string dataType = item.DataType; + if (dataType == "varchar" && item.Length == 0) + { + item.Length = 1; + } + //if (dataType == "uuid") + //{ + // item.Length = 50; + // dataType = "varchar"; + //} + string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; + if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric") + { + dataSize = $"({item.Length},{item.DecimalDigits})"; + } + string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull; + string primaryKey = null; + string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, nullType, primaryKey, ""); + if (item.IsIdentity) + { + if (dataType?.ToLower() == "int") + { + dataSize = "int4"; + } + else if (dataType?.ToLower() == "long") + { + dataSize = "int8"; + } + string length = dataType.Substring(dataType.Length - 1); + string identityDataType = "serial" + length; + addItem = addItem.Replace(dataType, identityDataType); + } + columnArray.Add(addItem); + } + string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToLower(isAutoToLowerCodeFirst)), string.Join(",\r\n", columnArray)); + return tableString; + } + public override bool IsAnyConstraint(string constraintName) + { + throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException"); + } + public override bool BackupDataBase(string databaseName, string fullFileName) + { + Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported"); + return false; + } + + public override List GetColumnInfosByTableName(string tableName, bool isCache = true) + { + var result= base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); + if (result == null || result.Count() == 0) + { + result = base.GetColumnInfosByTableName(tableName, isCache); + } + try + { + string sql = $@"select + kcu.column_name as key_column + from information_schema.table_constraints tco + join information_schema.key_column_usage kcu + on kcu.constraint_name = tco.constraint_name + and kcu.constraint_schema = tco.constraint_schema + and kcu.constraint_name = tco.constraint_name + where tco.constraint_type = 'PRIMARY KEY' + and kcu.table_schema='{GetSchema()}' and + upper(kcu.table_name)=upper('{tableName.TrimEnd('"').TrimStart('"')}')"; + List pkList = new List(); + if (isCache) + { + pkList=GetListOrCache("GetColumnInfosByTableName_N_Pk"+tableName, sql); + } + else + { + pkList = this.Context.Ado.SqlQuery(sql); + } + if (pkList.Count >1) + { + foreach (var item in result) + { + if (pkList.Select(it=>it.ToUpper()).Contains(item.DbColumnName.ToUpper())) + { + item.IsPrimarykey = true; + } + } + } + } + catch + { + + } + return result; + } + #endregion + + #region Helper + private bool isAutoToLowerCodeFirst + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + else if ( + this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower == false && + this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLowerCodeFirst == false) + { + return false; + } + else + { + return true; + } + } + } + private string GetSchema() + { + var schema = "public"; + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + + return schema; + } + private static void ConvertCreateColumnInfo(DbColumnInfo x) + { + string[] array = new string[] { "uuid","int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; + + if (array.Contains(x.DataType?.ToLower())) + { + x.Length = 0; + x.DecimalDigits = 0; + } + } + #endregion + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Insertable/TDSQLForPGODBCInserttable.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Insertable/TDSQLForPGODBCInserttable.cs new file mode 100644 index 000000000..2ced9b60f --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Insertable/TDSQLForPGODBCInserttable.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCInserttable : InsertableProvider where T : class, new() + { + public override int ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt(); + After(sql, result); + return result; + } + public override async Task ExecuteReturnIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string identityColumn = GetIdentityColumn(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn)); + RestoreMapping(); + AutoRemoveDataCache(); + var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()); + var result = obj.ObjToInt(); + After(sql, result); + return result; + } + public override KeyValuePair> ToSql() + { + var result= base.ToSql(); + var primaryKey = GetPrimaryKeys().FirstOrDefault(); + if (primaryKey != null) + { + primaryKey = this.SqlBuilder.GetTranslationColumnName(primaryKey); + } + else if(result.Key?.EndsWith(" returning $PrimaryKey") ==true) + { + result=new KeyValuePair>( result.Key.Replace(" returning $PrimaryKey", null),result.Value); + } + return new KeyValuePair>(result.Key.Replace("$PrimaryKey", primaryKey), result.Value); + } + + public override long ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + After(sql, result); + return result; + } + public override async Task ExecuteReturnBigIdentityAsync() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault())); + RestoreMapping(); + AutoRemoveDataCache(); + var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0"); + After(sql, result); + return result; + } + + public override bool ExecuteCommandIdentityIntoEntity() + { + var result = InsertObjs.First(); + var identityKeys = GetIdentityKeys(); + if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; } + var idValue = ExecuteReturnBigIdentity(); + Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys"); + var identityKey = identityKeys.First(); + object setValue = 0; + if (idValue > int.MaxValue) + setValue = idValue; + else + setValue = Convert.ToInt32(idValue); + var propertyName = this.Context.EntityMaintenance.GetPropertyName(identityKey); + typeof(T).GetProperties().First(t => t.Name.ToUpper() == propertyName.ToUpper()).SetValue(result, setValue, null); + return idValue > 0; + } + + private string GetIdentityColumn() + { + var identityColumn = GetIdentityKeys().FirstOrDefault(); + if (identityColumn == null) + { + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(InsertBuilder.GetTableNameString); + identityColumn = columns.First(it => it.IsIdentity || it.IsPrimarykey).DbColumnName; + } + return identityColumn; + } + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Queryable/TDSQLForPGODBCQueryable.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Queryable/TDSQLForPGODBCQueryable.cs new file mode 100644 index 000000000..2b5265d89 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/Queryable/TDSQLForPGODBCQueryable.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + + public override ISugarQueryable PartitionBy(string groupFileds) + { + this.GroupBy(groupFileds); + return this; + } + } + public class PostgreSQLQueryable : QueryableProvider + { + public new ISugarQueryable With(string withString) + { + return this; + } + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } + public class PostgreSQLQueryable : QueryableProvider + { + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCBuilder.cs new file mode 100644 index 000000000..2fc928907 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCBuilder.cs @@ -0,0 +1,128 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCBuilder : SqlBuilderProvider + { + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string SqlDateNow + { + get + { + return "CURRENT_TIMESTAMP"; + } + } + public override string FullSqlDateNow + { + get + { + return "select CURRENT_TIMESTAMP"; + } + } + + public bool isAutoToLower + { + get + { + if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true; + return this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower; + } + } + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains(".")&& !propertyName.Contains(SqlTranslationLeft)) + { + return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToLower(isAutoToLower)}{SqlTranslationRight}")); + } + + if (propertyName.Contains(SqlTranslationLeft)) return propertyName; + else + return SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight; + } + + //public override string GetNoTranslationColumnName(string name) + //{ + // return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower(); + //} + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(ErrorMessage.ObjNotExist, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToLower(isAutoToLower) + SqlTranslationRight); + } + + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + var context = this.Context; + + var mappingInfo = context + .MappingTables + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo == null && name.Contains(".") && name.Contains("\"")) + { + return name; + } + name = (mappingInfo == null ? name : mappingInfo.DbTableName); + if (name.Contains(".")&& !name.Contains("(")&&!name.Contains("\".\"")) + { + return string.Join(".", name.ToLower(isAutoToLower).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight)); + } + else if (name.Contains("(")) + { + return name; + } + else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight)) + { + return name; + } + else + { + return SqlTranslationLeft + name.ToLower(isAutoToLower).TrimEnd('"').TrimStart('"') + SqlTranslationRight; + } + } + public override string GetUnionFomatSql(string sql) + { + return " ( " + sql + " ) "; + } + + public override Type GetNullType(string tableName, string columnName) + { + if (tableName != null) + tableName = tableName.Trim(); + var columnInfo=this.Context.DbMaintenance.GetColumnInfosByTableName(tableName).FirstOrDefault(z => z.DbColumnName.EqualCase(columnName)); + if (columnInfo != null) + { + var cTypeName=this.Context.Ado.DbBind.GetCsharpTypeNameByDbTypeName(columnInfo.DataType); + var value=UtilMethods.GetTypeByTypeName(cTypeName); + if (value != null) + { + var key = "GetNullType_" + tableName + columnName; + return new ReflectionInoCacheService().GetOrCreate(key, () => value); + } + } + return null; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCDeleteBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCDeleteBuilder.cs new file mode 100644 index 000000000..222e7369b --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCDeleteBuilder.cs @@ -0,0 +1,7 @@ +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs new file mode 100644 index 000000000..939dafc6c --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs @@ -0,0 +1,497 @@ +using System; +using System.Linq; +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarProvider Context { get; set; } + public TDSQLForPGODBCExpressionContext() + { + base.DbMehtods = new TDSQLForPGODBCMethod(); + } + public override string SqlTranslationLeft + { + get + { + return "\""; + } + } + public override string SqlTranslationRight + { + get + { + return "\""; + } + } + public override string GetTranslationText(string name) + { + return SqlTranslationLeft + name.ToLower(isAutoToLower) + SqlTranslationRight; + } + public bool isAutoToLower + { + get + { + return base.PgSqlIsAutoToLower; + } + } + public override string GetTranslationTableName(string entityName, bool isMapping = true) + { + Check.ArgumentNullException(entityName, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + if (IsTranslationText(entityName)) return entityName; + isMapping = isMapping && this.MappingTables.HasValue(); + var isComplex = entityName.Contains(UtilConstants.Dot); + if (isMapping && isComplex) + { + var columnInfo = entityName.Split(UtilConstants.DotChar); + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null) + { + columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName; + } + return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it))); + } + else if (isMapping) + { + var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); + + var tableName = mappingInfo?.DbTableName+""; + if (tableName.Contains(".")) + { + tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + return tableName; + } + + return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToLower(isAutoToLower) + SqlTranslationRight; + } + else if (isComplex) + { + return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(entityName); + } + } + public override string GetTranslationColumnName(string columnName) + { + Check.ArgumentNullException(columnName, string.Format(ErrorMessage.ObjNotExist, "Column Name")); + if (columnName.Substring(0, 1) == this.SqlParameterKeyWord) + { + return columnName; + } + if (IsTranslationText(columnName)) return columnName; + if (columnName.Contains(UtilConstants.Dot)) + { + return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); + } + else + { + return GetTranslationText(columnName); + } + } + public override string GetDbColumnName(string entityName, string propertyName) + { + if (this.MappingColumns.HasValue()) + { + var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName); + return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToLower(isAutoToLower); + } + else + { + return propertyName.ToLower(isAutoToLower); + } + } + + public string GetValue(object entityValue) + { + if (entityValue == null) + return null; + var type = UtilMethods.GetUnderType(entityValue.GetType()); + if (UtilConstants.NumericalTypes.Contains(type)) + { + return entityValue.ToString(); + } + else if (type == UtilConstants.DateType) + { + return this.DbMehtods.ToDate(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + else + { + return this.DbMehtods.ToString(new MethodCallExpressionModel() + { + Args = new System.Collections.Generic.List() { + new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" } + } + }); + } + } + } + public class TDSQLForPGODBCMethod : DefaultDbMethod, IDbMethods + { + public override string CharIndex(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string CharIndexNew(MethodCallExpressionModel model) + { + return string.Format(" (strpos ({0},{1}))", model.Args[0].MemberName, model.Args[1].MemberName); + } + public override string TrueValue() + { + return "true"; + } + public override string FalseValue() + { + return "false"; + } + public override string DateDiff(MethodCallExpressionModel model) + { + var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString())); + var begin = model.Args[1].MemberName; + var end = model.Args[2].MemberName; + switch (parameter) + { + case DateType.Year: + return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )"; + case DateType.Month: + return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )"; + case DateType.Day: + return $" ( DATE_PART('day', {end} - {begin}) )"; + case DateType.Hour: + return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )"; + case DateType.Minute: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )"; + case DateType.Second: + return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('second', {end} - {begin} )"; + case DateType.Millisecond: + break; + default: + break; + } + throw new Exception(parameter + " datediff no support"); + } + public override string IIF(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + if (parameter.Type == UtilConstants.BoolType) + { + parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); + parameter2.MemberName = false; + parameter3.MemberName = true; + } + return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName); + } + public override string DateValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var format = "dd"; + if (parameter2.MemberValue.ObjToString() == DateType.Year.ToString()) + { + format = "yyyy"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Month.ToString()) + { + format = "MM"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Day.ToString()) + { + format = "dd"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Hour.ToString()) + { + format = "hh24"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Minute.ToString()) + { + format = "mi"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Second.ToString()) + { + format = "ss"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Millisecond.ToString()) + { + format = "ms"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Quarter.ToString()) + { + format = "q"; + } + if (parameter2.MemberValue.ObjToString() == DateType.Weekday.ToString()) + { + return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) "; + } + + return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName); + } + + public override string Contains(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName ); + } + + public override string StartsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName); + } + + public override string EndsWith(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName,parameter2.MemberName); + } + + public override string DateIsSameDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ; + } + + public override string HasValue(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NOT NULL )", parameter.MemberName); + } + + public override string DateIsSameByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + DateType dateType =(DateType)parameter3.MemberValue; + var format = "yyyy-MM-dd"; + if (dateType == DateType.Quarter) + { + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName,format); + } + switch (dateType) + { + case DateType.Year: + format = "yyyy"; + break; + case DateType.Month: + format = "yyyy-MM"; + break; + case DateType.Day: + break; + case DateType.Hour: + format = "yyyy-MM-dd HH"; + break; + case DateType.Second: + format = "yyyy-MM-dd HH:mm:ss"; + break; + case DateType.Minute: + format = "yyyy-MM-dd HH:mm"; + break; + case DateType.Millisecond: + format = "yyyy-MM-dd HH:mm.ms"; + break; + default: + break; + } + return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format); + } + + public override string ToDate(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS timestamp)", parameter.MemberName); + } + public override string DateAddByType(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + return string.Format(" ({1} + ({2}||'{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName); + } + + public override string DateAddDay(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName); + } + + public override string ToInt32(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT4)", parameter.MemberName); + } + + public override string ToInt64(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS INT8)", parameter.MemberName); + } + + public override string ToString(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName); + } + + public override string ToGuid(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS UUID)", parameter.MemberName); + } + + public override string ToDouble(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string ToBool(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS boolean)", parameter.MemberName); + } + + public override string ToDecimal(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName); + } + + public override string Length(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format(" LENGTH({0})", parameter.MemberName); + } + public override string IsNullOrEmpty(MethodCallExpressionModel model) + { + if ( + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase|| + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.GaussDB) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL )", parameter.MemberName); + } + else + { + return base.IsNullOrEmpty(model); + } + } + public override string MergeString(params string[] strings) + { + var key = Guid.NewGuid() + ""; + return " concat("+string.Join(",", strings.Select(it=>it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; + } + public override string IsNull(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName); + } + public override string GetDate() + { + return "NOW()"; + } + public override string GetRandom() + { + return "RANDOM()"; + } + + public override string EqualTrue(string fieldName) + { + return "( " + fieldName + "=true )"; + } + + public override string JsonField(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + //var parameter2 = model.Args[2]; + //var parameter3= model.Args[3]; + var result= GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count()==2); + if (model.Args.Count > 2) + { + result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3); + } + if (model.Args.Count > 3) + { + result = GetJson(result, model.Args[3].MemberName, model.Args.Count() == 4); + } + if (model.Args.Count > 4) + { + result = GetJson(result, model.Args[4].MemberName, model.Args.Count() == 5); + } + if (model.Args.Count > 5) + { + result = GetJson(result, model.Args[5].MemberName, model.Args.Count() == 6); + } + return result; + } + + public override string JsonContainsFieldName(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + var parameter1 = model.Args[1]; + return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; + } + + private string GetJson(object memberName1, object memberName2,bool isLast) + { + if (isLast) + { + return $"({memberName1}::json->>{memberName2})"; + } + else + { + return $"({memberName1}->{memberName2})"; + } + } + + public override string JsonArrayLength(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" json_array_length({parameter.MemberName}::json) "; + } + + public override string JsonParse(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + //var parameter1 = model.Args[1]; + return $" ({parameter.MemberName}::json) "; + } + + public override string JsonArrayAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb "; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb "; + } + } + public override string JsonListObjectAny(MethodCallExpressionModel model) + { + if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb "; + } + else + { + return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb "; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCFastBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCFastBuilder.cs new file mode 100644 index 000000000..aac39a750 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCFastBuilder.cs @@ -0,0 +1,169 @@ +using Npgsql; +using NpgsqlTypes; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCFastBuilder : FastBuilder, IFastBuilder + { + public static Dictionary PgSqlType = UtilMethods.EnumToDictionary(); + private EntityInfo entityInfo; + + public TDSQLForPGODBCFastBuilder(EntityInfo entityInfo) + { + this.entityInfo = entityInfo; + } + + public override string UpdateSql { get; set; } = @"UPDATE {1} SET {0} FROM {2} AS TE WHERE {3} +"; + + //public virtual async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + //{ + // Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + // Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + // var sets = string.Join(",", updateColumns.Select(it => $"TM.{it}=TE.{it}")); + // var wheres = string.Join(",", whereColumns.Select(it => $"TM.{it}=TE.{it}")); + // string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + // return await this.Context.Ado.ExecuteCommandAsync(sql); + //} + public async Task ExecuteBulkCopyAsync(DataTable dt) + { + List lsColNames = new List(); + for (int i = 0; i < dt.Columns.Count; i++) + { + lsColNames.Add($"\"{dt.Columns[i].ColumnName}\""); + } + string copyString = $"COPY {dt.TableName} ( {string.Join(",", lsColNames) } ) FROM STDIN (FORMAT BINARY)"; + if (this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.OpenGauss) + { + copyString = copyString.Replace("(FORMAT BINARY)", "(FORMAT 'BINARY')"); + } + NpgsqlConnection conn = (NpgsqlConnection)this.Context.Ado.Connection; + var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(this.entityInfo.DbTableName); + try + { + var identityColumnInfo = this.entityInfo.Columns.FirstOrDefault(it => it.IsIdentity); + if (identityColumnInfo != null) + { + throw new Exception("PgSql bulkcopy no support identity"); + } + BulkCopy(dt, copyString, conn, columns); + } + catch (Exception ex) + { + throw ex; + } + finally + { + base.CloseDb(); + } + return await Task.FromResult(dt.Rows.Count); + } + + private void BulkCopy(DataTable dt, string copyString, NpgsqlConnection conn, List columns) + { + if (conn.State == ConnectionState.Closed) + conn.Open(); + List columnViews = new List(); + foreach (DataColumn item in dt.Columns) + { + ColumnView result = new ColumnView(); + result.DbColumnInfo = columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + result.DataColumn = item; + result.EntityColumnInfo=this.entityInfo.Columns.FirstOrDefault(it => it.DbColumnName.EqualCase(item.ColumnName)); + var key = result.DbColumnInfo?.DataType?.ToLower(); + if (result.DbColumnInfo == null) + { + result.Type = null; + } + else if (PgSqlType.ContainsKey(key)) + { + result.Type = PgSqlType[key]; + } + else if (key?.First() == '_') + { + if (key == "_int4") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Integer; + } + else if (key == "_int2") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Smallint; + } + else if (key == "_int8") + { + result.Type = NpgsqlDbType.Array | NpgsqlDbType.Bigint; + } + else + { + var type = PgSqlType[key.Substring(1)]; + result.Type = NpgsqlDbType.Array | type; + } + } + else + { + result.Type = null; + } + columnViews.Add(result); + } + using (var writer = conn.BeginBinaryImport(copyString)) + { + foreach (DataRow row in dt.Rows) + { + writer.StartRow(); + foreach (var column in columnViews) + { + var value = row[column.DataColumn.ColumnName]; + if (value == null) + { + value = DBNull.Value; + } + //else if (value is double&&this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel==null) + //{ + // column.Type = NpgsqlDbType.Double; + //} + if (column.Type == null) + { + writer.Write(value); + } + else + { + writer.Write(value, column.Type.Value); + } + } + } + writer.Complete(); + } + } + + + public override async Task UpdateByTempAsync(string tableName, string tempName, string[] updateColumns, string[] whereColumns) + { + var sqlquerybulder= this.Context.Queryable().SqlBuilder; + Check.ArgumentNullException(!updateColumns.Any(), "update columns count is 0"); + Check.ArgumentNullException(!whereColumns.Any(), "where columns count is 0"); + var sets = string.Join(",", updateColumns.Select(it => $"{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + var wheres = string.Join(" AND ", whereColumns.Select(it => $"{tableName}.{sqlquerybulder.GetTranslationColumnName(it)}=TE.{sqlquerybulder.GetTranslationColumnName(it)}")); + string sql = string.Format(UpdateSql, sets, tableName, tempName, wheres); + return await this.Context.Ado.ExecuteCommandAsync(sql); + } + public override async Task CreateTempAsync(DataTable dt) + { + await this.Context.Queryable().Where(it => false).AS(dt.TableName).Select(" * into temp mytemptable").ToListAsync(); + dt.TableName = "mytemptable"; + } + + public class ColumnView + { + public DataColumn DataColumn { get; set; } + public EntityColumnInfo EntityColumnInfo { get; set; } + public DbColumnInfo DbColumnInfo { get; set; } + public NpgsqlDbType? Type { get; set; } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs new file mode 100644 index 000000000..39dc62a69 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs @@ -0,0 +1,196 @@ +using System; +using System.Linq; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCInsertBuilder : InsertBuilder + { + public override string SqlTemplate + { + get + { + if (IsReturnIdentity) + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) returning $PrimaryKey"; + } + else + { + return @"INSERT INTO {0} + ({1}) + VALUES + ({2}) ;"; + + } + } + } + public override string SqlTemplateBatch => "INSERT INTO {0} ({1})"; + public override string SqlTemplateBatchUnion => " VALUES "; + + public override string SqlTemplateBatchSelect => " {0} "; + + public override Func ConvertInsertReturnIdFunc { get; set; } = (name, sql) => + { + return sql.Trim().TrimEnd(';')+ $"returning {name} "; + }; + public override string ToSqlString() + { + if (IsNoInsertNull) + { + DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList(); + } + var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList(); + var isSingle = groupList.Count() == 1; + string columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName))); + if (isSingle) + { + string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it =>base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName))); + ActionMinDate(); + return GetIgnoreSql(string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString)); + } + else + { + StringBuilder batchInsetrSql = new StringBuilder(); + int pageSize = 200; + int pageIndex = 1; + if (IsNoPage&&IsReturnPkList) + { + pageSize = groupList.Count; + } + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + while (pageCount >= pageIndex) + { + batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); + int i = 0; + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (isFirst) + { + batchInsetrSql.Append(SqlTemplateBatchUnion); + } + batchInsetrSql.Append("\r\n ( " + string.Join(",", columns.Select(it => + { + if (it.InsertServerTime || it.InsertSql.HasValue()||it.SqlParameterDbType is Type|| it?.PropertyType?.Name=="DateOnly" || it?.PropertyType?.Name == "TimeOnly") + { + return GetDbColumn(it, null); + } + object value = null; + if (it.Value is DateTime) + { + var date = ((DateTime)it.Value); + value = date.ToString("O"); + if (date==DateTime.MaxValue) + { + value = "9999-12-31T23:59:59.999999"; + } + } + else if (it.Value is DateTimeOffset) + { + return FormatDateTimeOffset(it.Value); + } + else if (it.IsArray&&it.Value!=null) + { + return FormatValue(it.Value,it.PropertyName,i,it); + } + else if (it.Value is byte[]) + { + return FormatValue(it.Value, it.PropertyName, i, it); + } + else + { + value = it.Value; + } + if (value == null||value==DBNull.Value) + { + return string.Format(SqlTemplateBatchSelect, "NULL"); + } + return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToStringNoTrim().ToSqlFilter() + "'"); + })) + "),"); + ++i; + } + pageIndex++; + batchInsetrSql.Remove(batchInsetrSql.Length - 1,1).Append("\r\n;\r\n"); + } + return GetIgnoreSql(batchInsetrSql.ToString()); + } + } + + public object FormatValue(object value, string name, int i, DbColumnInfo columnInfo) + { + if (value == null) + { + return "NULL"; + } + else + { + var type = value.GetType(); + if (type == UtilConstants.ByteArrayType||type == UtilConstants.DateType || columnInfo.IsArray || columnInfo.IsJson) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + var paramter = new SugarParameter(parameterName, value); + if (columnInfo.IsJson) + { + paramter.IsJson = true; + } + if (columnInfo.IsArray) + { + paramter.IsArray = true; + } + this.Parameters.Add(paramter); + return parameterName; + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + return bytesString; + } + else if (type.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + return value.ToSqlValue(); + } + else + { + return Convert.ToInt64(value); + } + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + + private string GetIgnoreSql(string sql) + { + if (this.ConflictNothing?.Any() == true) + { + sql = sql.Replace(";", $" ON CONFLICT ({string.Join(",", this.ConflictNothing)}) DO NOTHING;"); + } + + return sql; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCQueryBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCQueryBuilder.cs new file mode 100644 index 000000000..c53a4d4f7 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCQueryBuilder.cs @@ -0,0 +1,130 @@ +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDSQLForPGODBC +{ + public partial class TDSQLForPGODBCQueryBuilder : QueryBuilder + { + #region Sql Template + public override string PageTempalte + { + get + { + /* + SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0 + */ + var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}"; + return template; + } + } + public override string DefaultOrderByTemplate + { + get + { + return "ORDER BY NOW() "; + } + } + + #endregion + + #region Common Methods + public override string GetTableNameString + { + get + { + if (this.TableShortName != null&&this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower==false) + { + this.TableShortName = Builder.GetTranslationColumnName(this.TableShortName); + } + return base.GetTableNameString; + } + } + public override bool IsComplexModel(string sql) + { + return Regex.IsMatch(sql, @"AS ""\w+\.\w+""")|| Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+"""); + } + public override string ToSqlString() + { + base.AppendFilter(); + string oldOrderValue = this.OrderByValue; + var isNullOrderValue = Skip == 0 && Take == 1 && oldOrderValue == "ORDER BY NOW() "; + if (isNullOrderValue) + { + this.OrderByValue = null; + } + string result = null; + sql = new StringBuilder(); + sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString); + if (IsCount) { return sql.ToString(); } + if (Skip != null && Take == null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue); + } + else if (Skip == null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt()); + } + else if (Skip != null && Take != null) + { + if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0]; + result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take); + } + else + { + result = sql.ToString(); + } + this.OrderByValue = oldOrderValue; + result = GetSqlQuerySql(result); + if (result.IndexOf("-- No table") > 0) + { + return "-- No table"; + } + if (TranLock != null) + { + result = result + TranLock; + } + //if (result.Contains("uuid_generate_v4()")) + //{ + // result=" CREATE EXTENSION IF NOT EXISTS pgcrypto;CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"; "+ result; + //} + return result; + } + + #endregion + + #region Get SQL Partial + public override string GetSelectValue + { + get + { + string result = string.Empty; + if (this.SelectValue == null || this.SelectValue is string) + { + result = GetSelectValueByString(); + } + else + { + result = GetSelectValueByExpression(); + } + if (this.SelectType == ResolveExpressType.SelectMultiple) + { + this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName)); + } + if (IsDistinct&&result?.TrimStart()?.StartsWith("distinct ")!=true) + { + result = "distinct "+result; + } + if (this.SubToListParameters != null && this.SubToListParameters.Any()) + { + result = SubToListMethod(result); + } + return result; + } + } + + #endregion + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs new file mode 100644 index 000000000..83e1b4719 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class TDSQLForPGODBCUpdateBuilder : UpdateBuilder + { + public override string SqlTemplateBatch + { + get + { + return @"UPDATE {1} {2} SET {0} FROM ${{0}} "; + } + } + public override string SqlTemplateJoin + { + get + { + return @" (VALUES + {0} + + ) AS T ({2}) WHERE {1} + "; + } + } + + public override string SqlTemplateBatchUnion + { + get + { + return ","; + } + } + + public object FormatValue(object value,string name,int i,DbColumnInfo columnInfo) + { + if (value == null) + { + return "NULL"; + } + else + { + var type =UtilMethods.GetUnderType(value.GetType()); + if (type == UtilConstants.ByteArrayType||type == UtilConstants.DateType||columnInfo.IsArray||columnInfo.IsJson) + { + var parameterName = this.Builder.SqlParameterKeyWord + name + i; + var paramter = new SugarParameter(parameterName, value); + if (columnInfo.IsJson) + { + paramter.IsJson = true; + } + if (columnInfo.IsArray) + { + paramter.IsArray = true; + } + this.Parameters.Add(paramter); + return parameterName; + } + else if (type == UtilConstants.DateTimeOffsetType) + { + return FormatDateTimeOffset(value); + } + else if (type == UtilConstants.ByteArrayType) + { + string bytesString = "0x" + BitConverter.ToString((byte[])value); + return bytesString; + } + else if (type.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + return value.ToSqlValue(); + } + else + { + return Convert.ToInt64(value); + } + } + else if (type == UtilConstants.BoolType) + { + return value.ObjToBool() ? "1" : "0"; + } + else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) + { + return "'" + value.ToString().ToSqlFilter() + "'"; + } + else + { + return "'" + value.ToString() + "'"; + } + } + } + + protected override string TomultipleSqlString(List> groupList) + { + Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List need Primary key"); + int pageSize = 200; + int pageIndex = 1; + int totalRecord = groupList.Count; + int pageCount = (totalRecord + pageSize - 1) / pageSize; + StringBuilder batchUpdateSql = new StringBuilder(); + while (pageCount >= pageIndex) + { + StringBuilder updateTable = new StringBuilder(); + string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue != null && setValue.Any()) + { + return setValue.First().Value; + } + } + var result = string.Format("{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName)); + return result; + })); + string tempColumnValue = string.Join(",", groupList.First().Select(it => + { + if (SetValues.IsValuable()) + { + var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName)); + if (setValue != null && setValue.Any()) + { + return setValue.First().Value; + } + } + var result = Builder.GetTranslationColumnName(it.DbColumnName); + return result; + })); + batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString); + int i = 0; + var tableColumnList = this.Context.DbMaintenance.GetColumnInfosByTableName(GetTableNameStringNoWith); + + foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) + { + var isFirst = i == 0; + if (!isFirst) + { + updateTable.Append(SqlTemplateBatchUnion); + } + updateTable.Append("\r\n (" + string.Join(",", columns.Select(it => + { + var columnInfo = tableColumnList.FirstOrDefault(x => x.DbColumnName.Equals(it.DbColumnName, StringComparison.OrdinalIgnoreCase)); + var dbType = columnInfo?.DataType; + if (dbType == null) { + var typeName = it.PropertyType.Name.ToLower(); + if (columnInfo==null&&it.PropertyType.IsEnum) + { + if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString!=true) + { + typeName = "int"; + } + } + if (typeName == "int32") + typeName = "int"; + if (typeName == "int64") + typeName = "long"; + if (typeName == "int16") + typeName = "short"; + if (typeName == "boolean") + typeName = "bool"; + + var isAnyType = TDSQLForPGODBCDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).Any(); + if (isAnyType) + { + dbType = TDSQLForPGODBCDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).FirstOrDefault().Key; + } + else { + dbType = "varchar"; + } + } + if(it?.PropertyType?.FullName == "NetTopologySuite.Geometries.Geometry") + { + return string.Format(" {0} ", base.GetDbColumn(it, FormatValue(it.Value, it.DbColumnName, i + (pageIndex - 1) * 100000, it)), dbType); + } + return string.Format("CAST({0} AS {1})", base.GetDbColumn(it,FormatValue(it.Value,it.DbColumnName,i+(pageIndex-1)*100000,it)), dbType); + + })) + ")"); + ++i; + } + pageIndex++; + updateTable.Append("\r\n"); + string whereString = null; + if (this.WhereValues.HasValue()) + { + foreach (var item in WhereValues) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += item; + } + } + else if (PrimaryKeys.HasValue()) + { + foreach (var item in PrimaryKeys) + { + var isFirst = whereString == null; + whereString += (isFirst ? null : " AND "); + whereString += string.Format("{0}.{1}=T.{1}", GetTableNameStringNoWith, Builder.GetTranslationColumnName(item)); + } + } + var format = string.Format(SqlTemplateJoin, updateTable, whereString, tempColumnValue); + batchUpdateSql.Replace("${0}", format); + batchUpdateSql.Append(";"); + } + batchUpdateSql = GetBatchUpdateSql(batchUpdateSql); + return batchUpdateSql.ToString(); + } + + private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql) + { + if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null) + { + var result = batchUpdateSql.ToString(); + foreach (var item in ReSetValueBySqlExpList) + { + var dbColumnName = item.Value.DbColumnName; + if (item.Value.Type == ReSetValueBySqlExpListModelType.List) + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={GetTableNameString}.{dbColumnName}{item.Value.Sql}T.{dbColumnName}"); + } + else + { + if (item.Value?.Sql?.StartsWith("( CASE WHEN")==true) + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(" \"", $" {Builder.GetTranslationColumnName(this.TableName)}.\"")}"); + } + else + { + result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(dbColumnName, $"{Builder.GetTranslationColumnName(this.TableName)}.{dbColumnName}")}"); + } + } + batchUpdateSql = new StringBuilder(result); + } + } + + return batchUpdateSql; + } + protected override string GetJoinUpdate(string columnsString, ref string whereString) + { + if (this.JoinInfos?.Count > 1) + { + return this.GetJoinUpdateMany(columnsString,whereString); + } + var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} "; + var joinString = ""; + foreach (var item in this.JoinInfos) + { + whereString += " AND "+item.JoinWhere; + joinString += $"\r\n FROM {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} "; + } + var tableName = formString + "\r\n "; + columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName)+".","")+joinString; + return string.Format(SqlTemplate, tableName, columnsString, whereString); + } + private string GetJoinUpdateMany(string columnsString,string where) + { + var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} "; + var joinString = ""; + var i = 0; + foreach (var item in this.JoinInfos) + { + var whereString = " ON " + item.JoinWhere; + joinString += $"\r\n JOIN {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} "; + joinString = joinString + whereString; + i++; + } + var tableName = Builder.GetTranslationColumnName(this.TableName) + "\r\n "; + columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName) + ".", "") + $" FROM {Builder.GetTranslationColumnName(this.TableName)} {Builder.GetTranslationColumnName(this.ShortName)}\r\n " + joinString; + return string.Format(SqlTemplate, tableName, columnsString, where); + } + public override string FormatDateTimeOffset(object value) + { + return "'" + ((DateTimeOffset)value).ToString("o") + "'"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/TDSQLForPGODBCProvider.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/TDSQLForPGODBCProvider.cs new file mode 100644 index 000000000..71e826ee1 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/TDSQLForPGODBCProvider.cs @@ -0,0 +1,370 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using System.Data.Odbc; +using System.Text.RegularExpressions; +using System.Data.SqlTypes; + +namespace SqlSugar.TDSQLForPGODBC +{ + /// + /// 适配TDSQL的ODBC驱动 + /// + public class TDSQLForPGODBCProvider : AdoProvider + { + public TDSQLForPGODBCProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + try + { + base._DbConnection = new OdbcConnection(base.Context.CurrentConnectionConfig.ConnectionString); + } + catch (Exception ex) + { + throw ex; + } + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + + public string SplitCommandTag => UtilConstants.ReplaceCommaKey.Replace("{", "").Replace("}", ""); + + + public override object GetScalar(string sql, params SugarParameter[] parameters) + { + if (this.Context.Ado.Transaction != null) + { + return _GetScalar(sql, parameters); + } + else + { + try + { + this.Context.Ado.BeginTran(); + var result = _GetScalar(sql, parameters); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception ex) + { + this.Context.Ado.RollbackTran(); + throw ex; + } + } + } + + public override async Task GetScalarAsync(string sql, params SugarParameter[] parameters) + { + if (this.Context.Ado.Transaction != null) + { + return await _GetScalarAsync(sql, parameters); + } + else + { + try + { + this.Context.Ado.BeginTran(); + var result = await _GetScalarAsync(sql, parameters); + this.Context.Ado.CommitTran(); + return result; + } + catch (Exception ex) + { + this.Context.Ado.RollbackTran(); + throw ex; + } + } + } + private object _GetScalar(string sql, SugarParameter[] parameters) + { + if (sql == null) throw new Exception("sql is null"); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + object result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") + { + result = base.GetScalar(item, parameters); + } + } + return result; + } + else + { + return base.GetScalar(sql, parameters); + } + } + private async Task _GetScalarAsync(string sql, SugarParameter[] parameters) + { + if (sql == null) throw new Exception("sql is null"); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + object result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") + { + result = await base.GetScalarAsync(item, parameters); + } + } + return result; + } + else + { + return await base.GetScalarAsync(sql, parameters); + } + } + + public override int ExecuteCommand(string sql, SugarParameter[] parameters) + { + if (sql == null) throw new Exception("sql is null"); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + int result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") + { + result += base.ExecuteCommand(item, parameters); + } + } + return result; + } + else + { + return base.ExecuteCommand(sql, parameters); + } + } + public override async Task ExecuteCommandAsync(string sql, SugarParameter[] parameters) + { + if (sql == null) throw new Exception("sql is null"); + if (sql.IndexOf(this.SplitCommandTag) > 0) + { + var sqlParts = Regex.Split(sql, this.SplitCommandTag).Where(it => !string.IsNullOrEmpty(it)).ToList(); + int result = 0; + foreach (var item in sqlParts) + { + if (item.TrimStart('\r').TrimStart('\n') != "") + { + result += await base.ExecuteCommandAsync(item, parameters); + } + } + return result; + } + else + { + return base.ExecuteCommand(sql, parameters); + } + } + + /// + /// Only Odbc + /// + /// + public override void BeginTran(string transactionName) + { + CheckConnection(); + base.Transaction = ((OdbcConnection)this.Connection).BeginTransaction(); + } + /// + /// Only Odbc + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + CheckConnection(); + base.Transaction = ((OdbcConnection)this.Connection).BeginTransaction(iso); + } + + public override IDataAdapter GetAdapter() + { + return new TDSQLForPGODBCAdapter(); + } + public override DbCommand GetCommand(string sql, SugarParameter[] parameters) + { + var helper = new TDSQLForPGODBCInsertBuilder(); + helper.Context = this.Context; + List orderParameters = new List(); + if (parameters.HasValue()) + { + foreach (var p in parameters) + { + if (!p.ParameterName.StartsWith(this.SqlParameterKeyWord)) + { + p.ParameterName = this.SqlParameterKeyWord + p.ParameterName; + } + } + orderParameters = parameters.Where(it => sql.Contains(it.ParameterName)) + .Select(it => new { p = it, sort = GetSortId(sql, it) }) + .OrderBy(it => it.sort) + .Where(it => it.sort != 0) + .Select(it => it.p) + .ToList(); + foreach (var param in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + sql = sql.Replace(param.ParameterName, "?"); + } + + } + OdbcCommand sqlCommand = new OdbcCommand(sql, (OdbcConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (OdbcTransaction)this.Transaction; + } + if (orderParameters.HasValue()) + { + OdbcParameter[] ipars = GetSqlParameter(orderParameters.ToArray()); + sqlCommand.Parameters.AddRange(ipars); + } + CheckConnection(); + return sqlCommand; + } + + private static int GetSortId(string sql, SugarParameter it) + { + return new List() { + 0, + sql.IndexOf(it.ParameterName+")"), + sql.IndexOf(it.ParameterName+" "), + sql.IndexOf(it.ParameterName+"="), + sql.IndexOf(it.ParameterName+"+"), + sql.IndexOf(it.ParameterName+"-"), + sql.IndexOf(it.ParameterName+";"), + sql.IndexOf(it.ParameterName+","), + sql.IndexOf(it.ParameterName+"*"), + sql.IndexOf(it.ParameterName+"/"), + sql.IndexOf(it.ParameterName+"|"), + sql.IndexOf(it.ParameterName+"&"), + sql.EndsWith(it.ParameterName)?sql.IndexOf(it.ParameterName):0 + }.Max(); + } + + public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command) + { + ((TDSQLForPGODBCAdapter)dataAdapter).SelectCommand = (OdbcCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return new OdbcParameter[] { }; + OdbcParameter[] result = new OdbcParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new OdbcParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + //sqlParameter.UdtTypeName = parameter.UdtTypeName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + ++index; + } + return result; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public OdbcParameter[] GetSqlParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + OdbcParameter[] result = new OdbcParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new OdbcParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + //sqlParameter.UdtTypeName = parameter.UdtTypeName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = GetDbType(parameter); + var isTime = parameter.DbType == System.Data.DbType.Time; + if (isTime) + { + sqlParameter.Value = DateTime.Parse(parameter.Value?.ToString()).TimeOfDay; + } + if (sqlParameter.Value != null && sqlParameter.Value != DBNull.Value && sqlParameter.DbType == System.Data.DbType.DateTime) + { + var date = Convert.ToDateTime(sqlParameter.Value); + if (date == DateTime.MinValue) + { + sqlParameter.Value = UtilMethods.GetMinDate(this.Context.CurrentConnectionConfig); + } + } + if (parameter.Direction == 0) + { + parameter.Direction = ParameterDirection.Input; + } + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue)) + { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + + ++index; + } + return result; + } + + private static System.Data.DbType GetDbType(SugarParameter parameter) + { + if (parameter.DbType == System.Data.DbType.UInt16) + { + return System.Data.DbType.Int16; + } + else if (parameter.DbType == System.Data.DbType.UInt32) + { + return System.Data.DbType.Int32; + } + else if (parameter.DbType == System.Data.DbType.UInt64) + { + return System.Data.DbType.Int64; + } + else + { + return parameter.DbType; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ErrorMessage.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ErrorMessage.cs new file mode 100644 index 000000000..83fd65fd6 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ErrorMessage.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar.TDSQLForPGODBC +{ + internal static partial class ErrorMessage + { + internal static LanguageType SugarLanguageType { get; set; } = LanguageType.Default; + internal static string ObjNotExist + { + get + { + return GetThrowMessage("{0} does not exist.", + "{0}不存在。"); + } + } + internal static string EntityMappingError + { + get + { + return GetThrowMessage("Entity mapping error.{0}", + "实体与表映射出错。{0}"); + } + } + + public static string NotSupportedDictionary + { + get + { + return GetThrowMessage("This type of Dictionary is not supported for the time being. You can try Dictionary, or contact the author!!", + "暂时不支持该类型的Dictionary 你可以试试 Dictionary或者联系作者!!"); + } + } + + public static string NotSupportedArray + { + get + { + return GetThrowMessage("This type of Array is not supported for the time being. You can try object[] or contact the author!!", + "暂时不支持该类型的Array 你可以试试 object[] 或者联系作者!!"); + } + } + + internal static string GetThrowMessage(string enMessage, string cnMessage, params string[] args) + { + if (SugarLanguageType == LanguageType.Default) + { + List formatArgs = new List() { enMessage, cnMessage }; + formatArgs.AddRange(args); + return string.Format(@"中文提示 : {1} +English Message : {0}", formatArgs.ToArray()); + } + else if (SugarLanguageType == LanguageType.English) + { + return enMessage; + } + else + { + return cnMessage; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ExpressionConst.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ExpressionConst.cs new file mode 100644 index 000000000..706d88ec6 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ExpressionConst.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + internal class ExpressionConst + { + public const string Const = "Const"; + public const string FormatSymbol = "{0}"; + public const string RightParenthesis = ")"; + public const string LeftParenthesis = "("; + public const string MethodConst = "MethodConst"; + public const string SqlFuncFullName = "SqlSugar.SqlFunc"; + public const string BinaryFormatString = " ( {0} {1} {2} ) "; + public const string ExpressionReplace = "46450BDC-77B7-4025-B2A6-3F048CA85AD0"; + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/FileHelper.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/FileHelper.cs new file mode 100644 index 000000000..182467ccd --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/FileHelper.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace SqlSugar.TDSQLForPGODBC +{ + internal class FileHelper + { + public static void CreateFile(string filePath, string text, Encoding encoding) + { + try + { + if (IsExistFile(filePath)) + { + DeleteFile(filePath); + } + if (!IsExistFile(filePath)) + { + string directoryPath = GetDirectoryFromFilePath(filePath); + CreateDirectory(directoryPath); + + //Create File + FileInfo file = new FileInfo(filePath); + using (FileStream stream = file.Create()) + { + using (StreamWriter writer = new StreamWriter(stream, encoding)) + { + writer.Write(text); + writer.Flush(); + } + } + } + } + catch(Exception ex) + { + throw ex; + } + } + public static bool IsExistDirectory(string directoryPath) + { + return Directory.Exists(directoryPath); + } + public static void CreateDirectory(string directoryPath) + { + if (!IsExistDirectory(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + } + public static void DeleteFile(string filePath) + { + if (IsExistFile(filePath)) + { + File.Delete(filePath); + } + } + public static string GetDirectoryFromFilePath(string filePath) + { + FileInfo file = new FileInfo(filePath); + DirectoryInfo directory = file.Directory; + return directory.FullName; + } + public static bool IsExistFile(string filePath) + { + return File.Exists(filePath); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs new file mode 100644 index 000000000..86ce50d2f --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Text; +namespace SqlSugar.TDSQLForPGODBC +{ + internal static class UtilConstants + { + public const string Dot = "."; + public const char DotChar = '.'; + internal const string Space = " "; + internal const char SpaceChar = ' '; + internal const string AssemblyName = "SqlSugar"; + internal static string ReplaceKey = "{" + Guid.NewGuid() + "}"; + internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + + internal static Type UShortType = typeof(ushort); + internal static Type ULongType = typeof(ulong); + internal static Type UIntType = typeof(uint); + internal static Type IntType = typeof(int); + internal static Type LongType = typeof(long); + internal static Type GuidType = typeof(Guid); + internal static Type BoolType = typeof(bool); + internal static Type BoolTypeNull = typeof(bool?); + internal static Type ByteType = typeof(Byte); + internal static Type SByteType = typeof(sbyte); + internal static Type ObjType = typeof(object); + internal static Type DobType = typeof(double); + internal static Type FloatType = typeof(float); + internal static Type ShortType = typeof(short); + internal static Type DecType = typeof(decimal); + internal static Type StringType = typeof(string); + internal static Type DateType = typeof(DateTime); + internal static Type DateTimeOffsetType = typeof(DateTimeOffset); + internal static Type TimeSpanType = typeof(TimeSpan); + internal static Type ByteArrayType = typeof(byte[]); + internal static Type ModelType = typeof(ModelContext); + internal static Type DynamicType = typeof(ExpandoObject); + internal static Type Dicii = typeof(KeyValuePair); + internal static Type DicIS = typeof(KeyValuePair); + internal static Type DicSi = typeof(KeyValuePair); + internal static Type DicSS = typeof(KeyValuePair); + internal static Type DicOO = typeof(KeyValuePair); + internal static Type DicSo = typeof(KeyValuePair); + internal static Type DicArraySS = typeof(Dictionary); + internal static Type DicArraySO = typeof(Dictionary); + + public static Type SqlConvertType = typeof(SqlSugar.DbConvert.NoParameterCommonPropertyConvert); + + public static Type SugarType = typeof(SqlSugarProvider); + + + internal static Type[] NumericalTypes = new Type[] + { + typeof(int), + typeof(uint), + typeof(byte), + typeof(sbyte), + typeof(long), + typeof(ulong), + typeof(short), + typeof(ushort), + }; + + + internal static string[] DateTypeStringList = new string[] + { + "Year", + "Month", + "Day", + "Hour", + "Second" , + "Minute", + "Millisecond", + "Date" + }; + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilExtensions.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilExtensions.cs new file mode 100644 index 000000000..88a5fb203 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar.TDSQLForPGODBC +{ + /// + ///Common Extensions for external users + /// + public static class UtilExtensions + { + public static string ToLower(this string value, bool isLower) + { + if (isLower) + { + return value.ObjToString().ToLower(); + } + return value.ObjToString(); + } + public static string ToUpper(this string value, bool isAutoToUpper) + { + if (value == null) return null; + if (isAutoToUpper == false) return value; + return value.ToUpper(); + } + + public static string GetN(this SqlSugarProvider Context) + { + var N = "N"; + if (Context.CurrentConnectionConfig.MoreSettings != null && Context.CurrentConnectionConfig.MoreSettings.DisableNvarchar) + { + N = ""; + } + return N; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs new file mode 100644 index 000000000..0cd31b003 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs @@ -0,0 +1,1751 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlSugar.TDSQLForPGODBC +{ + public class UtilMethods + { + + public static List CopySugarParameters(List pars) + { + if (pars == null) return null; + var newParameters = pars.Select(it => new SugarParameter(it.ParameterName, it.Value) + { + TypeName = it.TypeName, + Value = it.Value, + IsRefCursor = it.IsRefCursor, + IsArray = it.IsArray, + IsJson = it.IsJson, + ParameterName = it.ParameterName, + IsNvarchar2 = it.IsNvarchar2, + IsNClob = it.IsClob, + IsClob = it.IsClob, + UdtTypeName = it.UdtTypeName, + CustomDbType = it.CustomDbType, + DbType = it.DbType, + Direction = it.Direction, + Precision = it.Precision, + Size = it.Size, + Scale = it.Scale, + IsNullable = it.IsNullable, + SourceColumn = it.SourceColumn, + SourceColumnNullMapping = it.SourceColumnNullMapping, + SourceVersion = it.SourceVersion, + TempDate = it.TempDate, + _Size = it._Size + }); + return newParameters.ToList(); + } + public static bool IsTuple(Type tType, List classProperties) + { + if (classProperties?.Any() != true) + { + return false; + } + return tType.FullName?.StartsWith("System.Tuple`") == true && classProperties.FirstOrDefault()?.Name == "Item1"; + } + + internal static string GetTableByDbLink(SqlSugarProvider context, string tableName, string oldTableName, TenantAttribute attr) + { + QueryBuilder queryBuilder = InstanceFactory.GetQueryBuilderWithContext(context); + var dbLinkName = context.Root.GetConnection(attr.configId).CurrentConnectionConfig.DbLinkName; + if (dbLinkName != null) + { + if (dbLinkName.First() == '@') + { + tableName = queryBuilder.Builder.GetTranslationColumnName(oldTableName) + dbLinkName; + } + else if (dbLinkName.Last() == '_') + { + tableName = dbLinkName + oldTableName; + } + else + { + tableName = dbLinkName + "." + queryBuilder.Builder.GetTranslationColumnName(oldTableName); + } + } + return tableName; + } + public static List> GetColumnInfo(IDataReader reader) + { + var columnInfo = new List>(); + + // 获取列的数量 + int columnCount = reader.FieldCount; + + // 遍历每一列 + for (int i = 0; i < columnCount; i++) + { + // 获取列名 + string columnName = reader.GetName(i); + + // 获取列的数据类型 + Type columnType = reader.GetFieldType(i); + + // 将列名和类型添加到列表中 + columnInfo.Add(Tuple.Create(columnName, columnType)); + } + + return columnInfo; + } + public static object ConvertToObjectList(Type targetType, List sourceList) + { + // 创建 List 类型的实例 + object resultList = Activator.CreateInstance(typeof(List<>).MakeGenericType(targetType)); + // 获取 Add 方法 + var addMethod = resultList.GetType().GetMethod("Add"); + foreach (var obj in sourceList) + { + addMethod.Invoke(resultList, new object[] { obj }); + } + return resultList; + } + public static Dictionary DataRowToDictionary(DataRow row) + { + Dictionary dictionary = new Dictionary(); + + // 遍历所有列并将其添加到字典中 + foreach (DataColumn column in row.Table.Columns) + { + if (column.ColumnName != "Items" && column.DataType.Name.IsCollectionsList() == false) + { + dictionary.Add(column.ColumnName, row[column]); + } + } + + return dictionary; + } + public static IEnumerable BuildTree(ISqlSugarClient db, IEnumerable list, string idName, string pIdName, string childName, object rootValue) + { + var entityInfo = db.EntityMaintenance.GetEntityInfo(); ; + var mainIdProp = entityInfo.Type.GetProperty(idName); + var pIdProp = entityInfo.Type.GetProperty(pIdName); + var childProp = entityInfo.Type.GetProperty(childName); + + Dictionary kvList; + IEnumerable> group; + BuildTreeGroup(list, mainIdProp, pIdProp, out kvList, out group); + + var root = rootValue != null ? group.FirstOrDefault(x => x.Key == rootValue.ObjToString()) : group.FirstOrDefault(x => x.Key == null || x.Key == "" || x.Key == "0" || x.Key == Guid.Empty.ToString()); + + if (root != null) + { + foreach (var item in group) + { + if (kvList.TryGetValue(item.Key, out var parent)) + { + childProp.SetValue(parent, item.ToList()); + } + } + } + + return root; + } + + private static void BuildTreeGroup(IEnumerable list, PropertyInfo mainIdProp, PropertyInfo pIdProp, out Dictionary kvList, out IEnumerable> group) + { + kvList = list.ToDictionary(x => mainIdProp.GetValue(x).ObjToString()); + group = list.GroupBy(x => pIdProp.GetValue(x).ObjToString()); + } + + internal static bool? _IsErrorDecimalString { get; set; } + internal static bool? IsErrorDecimalString() + { + if (_IsErrorDecimalString == null) + { + decimal dec = Convert.ToDecimal(1.1); + _IsErrorDecimalString = dec.ToString().Contains(","); + } + return _IsErrorDecimalString; + } + internal static bool IsParameterConverter(EntityColumnInfo columnInfo) + { + return columnInfo != null && columnInfo.SqlParameterDbType != null && columnInfo.SqlParameterDbType is Type + && typeof(ISugarDataConverter).IsAssignableFrom(columnInfo.SqlParameterDbType as Type); + } + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, Expression oppoSiteExpression, EntityColumnInfo columnInfo) + { + var entity = db.EntityMaintenance.GetEntityInfo(oppoSiteExpression.Type); + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; + } + internal static SugarParameter GetParameterConverter(int index, ISqlSugarClient db, object value, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("ParameterConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; + return p; + } + internal static bool IsErrorParameterName(ConnectionConfig connectionConfig, DbColumnInfo columnInfo) + { + return connectionConfig.MoreSettings?.IsCorrectErrorSqlParameterName == true && + columnInfo.DbColumnName.IsContainsIn("-", " ", ".", "(", ")", "(", ")"); + } + + public static bool StringCheckFirstAndLast(string withString, string first, string last) + { + return withString.StartsWith(first) && withString.EndsWith(last); + } + public static bool HasInterface(Type targetType, Type interfaceType) + { + if (targetType == null || interfaceType == null || !interfaceType.IsInterface) + { + return false; + } + + return interfaceType.IsAssignableFrom(targetType); + } + public static void ClearPublicProperties(T obj, EntityInfo entity) + { + if (obj == null) + { + throw new ArgumentNullException(nameof(obj)); + } + + Type type = typeof(T); + + foreach (var column in entity.Columns) + { + if (column.PropertyInfo.CanWrite && column.PropertyInfo.GetSetMethod() != null) + { + Type propertyType = column.PropertyInfo.PropertyType; + object defaultValue = propertyType.IsValueType ? Activator.CreateInstance(propertyType) : null; + column.PropertyInfo.SetValue(obj, defaultValue); + } + } + } + + internal static Expression GetIncludeExpression(string navMemberName, EntityInfo entityInfo, out Type properyItemType, out bool isList) + { + var navInfo = entityInfo.Columns.Where(it => it.Navigat != null && it.PropertyName.EqualCase(navMemberName)).FirstOrDefault(); + var properyType = navInfo.PropertyInfo.PropertyType; + properyItemType = properyType; + if (properyType.FullName.IsCollectionsList()) + { + properyItemType = properyType.GetGenericArguments()[0]; + isList = true; + } + else + { + isList = false; + } + return ExpressionBuilderHelper.CreateExpressionSelectField(entityInfo.Type, navInfo.PropertyName, properyType); + } + public static string RemoveEqualOne(string value) + { + value = value.TrimEnd(' ').TrimEnd('1').TrimEnd('='); + return value; + } + + public static int CountSubstringOccurrences(string mainString, string searchString) + { + string[] substrings = mainString.Split(new string[] { searchString }, StringSplitOptions.None); + return substrings.Length - 1; + } + public static string RemoveBeforeFirstWhere(string query) + { + int whereIndex = query.IndexOf("WHERE", StringComparison.OrdinalIgnoreCase); + if (whereIndex >= 0) + { + return query.Substring(whereIndex + "WHERE".Length); + } + else + { + return query; + } + } + public static List ConvertToListOfObjects(object inValues) + { + // 创建一个新的List并逐个将元素转换并添加到其中 + List resultList = new List(); + foreach (var item in (IEnumerable)inValues) + { + resultList.Add(item); + } + + return resultList; + } + public static bool IsValueTypeArray(object memberValue) + { + return memberValue is List || + memberValue is string[] || + memberValue is List || + memberValue is int[] || + memberValue is List || + memberValue is Guid[] || + memberValue is List || + memberValue is long[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[] || + memberValue is List || + memberValue is float[] || + memberValue is List || + memberValue is double[] || + memberValue is List || + memberValue is decimal[] || + memberValue is List || + memberValue is DateTime[] || + memberValue is List || + memberValue is TimeSpan[] || + memberValue is List || + memberValue is bool[] || + memberValue is List || + memberValue is byte[] || + memberValue is List || + memberValue is char[] || + memberValue is List || + memberValue is short[] || + memberValue is List || + memberValue is ushort[] || + memberValue is List || + memberValue is uint[] || + memberValue is List || + memberValue is ulong[] || + memberValue is List || + memberValue is sbyte[] || + memberValue is List || + memberValue is object[] || + memberValue is List || + memberValue is int?[] || + memberValue is List || + memberValue is Guid?[] || + memberValue is List || + memberValue is long?[]; + } + internal static void EndCustomSplitTable(ISqlSugarClient context, Type entityType) + { + if (context == null || entityType == null) + { + return; + } + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) + { + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = null; + } + } + + internal static void StartCustomSplitTable(ISqlSugarClient context, Type entityType) + { + if (context == null || entityType == null) + { + return; + } + var splitTableAttribute = entityType.GetCustomAttribute(); + if (splitTableAttribute == null) + { + return; + } + if (splitTableAttribute.CustomSplitTableService != null) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = (ISplitTableService)Activator.CreateInstance(splitTableAttribute.CustomSplitTableService); + } + if ( + context?.CurrentConnectionConfig?.ConfigureExternalServices?.SplitTableService != null + && splitTableAttribute.CustomSplitTableService == null + && context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.EndsWith("_{year}{month}{day}") == true + && !context.EntityMaintenance.GetEntityInfo(entityType).DbTableName?.Replace("_{year}{month}{day}", "")?.Contains("{") == true + ) + { + context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService + = null; + } + } + public static void ConvertParameter(SugarParameter p, ISqlBuilder builder) + { + if (!p.ParameterName.StartsWith(builder.SqlParameterKeyWord)) + { + p.ParameterName = (builder.SqlParameterKeyWord + p.ParameterName.TrimStart('@')); + } + } + public static object SetAnonymousObjectPropertyValue(object obj, string propertyName, object propertyValue) + { + if (obj.GetType().IsAnonymousType()) // 判断是否为匿名对象 + { + var objType = obj.GetType(); + var objFields = objType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); + foreach (var field in objFields) // 遍历字段列表,查找需要修改的属性 + { + if (field.Name == $"<{propertyName}>i__Field") + { + field.SetValue(obj, propertyValue); // 使用反射修改属性值 + break; + } + } + } + else + { + obj.GetType().GetProperty(propertyName).SetValue(obj, propertyValue); + } + return obj; + } + + internal static bool IsNumberArray(Type type) + { + + return type.IsIn(typeof(int[]), + typeof(long[]), + typeof(short[]), + typeof(uint[]), + typeof(ulong[]), + typeof(ushort[]), + typeof(int?[]), + typeof(long?[]), + typeof(short?[]), + typeof(uint?[]), + typeof(ulong?[]), + typeof(ushort?[]), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List), + typeof(List)); + } + public static string GetNativeSql(string sql, SugarParameter[] pars) + { + if (pars == null || pars.Length == 0) + return "\r\n[Sql]:" + sql + "\r\n"; + return $"\r\n[Sql]:{sql} \r\n[Pars]:{string.Join(" ", pars.Select(it => $"\r\n[Name]:{it.ParameterName} [Value]:{it.Value} [Type]:{it.DbType} {(it.IsNvarchar2 ? "nvarchar2" : "")} "))} \r\n"; + } + public static string ToUnderLine(string str, bool isToUpper = false) + { + if (str == null || str.Contains("_")) + { + return str; + } + else if (isToUpper) + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToUpper(); + } + else + { + return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); + } + } + internal static bool IsArrayMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsArray && z.PropertyName == member.Member.Name); + return json != null; + } + internal static bool IsJsonMember(Expression expression, SqlSugarProvider context) + { + if (expression == null) + return false; + if (!(expression is LambdaExpression)) + return false; + var lambda = (LambdaExpression)expression; + if (!(lambda.Body is MemberExpression)) + return false; + var member = lambda.Body as MemberExpression; + if (!(member.Type.IsClass())) + return false; + if (member.Expression == null) + return false; + var entity = context.EntityMaintenance.GetEntityInfo(member.Expression.Type); + var json = entity.Columns.FirstOrDefault(z => z.IsJson && z.PropertyName == member.Member.Name); + return json != null; + } + public static string GetSeparatorChar() + { + return Path.Combine("a", "a").Replace("a", ""); + } + public static bool IsParentheses(object name) + { + return name.ObjToString().Trim().Last() == ')' && name.ObjToString().Trim().First() == '('; + } + + internal static bool IsDefaultValue(object value) + { + if (value == null) return true; + return value.Equals(UtilMethods.GetDefaultValue(value.GetType())); + } + + internal static DateTime ConvertFromDateTimeOffset(DateTimeOffset dateTime) + { + if (dateTime.Offset.Equals(TimeSpan.Zero)) + return dateTime.UtcDateTime; + else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) + return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local); + else + return dateTime.DateTime; + } + + internal static object To(object value, Type destinationType) + { + return To(value, destinationType, CultureInfo.InvariantCulture); + } + + internal static object To(object value, Type destinationType, CultureInfo culture) + { + if (value != null) + { + destinationType = UtilMethods.GetUnderType(destinationType); + var sourceType = value.GetType(); + if (destinationType.Name == "DateOnly" && sourceType == typeof(string)) + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { Convert.ToDateTime(value) }); + } + else if (destinationType.FullName == "System.Ulid") + { + var method = destinationType.GetMyMethod("Parse", 1); + if (method != null) + { + var result = method.Invoke(null, new object[] { value }); + return result; + } + } + var destinationConverter = TypeDescriptor.GetConverter(destinationType); + if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) + return destinationConverter.ConvertFrom(null, culture, value); + + var sourceConverter = TypeDescriptor.GetConverter(sourceType); + if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) + return sourceConverter.ConvertTo(null, culture, value, destinationType); + + if (destinationType.IsEnum && value is int) + return Enum.ToObject(destinationType, (int)value); + + if (destinationType.Name == "TimeOnly" && sourceType.Name != "TimeOnly") + { + var type = Type.GetType("System.TimeOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromTimeSpan"); + return method.Invoke(null, new object[] { value }); + } + if (destinationType.Name == "DateOnly" && sourceType.Name != "DateOnly") + { + var type = Type.GetType("System.DateOnly", true, true); + var method = type.GetMethods().FirstOrDefault(it => it.GetParameters().Length == 1 && it.Name == "FromDateTime"); + return method.Invoke(null, new object[] { value }); + } + + if (!destinationType.IsInstanceOfType(value)) + return Convert.ChangeType(value, destinationType, culture); + } + return value; + } + public static bool IsAnyAsyncMethod(StackFrame[] methods) + { + bool isAsync = false; + foreach (var item in methods) + { + if (UtilMethods.IsAsyncMethod(item.GetMethod())) + { + isAsync = true; + break; + } + } + return isAsync; + } + + + public static ConnectionConfig CopyConfig(ConnectionConfig it) + { + return new ConnectionConfig() + { + AopEvents = it.AopEvents == null ? null : new AopEvents() + { + DataExecuting = it.AopEvents?.DataExecuting, + OnDiffLogEvent = it.AopEvents?.OnDiffLogEvent, + OnError = it.AopEvents?.OnError, + OnExecutingChangeSql = it.AopEvents?.OnExecutingChangeSql, + OnLogExecuted = it.AopEvents?.OnLogExecuted, + OnLogExecuting = it.AopEvents?.OnLogExecuting, + DataExecuted = it.AopEvents?.DataExecuted, + }, + ConfigId = it.ConfigId, + ConfigureExternalServices = it.ConfigureExternalServices == null ? null : new ConfigureExternalServices() + { + AppendDataReaderTypeMappings = it.ConfigureExternalServices.AppendDataReaderTypeMappings, + DataInfoCacheService = it.ConfigureExternalServices.DataInfoCacheService, + EntityNameService = it.ConfigureExternalServices.EntityNameService, + EntityService = it.ConfigureExternalServices.EntityService, + RazorService = it.ConfigureExternalServices.RazorService, + ReflectionInoCacheService = it.ConfigureExternalServices.ReflectionInoCacheService, + SerializeService = it.ConfigureExternalServices.SerializeService, + SplitTableService = it.ConfigureExternalServices.SplitTableService, + SqlFuncServices = it.ConfigureExternalServices.SqlFuncServices + }, + ConnectionString = it.ConnectionString, + DbType = it.DbType, + DbLinkName = it.DbLinkName, + IndexSuffix = it.IndexSuffix, + InitKeyType = it.InitKeyType, + IsAutoCloseConnection = it.IsAutoCloseConnection, + LanguageType = it.LanguageType, + MoreSettings = it.MoreSettings == null ? null : new ConnMoreSettings() + { + DefaultCacheDurationInSeconds = it.MoreSettings.DefaultCacheDurationInSeconds, + DisableNvarchar = it.MoreSettings.DisableNvarchar, + PgSqlIsAutoToLower = it.MoreSettings.PgSqlIsAutoToLower, + PgSqlIsAutoToLowerCodeFirst = it.MoreSettings.PgSqlIsAutoToLowerCodeFirst, + IsAutoRemoveDataCache = it.MoreSettings.IsAutoRemoveDataCache, + IsWithNoLockQuery = it.MoreSettings.IsWithNoLockQuery, + DisableWithNoLockWithTran = it.MoreSettings.DisableWithNoLockWithTran, + TableEnumIsString = it.MoreSettings.TableEnumIsString, + DisableMillisecond = it.MoreSettings.DisableMillisecond, + DbMinDate = it.MoreSettings.DbMinDate, + IsNoReadXmlDescription = it.MoreSettings.IsNoReadXmlDescription, + SqlServerCodeFirstNvarchar = it.MoreSettings.SqlServerCodeFirstNvarchar, + OracleCodeFirstNvarchar2 = it.MoreSettings.OracleCodeFirstNvarchar2, + IsAutoToUpper = it.MoreSettings.IsAutoToUpper, + IsAutoDeleteQueryFilter = it.MoreSettings.IsAutoDeleteQueryFilter, + IsAutoUpdateQueryFilter = it.MoreSettings.IsAutoUpdateQueryFilter, + EnableModelFuncMappingColumn = it.MoreSettings.EnableModelFuncMappingColumn, + EnableOracleIdentity = it.MoreSettings.EnableOracleIdentity, + IsWithNoLockSubquery = it.MoreSettings.IsWithNoLockSubquery, + EnableCodeFirstUpdatePrecision = it.MoreSettings.EnableCodeFirstUpdatePrecision, + SqliteCodeFirstEnableDefaultValue = it.MoreSettings.SqliteCodeFirstEnableDefaultValue, + SqliteCodeFirstEnableDescription = it.MoreSettings.SqliteCodeFirstEnableDescription, + IsCorrectErrorSqlParameterName = it.MoreSettings.IsCorrectErrorSqlParameterName, + SqliteCodeFirstEnableDropColumn = it.MoreSettings.SqliteCodeFirstEnableDropColumn, + MaxParameterNameLength = it.MoreSettings.MaxParameterNameLength, + DisableQueryWhereColumnRemoveTrim = it.MoreSettings.DisableQueryWhereColumnRemoveTrim, + DatabaseModel = it.MoreSettings.DatabaseModel, + EnableILike = it.MoreSettings.EnableILike, + ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal + + }, + SqlMiddle = it.SqlMiddle == null ? null : new SqlMiddle + { + IsSqlMiddle = it.SqlMiddle.IsSqlMiddle, + ExecuteCommand = it.SqlMiddle.ExecuteCommand, + ExecuteCommandAsync = it.SqlMiddle.ExecuteCommandAsync, + GetDataReader = it.SqlMiddle.GetDataReader, + GetDataReaderAsync = it.SqlMiddle.GetDataReaderAsync, + GetDataSetAll = it.SqlMiddle.GetDataSetAll, + GetDataSetAllAsync = it.SqlMiddle.GetDataSetAllAsync, + GetScalar = it.SqlMiddle.GetScalar, + GetScalarAsync = it.SqlMiddle.GetScalarAsync + }, + SlaveConnectionConfigs = it.SlaveConnectionConfigs + }; + } + + internal static object GetRandomByType(Type underType) + { + if (underType == UtilConstants.GuidType) + { + return Guid.NewGuid(); + } + else if (underType == UtilConstants.LongType) + { + return SnowFlakeSingle.Instance.NextId(); + } + else if (underType == UtilConstants.StringType) + { + return Guid.NewGuid() + ""; + } + else if (underType == UtilConstants.DateType) + { + return System.DateTime.Now; + } + else + { + return Guid.NewGuid() + ""; + } + } + + public static bool IsAsyncMethod(MethodBase method) + { + if (method == null) + { + return false; + } + if (method.DeclaringType != null) + { + if (method.DeclaringType.GetInterfaces().Contains(typeof(IAsyncStateMachine))) + { + return true; + } + } + var name = method.Name; + if (name.Contains("OutputAsyncCausalityEvents")) + { + return true; + } + if (name.Contains("OutputWaitEtwEvents")) + { + return true; + } + if (name.Contains("ExecuteAsync")) + { + return true; + } + //if (method?.DeclaringType?.FullName?.Contains("Furion.InternalApp")==true) + //{ + // return false; + //} + Type attType = typeof(AsyncStateMachineAttribute); + var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType); + return (attrib != null); + } + + public static StackTraceInfo GetStackTrace() + { + + StackTrace st = new StackTrace(true); + StackTraceInfo info = new StackTraceInfo(); + info.MyStackTraceList = new List(); + info.SugarStackTraceList = new List(); + for (int i = 0; i < st.FrameCount; i++) + { + var frame = st.GetFrame(i); + if (frame.GetMethod().Module.Name.ToLower() != "sqlsugar.dll" && frame.GetMethod().Name.First() != '<') + { + info.MyStackTraceList.Add(new StackTraceInfoItem() + { + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); + } + else + { + info.SugarStackTraceList.Add(new StackTraceInfoItem() + { + FileName = frame.GetFileName(), + MethodName = frame.GetMethod().Name, + Line = frame.GetFileLineNumber() + }); + } + } + return info; + } + + internal static object GetConvertValue(object entityValue) + { + if (entityValue != null && entityValue is DateTime) + { + entityValue = entityValue.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff"); + } + return entityValue; + } + + internal static T To(object value) + { + return (T)To(value, typeof(T)); + } + + internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig) + { + if (currentConnectionConfig.MoreSettings == null) + { + return Convert.ToDateTime("1900-01-01"); + } + else if (currentConnectionConfig.MoreSettings.DbMinDate == null) + { + return Convert.ToDateTime("1900-01-01"); + } + else + { + return currentConnectionConfig.MoreSettings.DbMinDate.Value; + } + } + + public static Type GetUnderType(Type oldType) + { + Type type = Nullable.GetUnderlyingType(oldType); + return type == null ? oldType : type; + } + public static object GetDefaultValue(Type type) + { + return type.IsValueType ? Activator.CreateInstance(type) : null; + } + public static string ReplaceFirstMatch(string input, string pattern, string replacement) + { + Regex regex = new Regex(pattern); + return regex.Replace(input, replacement, 1); + } + public static string ReplaceSqlParameter(string itemSql, SugarParameter itemParameter, string newName) + { + itemSql = Regex.Replace(itemSql, string.Format(@"{0} ", "\\" + itemParameter.ParameterName), newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\)", "\\" + itemParameter.ParameterName), newName + ")", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\,", "\\" + itemParameter.ParameterName), newName + ",", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}$", "\\" + itemParameter.ParameterName), newName, RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0}\+", "\\" + itemParameter.ParameterName), "+" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\+{0} ", "\\" + itemParameter.ParameterName), "+" + newName + " ", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@" {0}\+", "\\" + itemParameter.ParameterName), " " + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\|\|{0}\|\|", "\\" + itemParameter.ParameterName), "||" + newName + "||", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"\={0}\+", "\\" + itemParameter.ParameterName), "=" + newName + "+", RegexOptions.IgnoreCase); + itemSql = Regex.Replace(itemSql, string.Format(@"{0}\|\|", "\\" + itemParameter.ParameterName), newName + "||", RegexOptions.IgnoreCase); + return itemSql; + } + internal static Type GetRootBaseType(Type entityType) + { + var baseType = entityType.BaseType; + while (baseType != null && baseType.BaseType != UtilConstants.ObjType) + { + baseType = baseType.BaseType; + } + return baseType; + } + + + internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + isNullable = unType != null; + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static Type GetUnderType(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + unType = unType ?? propertyInfo.PropertyType; + return unType; + } + + internal static bool IsNullable(PropertyInfo propertyInfo) + { + Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType); + return unType != null; + } + + internal static bool IsNullable(Type type) + { + Type unType = Nullable.GetUnderlyingType(type); + return unType != null; + } + internal static T IsNullReturnNew(T returnObj) where T : new() + { + if (returnObj.IsNullOrEmpty()) + { + returnObj = new T(); + } + return returnObj; + } + public static object ChangeType2(object value, Type type) + { + if (value is byte[] && type == UtilConstants.StringType) + { + return Encoding.UTF8.GetString(value as byte[]); + } + if (value == null && type.IsGenericType) return Activator.CreateInstance(type); + if (value == null) return null; + if (type == value.GetType()) return value; + if (type.IsEnum) + { + if (value is string) + return Enum.Parse(type, value as string); + else + return Enum.ToObject(type, value); + } + if (value is string && type == typeof(Guid?)) return value.IsNullOrEmpty() ? null : (Guid?)new Guid(value as string); + if (!type.IsInterface && type.IsGenericType) + { + Type innerType = type.GetGenericArguments()[0]; + object innerValue = ChangeType(value, innerType); + return Activator.CreateInstance(type, new object[] { innerValue }); + } + if (value is string && type == typeof(Guid)) return new Guid(value as string); + if (value is string && type == typeof(Version)) return new Version(value as string); + if (!(value is IConvertible)) return value; + if (value is DateTime && type.FullName == "System.DateOnly") + { + value = UtilMethods.DateTimeToDateOnly(value); + } + return Convert.ChangeType(value, type); + } + + internal static T ChangeType(T obj, Type type) + { + return (T)Convert.ChangeType(obj, type); + } + + internal static T ChangeType(T obj) + { + return (T)Convert.ChangeType(obj, typeof(T)); + } + + internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date) + { + date = DateTime.SpecifyKind(date, DateTimeKind.Utc); + DateTimeOffset utcTime2 = date; + return utcTime2; + } + + internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + internal static void RepairReplicationParameters(ISqlSugarClient db, ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null) + { + if (appendSql.HasValue() && parameters.HasValue()) + { + foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length)) + { + //Compatible with.NET CORE parameters case + var name = parameter.ParameterName; + string newName = name + append + addIndex; + var maxLength = db.CurrentConnectionConfig.MoreSettings.MaxParameterNameLength; + if (newName.Length > maxLength) + { + newName = (name.Substring(0, 1) + name.GetNonNegativeHashCodeString() + "_" + addIndex); + } + appendSql = ReplaceSqlParameter(appendSql, parameter, newName); + parameter.ParameterName = newName; + } + } + } + + internal static string GetPackTable(string sql, string shortName) + { + return string.Format(" ({0}) {1} ", sql, shortName); + } + + public static Func GetTypeConvert(object value) + { + if (value is int || value is uint || value is int? || value is uint?) + { + return x => Convert.ToInt32(x); + } + else if (value is short || value is ushort || value is short? || value is ushort?) + { + return x => Convert.ToInt16(x); + } + else if (value is long || value is long? || value is ulong? || value is long?) + { + return x => Convert.ToInt64(x); + } + else if (value is DateTime || value is DateTime?) + { + return x => Convert.ToDateTime(x); + } + else if (value is bool || value is bool?) + { + return x => Convert.ToBoolean(x); + } + return null; + } + + internal static string GetTypeName(object value) + { + if (value == null) + { + return null; + } + else + { + return value.GetType().Name; + } + } + + internal static string GetParenthesesValue(string dbTypeName) + { + if (Regex.IsMatch(dbTypeName, @"\(.+\)")) + { + if (Regex.IsMatch(dbTypeName, @"SimpleAggregateFunction")) + dbTypeName = Regex.Match(dbTypeName, @"((?<=,\s)[^Nullable]\w+)|((?<=Nullable\()\w+)").Value; + else + dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", ""); + } + dbTypeName = dbTypeName.Trim(); + return dbTypeName; + } + + internal static T GetOldValue(T value, Action action) + { + action(); + return value; + } + + internal static object DefaultForType(Type targetType) + { + return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; + } + + internal static Int64 GetLong(byte[] bytes) + { + return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0')); + } + public static object GetPropertyValue(T t, string PropertyName) + { + return t.GetType().GetProperty(PropertyName).GetValue(t, null); + } + internal static string GetMD5(string myString) + { + MD5 md5 = new MD5CryptoServiceProvider(); + byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString); + byte[] targetData = md5.ComputeHash(fromData); + string byte2String = null; + + for (int i = 0; i < targetData.Length; i++) + { + byte2String += targetData[i].ToString("x"); + } + + return byte2String; + } + + public static string EncodeBase64(string code) + { + if (StaticConfig.Encode != null) + { + return StaticConfig.Encode(code); + } + if (code.IsNullOrEmpty()) return code; + string encode = ""; + byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(code); + try + { + encode = Convert.ToBase64String(bytes); + } + catch + { + encode = code; + } + return encode; + } + public static string ConvertNumbersToString(string value) + { + string[] splitInt = value.Split(new char[] { '9' }, StringSplitOptions.RemoveEmptyEntries); + + var splitChars = splitInt.Select(s => Convert.ToChar( + Convert.ToInt32(s, 8) + ).ToString()); + + return string.Join("", splitChars); + } + public static string ConvertStringToNumbers(string value) + { + StringBuilder sb = new StringBuilder(); + + foreach (char c in value) + { + int cAscil = (int)c; + sb.Append(Convert.ToString(c, 8) + "9"); + } + + return sb.ToString(); + } + + public static string DecodeBase64(string code) + { + try + { + if (StaticConfig.Decode != null) + { + return StaticConfig.Decode(code); + } + if (code.IsNullOrEmpty()) return code; + string decode = ""; + byte[] bytes = Convert.FromBase64String(code); + try + { + decode = Encoding.GetEncoding("utf-8").GetString(bytes); + } + catch + { + decode = code; + } + return decode; + } + catch + { + return code; + } + } + + public static string GetSqlValue(object value) + { + if (value == null) + { + return "null"; + } + else if (UtilMethods.IsNumber(value.GetType().Name)) + { + return value.ObjToString(); + } + else if (value is DateTime) + { + return UtilMethods.GetConvertValue(value) + ""; + } + else + { + return value.ToSqlValue(); + } + } + + public static void DataInoveByExpresson(Type[] datas, MethodCallExpression callExpresion) + { + var methodInfo = callExpresion.Method; + foreach (var item in datas) + { + if (item != null) + { + if (callExpresion.Arguments.Count == 0) + { + methodInfo.Invoke(item, null); + } + else + { + List methodParameters = new List(); + foreach (var callItem in callExpresion.Arguments) + { + var parameter = callItem.GetType().GetProperties().FirstOrDefault(it => it.Name == "Value"); + if (parameter == null) + { + var value = LambdaExpression.Lambda(callItem).Compile().DynamicInvoke(); + methodParameters.Add(value); + } + else + { + var value = parameter.GetValue(callItem, null); + methodParameters.Add(value); + } + } + methodInfo.Invoke(item, methodParameters.ToArray()); + } + } + } + } + + public static Dictionary EnumToDictionary() + { + Dictionary dic = new Dictionary(); + if (!typeof(T).IsEnum) + { + return dic; + } + string desc = string.Empty; + foreach (var item in Enum.GetValues(typeof(T))) + { + var key = item.ToString().ToLower(); + if (!dic.ContainsKey(key)) + dic.Add(key, (T)item); + } + return dic; + } + + public static Type GetTypeByTypeName(string ctypename) + { + + if (ctypename.EqualCase(UtilConstants.DecType.Name)) + { + return UtilConstants.DecType; + } + else if (ctypename.EqualCase(UtilConstants.DobType.Name)) + { + return UtilConstants.DobType; + } + else if (ctypename.EqualCase(UtilConstants.DateType.Name)) + { + return UtilConstants.DateType; + } + else if (ctypename.EqualCase(UtilConstants.IntType.Name)) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase(UtilConstants.BoolType.Name)) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase(UtilConstants.LongType.Name)) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase(UtilConstants.ShortType.Name)) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + return UtilConstants.DateTimeOffsetType; + } + else if (ctypename.EqualCase(UtilConstants.GuidType.Name)) + { + return UtilConstants.GuidType; + } + else if (ctypename.EqualCase("int")) + { + return UtilConstants.IntType; + } + else if (ctypename.EqualCase("long")) + { + return UtilConstants.LongType; + } + else if (ctypename.EqualCase("short")) + { + return UtilConstants.ShortType; + } + else if (ctypename.EqualCase("byte")) + { + return UtilConstants.ByteType; + } + else if (ctypename.EqualCase("uint")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("ulong")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("ushort")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase("uint32")) + { + return UtilConstants.UIntType; + } + else if (ctypename.EqualCase("uint64")) + { + return UtilConstants.ULongType; + } + else if (ctypename.EqualCase("bool")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("ToBoolean")) + { + return UtilConstants.BoolType; + } + else if (ctypename.EqualCase("uint16")) + { + return UtilConstants.UShortType; + } + else if (ctypename.EqualCase(UtilConstants.ByteArrayType.Name)) + { + return UtilConstants.ByteArrayType; + } + else + { + return UtilConstants.StringType; + } + } + public static object ConvertDataByTypeName(string ctypename, string value) + { + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + FieldValue = value + }; + if (item.FieldValue == string.Empty && item.CSharpTypeName.HasValue() && !item.CSharpTypeName.EqualCase("string")) + { + return null; + } + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return Convert.ToDecimal(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return Convert.ToDouble(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateType.Name)) + { + return Convert.ToDateTime(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.FieldValue != null && item.CSharpTypeName.EqualCase(UtilConstants.BoolType.Name)) + { + return Convert.ToBoolean(item.FieldValue.ToLower()); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DateTimeOffsetType.Name)) + { + DateTimeOffset dt; + if (DateTimeOffset.TryParse(item.FieldValue, out dt)) + { + return dt; + } + return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue)); + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.GuidType.Name)) + { + return Guid.Parse(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return Convert.ToInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return Convert.ToInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return Convert.ToInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return Convert.ToByte(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return Convert.ToUInt32(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return Convert.ToUInt64(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("bool")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("ToBoolean")) + { + return Convert.ToBoolean(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return Convert.ToUInt16(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("byte[]") && item.FieldValue != null && item.FieldValue.Contains("|")) + { + return item.FieldValue.Split('|').Select(it => Convert.ToByte(it)).ToArray(); + } + else + { + return item.FieldValue; + } + } + + public static bool IsNumber(string ctypename) + { + if (ctypename.IsNullOrEmpty()) + { + return false; + } + var item = new ConditionalModel() + { + CSharpTypeName = ctypename, + }; + if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name)) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("int")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("long")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("short")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("byte")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ulong")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("ushort")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint32")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint64")) + { + return true; + } + else if (item.CSharpTypeName.EqualCase("uint16")) + { + return true; + } + else + { + return false; + } + } + + /// + /// Get Week Last Day Sun + /// + /// + /// + public static DateTime GetWeekLastDaySun(DateTime datetime) + { + //星期天为最后一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + weeknow = (weeknow == 0 ? 7 : weeknow); + int daydiff = (7 - weeknow); + + //本周最后一天 + string LastDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(LastDay); + } + /// + /// Get Week First Day Mon + /// + /// + /// + public static DateTime GetWeekFirstDayMon(DateTime datetime) + { + //星期一为第一天 + int weeknow = Convert.ToInt32(datetime.DayOfWeek); + + //因为是以星期一为第一天,所以要判断weeknow等于0时,要向前推6天。 + weeknow = (weeknow == 0 ? (7 - 1) : (weeknow - 1)); + int daydiff = (-1) * weeknow; + + //本周第一天 + string FirstDay = datetime.AddDays(daydiff).ToString("yyyy-MM-dd"); + return Convert.ToDateTime(FirstDay); + } + public static string GetSqlString(DbType dbType, string sql, SugarParameter[] parametres, bool DisableNvarchar = false) + { + if (parametres == null) + parametres = new SugarParameter[] { }; + return GetSqlString(new ConnectionConfig() + { + DbType = dbType, + MoreSettings = new ConnMoreSettings() + { + DisableNvarchar = DisableNvarchar + } + }, new KeyValuePair>(sql, parametres.ToList())); + } + public static string GetSqlString(ConnectionConfig connectionConfig, KeyValuePair> sqlObj) + { + var result = sqlObj.Key; + if (sqlObj.Value != null) + { + foreach (var item in sqlObj.Value.OrderByDescending(it => it.ParameterName.Length)) + { + if (item.ParameterName.StartsWith(":") && !result.Contains(item.ParameterName)) + { + item.ParameterName = "@" + item.ParameterName.TrimStart(':'); + } + if (connectionConfig.MoreSettings == null) + { + connectionConfig.MoreSettings = new ConnMoreSettings(); + } + if (item.Value != null && item.Value is DateTime && ((DateTime)item.Value == DateTime.MinValue)) + { + item.Value = connectionConfig.MoreSettings.DbMinDate; + } + if (item.Value == null || item.Value == DBNull.Value) + { + result = result.Replace(item.ParameterName, "null"); + } + else if (UtilMethods.IsNumber(item.Value.GetType().Name)) + { + result = result.Replace(item.ParameterName, item.Value.ObjToString()); + } + else if (item.Value is DateTime && connectionConfig.DbType == DbType.SqlServer) + { + result = result.Replace(item.ParameterName, "CAST('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "' AS DATETIME)"); + } + else if (item.Value is DateTime && connectionConfig.DbType.IsIn(DbType.Dm, DbType.Oracle)) + { + if (item.DbType == System.Data.DbType.Date || connectionConfig?.MoreSettings?.DisableMillisecond == true) + { + var value = "to_date('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss") + "', 'YYYY-MM-DD HH24:MI:SS') "; ; + result = result.Replace(item.ParameterName, value); + } + else + { + var value = "to_timestamp('" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.ffffff") + "', 'YYYY-MM-DD HH24:MI:SS.FF') "; + result = result.Replace(item.ParameterName, value); + } + } + else if (item.Value is DateTime) + { + result = result.Replace(item.ParameterName, "'" + item.Value.ObjToDate().ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"); + } + else if (item.IsArray) + { + result = result.Replace(item.ParameterName, "'{" + new SerializeService().SerializeObject(item.Value).TrimStart('[').TrimEnd(']') + "}'"); + } + else if (item.Value is byte[] && connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, ByteArrayToPostgreByteaLiteral(item.Value as byte[])); + } + else if (item.Value is byte[]) + { + result = result.Replace(item.ParameterName, "0x" + BitConverter.ToString((byte[])item.Value).Replace("-", "")); + } + else if (item.Value is bool) + { + if (connectionConfig.DbType == DbType.PostgreSQL) + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? "true" : "false")); + } + else + { + result = result.Replace(item.ParameterName, (Convert.ToBoolean(item.Value) ? 1 : 0) + ""); + } + } + else if (item.Value.GetType() != UtilConstants.StringType && connectionConfig.DbType == DbType.PostgreSQL && TDSQLForPGODBCDbBind.MappingTypesConst.Any(x => x.Value.ToString().EqualCase(item.Value.GetType().Name))) + { + var type = TDSQLForPGODBCDbBind.MappingTypesConst.First(x => x.Value.ToString().EqualCase(item.Value.GetType().Name)).Key; + var replaceValue = string.Format("CAST('{0}' AS {1})", item.Value, type); + result = result.Replace(item.ParameterName, replaceValue); + } + else if (connectionConfig.MoreSettings?.DisableNvarchar == true || item.DbType == System.Data.DbType.AnsiString || connectionConfig.DbType == DbType.Sqlite) + { + result = result.Replace(item.ParameterName, $"'{item.Value.ObjToString().ToSqlFilter()}'"); + } + else + { + result = result.Replace(item.ParameterName, $"N'{item.Value.ObjToString().ToSqlFilter()}'"); + } + } + } + + return result; + } + public static string ByteArrayToPostgreByteaLiteral(byte[] data) + { + var sb = new StringBuilder("E'"); + + foreach (var b in data) + { + if (b >= 32 && b < 127 && !char.IsControl((char)b)) // 可打印的ASCII字符 + { + sb.Append((char)b); + } + else // 非打印字符或控制字符 + { + sb.Append("\\\\"); + sb.Append(Convert.ToString(b, 8).PadLeft(3, '0')); + } + } + + sb.Append("'::bytea"); + return sb.ToString(); + } + public static void CheckArray(T[] insertObjs) where T : class, new() + { + + if (insertObjs != null + && insertObjs.Length == 1 + && insertObjs.FirstOrDefault() != null + && insertObjs.FirstOrDefault().GetType().FullName.Contains("System.Collections.Generic.List`")) + { + Check.ExceptionEasy("Insertable(T []) is an array and your argument is a List", "二次封装引起的进错重载,当前方法是 Insertable(T []) 参数是一个数组,而你的参数是一个List"); + } + } + + [Obsolete("请使用新名字:FieldNameSql")] + public static string FiledNameSql() + { + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + public static string FieldNameSql() + { + if (StaticConfig.TableQuerySqlKey != null && StaticConfig.TableQuerySqlKey != Guid.Empty) + { + return $"[value=sql{StaticConfig.TableQuerySqlKey}]"; + } + return $"[value=sql{UtilConstants.ReplaceKey}]"; + } + + internal static object TimeOnlyToTimeSpan(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToTimeSpan"); + return method.Invoke(value, new object[] { }); + } + + internal static object DateOnlyToDateTime(object value) + { + if (value == null) return null; + var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToShortDateString"); + return method.Invoke(value, new object[] { }); + } + internal static object DateTimeToDateOnly(object value) + { + if (value == null) return null; + + // 获取DateOnly类型 + Type dateOnlyType = Type.GetType("System.DateOnly, System.Runtime", throwOnError: false); + if (dateOnlyType == null) + { + throw new InvalidOperationException("DateOnly type not found."); + } + + // 获取DateOnly的构造函数 + var constructor = dateOnlyType.GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + if (constructor == null) + { + throw new InvalidOperationException("DateOnly constructor not found."); + } + + // 使用反射调用DateTime的属性 + var yearProperty = value.GetType().GetProperty("Year"); + var monthProperty = value.GetType().GetProperty("Month"); + var dayProperty = value.GetType().GetProperty("Day"); + + if (yearProperty == null || monthProperty == null || dayProperty == null) + { + throw new InvalidOperationException("DateTime properties not found."); + } + + int year = (int)yearProperty.GetValue(value); + int month = (int)monthProperty.GetValue(value); + int day = (int)dayProperty.GetValue(value); + + // 使用反射创建DateOnly实例 + return constructor.Invoke(new object[] { year, month, day }); + } + + + internal static void AddDiscrimator(Type type, ISugarQueryable queryable, string shortName = null) + { + var entityInfo = queryable.Context?.EntityMaintenance?.GetEntityInfoWithAttr(type); + if (entityInfo != null && entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + queryable.Where(shortName + name, "=", value); + } + } + } + internal static string GetDiscrimator(EntityInfo entityInfo, ISqlBuilder builer) + { + List wheres = new List(); + if (entityInfo != null && entityInfo.Discrimator.HasValue()) + { + Check.ExceptionEasy(!Regex.IsMatch(entityInfo.Discrimator, @"^(?:\w+:\w+)(?:,\w+:\w+)*$"), "The format should be type:cat for this type, and if there are multiple, it can be FieldName:cat,FieldName2:dog ", "格式错误应该是type:cat这种格式,如果是多个可以FieldName:cat,FieldName2:dog,不要有空格"); + var array = entityInfo.Discrimator.Split(','); + foreach (var disItem in array) + { + var name = disItem.Split(':').First(); + var value = disItem.Split(':').Last(); + wheres.Add($"{builer.GetTranslationColumnName(name)}={value.ToSqlValue()} "); + } + } + return string.Join(" AND ", wheres); + } + + internal static bool NoErrorParameter(string parameterName) + { + if (parameterName == null) + { + return false; + } + if (parameterName.Contains(" ")) + { + return false; + } + if (parameterName.Contains("(")) + { + return false; + } + if (parameterName.Contains("(")) + { + return false; + } + if (parameterName.Contains(".")) + { + return false; + } + return true; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ValidateExtensions.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ValidateExtensions.cs new file mode 100644 index 000000000..fc9364de2 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/ValidateExtensions.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +namespace SqlSugar.TDSQLForPGODBC +{ + internal static class ValidateExtensions + { + public static bool IsInRange(this int thisValue, int begin, int end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsInRange(this DateTime thisValue, DateTime begin, DateTime end) + { + return thisValue >= begin && thisValue <= end; + } + + public static bool IsIn(this T thisValue, params T[] values) + { + return values.Contains(thisValue); + } + + public static bool IsContainsIn(this string thisValue, params string[] inValues) + { + return inValues.Any(it => thisValue.Contains(it)); + } + + public static bool IsNullOrEmpty(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return true; + return thisValue.ToString() == ""; + } + + public static bool IsNullOrEmpty(this Guid? thisValue) + { + if (thisValue == null) return true; + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this Guid thisValue) + { + if (thisValue == null) return true; + return thisValue == Guid.Empty; + } + + public static bool IsNullOrEmpty(this IEnumerable thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return true; + return false; + } + + public static bool HasValue(this object thisValue) + { + if (thisValue == null || thisValue == DBNull.Value) return false; + return thisValue.ToString() != ""; + } + + public static bool HasValue(this IEnumerable thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return false; + return true; + } + + public static bool IsValuable(this IEnumerable> thisValue) + { + if (thisValue == null || thisValue.Count() == 0) return false; + return true; + } + + public static bool IsZero(this object thisValue) + { + return (thisValue == null || thisValue.ToString() == "0"); + } + + public static bool IsInt(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^\d+$"); + } + + /// + public static bool IsNoInt(this object thisValue) + { + if (thisValue == null) return true; + return !Regex.IsMatch(thisValue.ToString(), @"^\d+$"); + } + + public static bool IsMoney(this object thisValue) + { + if (thisValue == null) return false; + double outValue = 0; + return double.TryParse(thisValue.ToString(), out outValue); + } + public static bool IsGuid(this object thisValue) + { + if (thisValue == null) return false; + Guid outValue = Guid.Empty; + return Guid.TryParse(thisValue.ToString(), out outValue); + } + + public static bool IsDate(this object thisValue) + { + if (thisValue == null) return false; + DateTime outValue = DateTime.MinValue; + return DateTime.TryParse(thisValue.ToString(), out outValue); + } + + public static bool IsEamil(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"); + } + + public static bool IsMobile(this object thisValue) + { + if (thisValue == null) return false; + return Regex.IsMatch(thisValue.ToString(), @"^\d{11}$"); + } + + public static bool IsTelephone(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}$"); + + } + + public static bool IsIDcard(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$"); + } + + public static bool IsFax(this object thisValue) + { + if (thisValue == null) return false; + return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$"); + } + + public static bool IsMatch(this object thisValue, string pattern) + { + if (thisValue == null) return false; + Regex reg = new Regex(pattern); + return reg.IsMatch(thisValue.ToString()); + } + public static bool IsAnonymousType(this Type type) + { + string typeName = type.Name; + return typeName.Contains("<>") && typeName.Contains("__") && typeName.Contains("AnonymousType"); + } + public static bool IsCollectionsList(this string thisValue) + { + return (thisValue + "").StartsWith("System.Collections.Generic.List")|| (thisValue + "").StartsWith("System.Collections.Generic.IEnumerable"); + } + public static bool IsStringArray(this string thisValue) + { + return (thisValue + "").IsMatch(@"System\.[a-z,A-Z,0-9]+?\[\]"); + } + public static bool IsEnumerable(this string thisValue) + { + return (thisValue + "").StartsWith("System.Linq.Enumerable"); + } + + public static Type StringType = typeof (string); + + public static bool IsClass(this Type thisValue) + { + return thisValue != StringType && thisValue.IsEntity()&&thisValue!=UtilConstants.ByteArrayType; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Utilities/UtilConvert.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Utilities/UtilConvert.cs new file mode 100644 index 000000000..982b3dcc6 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Utilities/UtilConvert.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +namespace SqlSugar.TDSQLForPGODBC +{ + internal static class UtilConvert + { + public static int ObjToInt(this object thisValue) + { + int reval = 0; + if (thisValue == null) return 0; + if (thisValue is Enum) + { + return Convert.ToInt32(thisValue); + } + if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + + public static long ObjToLong(this object thisValue) + { + long reval = 0; + if (thisValue == null) return 0; + if (thisValue is Enum) + { + return Convert.ToInt64(thisValue); + } + if (thisValue != null && thisValue != DBNull.Value && long.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + + public static int ObjToInt(this object thisValue, int errorValue) + { + int reval = 0; + if (thisValue is Enum) + { + return (int)thisValue; + } + if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return errorValue; + } + + public static double ObjToMoney(this object thisValue) + { + double reval = 0; + if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return 0; + } + + public static double ObjToMoney(this object thisValue, double errorValue) + { + double reval = 0; + if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return errorValue; + } + public static bool EqualCase(this string thisValue,string equalValue) + { + if ( thisValue!=null && equalValue != null) + { + return thisValue.ToLower() == equalValue.ToLower(); + } + else + { + return thisValue == equalValue; + } + } + public static string ObjToString(this object thisValue,Func formatTime) + { + if (formatTime != null&&thisValue is DateTime) + { + var dt = Convert.ToDateTime(thisValue); + return formatTime(dt); + } + else + { + return thisValue.ObjToStringNoTrim(); + } + } + public static string ObjToString(this object thisValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return ""; + } + public static string ObjToStringNoTrim(this object thisValue) + { + if (thisValue != null) return thisValue.ToString(); + return ""; + } + public static string ObjToStringNew(this object thisValue) + { + if (thisValue != null && thisValue is byte[]) + { + return string.Join("|",thisValue as byte[]); + } + if (thisValue != null) return thisValue.ToString().Trim(); + return ""; + } + + public static string ObjToString(this object thisValue, string errorValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return errorValue; + } + + public static Decimal ObjToDecimal(this object thisValue) + { + Decimal reval = 0; + if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return 0; + } + + public static Decimal ObjToDecimal(this object thisValue, decimal errorValue) + { + Decimal reval = 0; + if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return errorValue; + } + + public static DateTime ObjToDate(this object thisValue) + { + if (thisValue is DateTime) + { + return (DateTime)thisValue; + } + DateTime reval = DateTime.MinValue; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) + { + reval = Convert.ToDateTime(thisValue); + } + return reval; + } + + public static DateTime ObjToDate(this object thisValue, DateTime errorValue) + { + if (thisValue is DateTime) + { + return (DateTime)thisValue; + } + DateTime reval = DateTime.MinValue; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return errorValue; + } + + public static bool ObjToBool(this object thisValue) + { + bool reval = false; + if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + + internal static MemberExpression ToMemberExpression(Expression parentIdExpression) + { + if (parentIdExpression is UnaryExpression) + { + return (parentIdExpression as UnaryExpression).Operand as MemberExpression; + } + else + { + return parentIdExpression as MemberExpression; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs index eb8291d8f..e5066717a 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarAccessory.cs @@ -497,6 +497,10 @@ namespace SqlSugar Check.Exception(SugarCompatible.IsFramework, "OceanBaseForOracle only support .net core"); InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.OceanBaseForOracle" : "SqlSugar.OceanBaseForOracleCore"; break; + case DbType.TDSQLForPGODBC: + Check.Exception(SugarCompatible.IsFramework, "TDSQLForPGODBC only support .net core"); + InstanceFactory.CustomDllName = SugarCompatible.IsFramework ? "SqlSugar.TDSQLForPGODBC" : "SqlSugar.TDSQLForPGODBC"; + break; case DbType.GaussDB: config.DbType = DbType.PostgreSQL; if (this.CurrentConnectionConfig.MoreSettings == null) diff --git a/Src/Asp.NetCore2/SqlSugar/Enum/DbType.cs b/Src/Asp.NetCore2/SqlSugar/Enum/DbType.cs index 969a4eac3..a3962e27c 100644 --- a/Src/Asp.NetCore2/SqlSugar/Enum/DbType.cs +++ b/Src/Asp.NetCore2/SqlSugar/Enum/DbType.cs @@ -33,6 +33,7 @@ namespace SqlSugar Doris, Xugu, GoldenDB, + TDSQLForPGODBC, Custom =900 } } diff --git a/Src/Asp.NetCore2/SqlSugarCore.sln b/Src/Asp.NetCore2/SqlSugarCore.sln index d6590f558..defb76bc5 100644 --- a/Src/Asp.NetCore2/SqlSugarCore.sln +++ b/Src/Asp.NetCore2/SqlSugarCore.sln @@ -76,7 +76,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DorisTest", "DorisTest\Dori EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlSugar.XuguCore", "SqlSugar.XuguCore\SqlSugar.XuguCore.csproj", "{86C30210-A729-4F66-958D-173ADC512B2B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2XuGuTest", "XuGuTest\2XuGuTest.csproj", "{4DA89736-24C7-4D20-B858-7DD304115E0A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "2XuGuTest", "XuGuTest\2XuGuTest.csproj", "{4DA89736-24C7-4D20-B858-7DD304115E0A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlSugar.TDSQLForPGODBC", "SqlSugar.TDSQLForPGODBC\SqlSugar.TDSQLForPGODBC.csproj", "{B86EC97E-13F2-422B-8CA0-46181D40DEF2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TDSQLForPGOBDCTest", "TDSQLForPGOBDCTest\TDSQLForPGOBDCTest.csproj", "{307E0D47-28A5-4E1A-8350-5CDC6C790B32}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -496,6 +500,30 @@ Global {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|ARM32.Build.0 = Release|Any CPU {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|x86.ActiveCfg = Release|Any CPU {4DA89736-24C7-4D20-B858-7DD304115E0A}.Release|x86.Build.0 = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|ARM32.ActiveCfg = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|ARM32.Build.0 = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|x86.ActiveCfg = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Debug|x86.Build.0 = Debug|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|Any CPU.Build.0 = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|ARM32.ActiveCfg = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|ARM32.Build.0 = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|x86.ActiveCfg = Release|Any CPU + {B86EC97E-13F2-422B-8CA0-46181D40DEF2}.Release|x86.Build.0 = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|ARM32.ActiveCfg = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|ARM32.Build.0 = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|x86.ActiveCfg = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Debug|x86.Build.0 = Debug|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|Any CPU.Build.0 = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|ARM32.ActiveCfg = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|ARM32.Build.0 = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|x86.ActiveCfg = Release|Any CPU + {307E0D47-28A5-4E1A-8350-5CDC6C790B32}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -510,6 +538,7 @@ Global {A8FDDB0E-835A-4042-A955-66A2DB98207D} = {88992AAF-146B-4253-9AD7-493E8F415B57} {6DED25D0-660B-468A-AD61-7646345145F5} = {88992AAF-146B-4253-9AD7-493E8F415B57} {86C30210-A729-4F66-958D-173ADC512B2B} = {88992AAF-146B-4253-9AD7-493E8F415B57} + {B86EC97E-13F2-422B-8CA0-46181D40DEF2} = {88992AAF-146B-4253-9AD7-493E8F415B57} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {230A85B9-54F1-41B1-B1DA-80086581B2B4} diff --git a/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Config.cs b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Config.cs new file mode 100644 index 000000000..42ea51c84 --- /dev/null +++ b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Config.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TDSQLForPGOBDCTest +{ + /// + /// Setting up the database name does not require you to create the database + /// 设置好数据库名不需要你去手动建库 + /// + public class Config + { + /// + /// Account have permission to create database + /// 用有建库权限的数据库账号 + /// + public static string ConnectionString = "Driver={TDSQL PostgreSQL Unicode(x64)};Server=172.19.4.36;Port=11001;Database=xirdb;Uid=xir_app;Pwd=xpar;ConnSettings=set search_path to XIR_APP;"; + /// + /// Account have permission to create database + /// 用有建库权限的数据库账号 + /// + public static string ConnectionString2 = "Driver={GBase ODBC DRIVER (64-Bit)};Host=localhost;Service=19088;Server=gbase01;Database=testdb;Protocol=onsoctcp;Uid=gbasedbt;Pwd=GBase123;Db_locale=zh_CN.utf8;Client_locale=zh_CN.utf8"; + /// + /// Account have permission to create database + /// 用有建库权限的数据库账号 + /// + public static string ConnectionString3 = "Driver={GBase ODBC DRIVER (64-Bit)};Host=localhost;Service=19088;Server=gbase01;Database=testdb;Protocol=onsoctcp;Uid=gbasedbt;Pwd=GBase123;Db_locale=zh_CN.utf8;Client_locale=zh_CN.utf8"; + } +} diff --git a/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Program.cs b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Program.cs new file mode 100644 index 000000000..f3b172a9f --- /dev/null +++ b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/Program.cs @@ -0,0 +1,51 @@ +using SqlSugar; +using SqlSugar.TDSQLForPGODBC; + +namespace TDSQLForPGOBDCTest +{ + internal class Program + { + static void Main(string[] args) + { + Console.WriteLine(""); + Console.WriteLine("#### MasterSlave Start ####"); + + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() + { + ConnectionString = Config.ConnectionString,//Master Connection + DbType = DbType.TDSQLForPGODBC,//Oracle 模式用这个 ,如果是MySql 模式用DbType.MySql + InitKeyType = InitKeyType.Attribute, + IsAutoCloseConnection = true, + MoreSettings = new ConnMoreSettings() + { + PgSqlIsAutoToLower = false,//增删查改支持驼峰表 + PgSqlIsAutoToLowerCodeFirst = false, // 建表建驼峰表。5.1.3.30 + } + }); + db.Aop.OnLogExecuted = (s, p) => + { + Console.WriteLine(s); + }; + var list = db.Queryable().ToList(); + + var page1 = db.Queryable().ToOffsetPage(1, 30); + + db.Insertable(new TSYS_USER + { + U_ID = "DGSSqlsugar", + U_NAME = "杜国舜SqlSugar适配", + U_EMAIL = "dd2@" + }).ExecuteCommand(); + + db.Updateable(new TSYS_USER + { + U_ID = "DGSSqlsugar", + U_NAME = "杜国舜SqlSugar适配,修改后", + U_EMAIL = "dd2@" + }).ExecuteCommand(); + + db.Deleteable().Where(m => m.U_ID == "DGSSqlsugar").ExecuteCommand(); + + } + } +} diff --git a/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TDSQLForPGOBDCTest.csproj b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TDSQLForPGOBDCTest.csproj new file mode 100644 index 000000000..ccea5b678 --- /dev/null +++ b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TDSQLForPGOBDCTest.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + diff --git a/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TSYS_USER.cs b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TSYS_USER.cs new file mode 100644 index 000000000..3b97c6049 --- /dev/null +++ b/Src/Asp.NetCore2/TDSQLForPGOBDCTest/TSYS_USER.cs @@ -0,0 +1,58 @@ +using SqlSugar; +using System; + +namespace TDSQLForPGOBDCTest +{ + /// + /// XIR用户表 + /// + [SugarTable("TSYS_USER")] + public partial class TSYS_USER + { + public TSYS_USER() + { + + + } + /// + /// Desc: + /// Default: + /// Nullable:False + /// + [SugarColumn(IsNullable = false, IsPrimaryKey = true, Length = 30)] + public string U_ID { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(IsNullable = true, Length = 50)] + public string U_NAME { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(IsNullable = true, Length = 1)] + public string U_STATE { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(IsNullable = true, Length = 2000)] + public string U_REMARK { get; set; } + + /// + /// Desc: + /// Default: + /// Nullable:True + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string U_EMAIL { get; set; } + + } +}