diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs index c06b3d1c7..e929de115 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleExpressionContext.cs @@ -72,14 +72,14 @@ namespace SqlSugar.OceanBaseForOracle } } } - - public override string GetLimit() - { - return "AND ROWNUM=1"; - } } public partial class OceanBaseForOracleMethod : DefaultDbMethod, IDbMethods { + public override string IsNullOrEmpty(MethodCallExpressionModel model) + { + var parameter = model.Args[0]; + return string.Format("( {0} IS NULL )", parameter.MemberName); + } public override string WeekOfYear(MethodCallExpressionModel mode) { var parameterNameA = mode.Args[0].MemberName; @@ -104,7 +104,14 @@ namespace SqlSugar.OceanBaseForOracle } public override string GetStringJoinSelector(string result, string separator) { - return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + if (result.Contains(",")) + { + return $"listagg(to_char({result.Split(',').First()}),'{separator}') within group(order by {result.Split(',').Last()}) "; + } + else + { + return $"listagg(to_char({result}),'{separator}') within group(order by {result}) "; + } } public override string HasValue(MethodCallExpressionModel model) { @@ -211,8 +218,10 @@ namespace SqlSugar.OceanBaseForOracle return string.Format("(CAST(TO_CHAR({0},'mi') AS NUMBER))", parameter.MemberName); case DateType.Millisecond: return string.Format("(CAST(TO_CHAR({0},'ff3') AS NUMBER))", parameter.MemberName); + case DateType.Quarter: + return string.Format("(CAST(TO_CHAR({0},'q') AS NUMBER))", parameter.MemberName); case DateType.Weekday: - return $" to_char({parameter.MemberName},'day') "; + return $" (TO_NUMBER(TO_CHAR({parameter.MemberName}, 'D'))-1) "; case DateType.Day: default: return string.Format("(CAST(TO_CHAR({0},'dd') AS NUMBER))", parameter.MemberName); @@ -275,6 +284,7 @@ namespace SqlSugar.OceanBaseForOracle var parameter = model.Args[0]; return string.Format(" TO_TIMESTAMP({0}, 'YYYY-MM-DD HH24:MI:SS.FF') ", parameter.MemberName); } + public override string ToDateShort(MethodCallExpressionModel model) { var parameter = model.Args[0]; @@ -311,7 +321,47 @@ namespace SqlSugar.OceanBaseForOracle } public override string DateIsSameByType(MethodCallExpressionModel model) { - throw new NotSupportedException("Oracle NotSupportedException DateIsSameDay"); + var parameter = model.Args[0]; + var parameter2 = model.Args[1]; + var parameter3 = model.Args[2]; + + var dateType = parameter3.MemberValue.ObjToString().ToLower(); + var date1 = parameter.MemberName; + var date2 = parameter2.MemberName; + + if (dateType == "year") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}))", date1, date2); + } + else if (dateType == "month") + { + return string.Format("(EXTRACT(YEAR FROM {0}) = EXTRACT(YEAR FROM {1}) AND EXTRACT(MONTH FROM {0}) = EXTRACT(MONTH FROM {1}))", date1, date2); + } + else if (dateType == "day") + { + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } + else if (dateType == "hour") + { + return string.Format("(TRUNC({0}, 'HH24') = TRUNC({1}, 'HH24'))", date1, date2); + } + else if (dateType == "minute") + { + return string.Format("(TRUNC({0}, 'MI') = TRUNC({1}, 'MI'))", date1, date2); + } + else if (dateType == "second") + { + return string.Format("(TRUNC({0}, 'SS') = TRUNC({1}, 'SS'))", date1, date2); + } + else if (dateType == "week" || dateType == "weekday") + { + return string.Format("(TRUNC({0}, 'IW') = TRUNC({1}, 'IW'))", date1, date2); + } + else + { + // 默认按天比较 + return string.Format("(TRUNC({0}) = TRUNC({1}))", date1, date2); + } } public override string Length(MethodCallExpressionModel model) { @@ -380,7 +430,28 @@ namespace SqlSugar.OceanBaseForOracle { var parameterNameA = mode.Args[0].MemberName; var parameterNameB = mode.Args[1].MemberName; - return $" SUBSTR({parameterNameA}, -2, {parameterNameB}) "; + return $" SUBSTR({parameterNameA}, (LENGTH({parameterNameA})-2), {parameterNameB}) "; + } + + public override string Ceil(MethodCallExpressionModel mode) + { + var parameterNameA = mode.Args[0].MemberName; + return $" CEIL({parameterNameA}) "; + } + + public override string NewUid(MethodCallExpressionModel mode) + { + return " SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 1, 8) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 9, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 13, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 17, 4) ||\r\n '-' ||\r\n SUBSTR(LOWER(RAWTOHEX(SYS_GUID())), 21) "; + } + public override string FullTextContains(MethodCallExpressionModel mode) + { + var columns = mode.Args[0].MemberName; + if (mode.Args[0].MemberValue is List) + { + columns = "(" + string.Join(",", mode.Args[0].MemberValue as List) + ")"; + } + var searchWord = mode.Args[1].MemberName; + return $" CONTAINS({columns}, {searchWord}, 1) "; } } } diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs index feed53182..3849d93e9 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/OceanBase/SqlBuilder/OceanBaseForOracleUpdateBuilder.cs @@ -37,7 +37,7 @@ namespace SqlSugar.OceanBaseForOracle { var isFirst = pkList.First() == item; var whereString = isFirst ? " " : " AND "; - whereString += GetOracleUpdateColums(item); + whereString += GetOracleUpdateColums(item, true); whereList.Add(whereString); } return string.Format("{0} {1} WHERE {2};", updateTable, setValues, string.Join("", whereList)); @@ -46,9 +46,15 @@ namespace SqlSugar.OceanBaseForOracle return sb.ToString(); } - private string GetOracleUpdateColums(DbColumnInfo m) + private string GetOracleUpdateColums(DbColumnInfo m, bool isWhere = false) { - return string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(m.Value, m.IsPrimarykey, m.PropertyName))); + + var result = string.Format("\"{0}\"={1} ", m.DbColumnName.ToUpper(IsUppper), base.GetDbColumn(m, FormatValue(m.Value, m.IsPrimarykey, m.PropertyName))); + if (isWhere && m.Value == null) + { + result = result.Replace("=NULL ", " is NULL "); + } + return result; } int i = 0; public object FormatValue(object value, bool isPrimaryKey, string name) diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs new file mode 100644 index 000000000..8eab177ed --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/QueryableFormat.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar.OceanBaseForOracle +{ + internal class QueryableFormat + { + public Type Type { get; set; } + public string TypeString { get; set; } + public string Format { get; set; } + public string PropertyName { get; set; } + public string MethodName { get; set; } + public MethodInfo MethodInfo { get; set; } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs index a5225abf4..fa0445b87 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilConstants.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Dynamic; using System.Linq; +using System.Linq.Expressions; using System.Text; namespace SqlSugar.OceanBaseForOracle { @@ -10,17 +11,22 @@ namespace SqlSugar.OceanBaseForOracle public const string Dot = "."; public const char DotChar = '.'; internal const string Space = " "; - internal const char SpaceChar =' '; - internal const string AssemblyName = "SqlSugar"; - internal const string ReplaceKey = "{662E689B-17A1-4D06-9D27-F29EAB8BC3D6}"; + internal const char SpaceChar = ' '; + internal const string AssemblyName = "SqlSugar.OceanBaseForOracle"; + internal static string ReplaceKey = "{" + Guid.NewGuid() + "}"; internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + internal const string GroupReplaceKey = "{GroupReplaceKey_l33asdysaas1231s}"; + 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); @@ -31,7 +37,7 @@ namespace SqlSugar.OceanBaseForOracle 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 ModelType = typeof(ModelContext); internal static Type DynamicType = typeof(ExpandoObject); internal static Type Dicii = typeof(KeyValuePair); internal static Type DicIS = typeof(KeyValuePair); @@ -42,6 +48,8 @@ namespace SqlSugar.OceanBaseForOracle 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); @@ -56,7 +64,7 @@ namespace SqlSugar.OceanBaseForOracle typeof(short), typeof(ushort), }; - + //internal static CultureInfo EnCultureInfo = new CultureInfo("en"); internal static string[] DateTypeStringList = new string[] { @@ -69,5 +77,8 @@ namespace SqlSugar.OceanBaseForOracle "Millisecond", "Date" }; + + public static ConstantExpression ExpTrue = Expression.Constant(true); + public static ConstantExpression ExpFalse = Expression.Constant(false); } } diff --git a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs index feb4fb09d..624cd1591 100644 --- a/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar.OceanBaseForOracle/Tools/UtilMethods.cs @@ -1,9 +1,11 @@ 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; @@ -16,21 +18,626 @@ namespace SqlSugar.OceanBaseForOracle { public class UtilMethods { - internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig) + public static string EscapeLikeValue(ISqlSugarClient db, string value, char wildcard = '%') { - if (currentConnectionConfig.MoreSettings == null) + var dbType = db.CurrentConnectionConfig.DbType; + if (db.CurrentConnectionConfig?.MoreSettings?.DatabaseModel != null) { - return Convert.ToDateTime("1900-01-01"); + dbType = db.CurrentConnectionConfig.MoreSettings.DatabaseModel.Value; } - else if (currentConnectionConfig.MoreSettings.DbMinDate == null) + if (string.IsNullOrEmpty(value)) + return value; + + string wildcardStr = wildcard.ToString(); + + switch (dbType) { - return Convert.ToDateTime("1900-01-01"); + // 支持标准 SQL LIKE 转义,通常使用中括号 [] 或反斜杠 \ 进行转义 + case DbType.SqlServer: + case DbType.Access: + case DbType.Odbc: + case DbType.TDSQLForPGODBC: + // SQL Server 使用中括号转义 %, _ 等 + value = value.Replace("[", "[[]") + .Replace("]", "[]]") + .Replace(wildcardStr, $"[{wildcard}]"); + break; + + // PostgreSQL 风格数据库,使用反斜杠进行 LIKE 转义 + case DbType.PostgreSQL: + case DbType.OpenGauss: + case DbType.TDSQL: + case DbType.GaussDB: + case DbType.GaussDBNative: + // MySQL 和兼容库,使用反斜杠进行转义 + case DbType.MySql: + case DbType.MySqlConnector: + case DbType.Tidb: + case DbType.PolarDB: + case DbType.OceanBase: + case DbType.Oracle: + case DbType.OceanBaseForOracle: + case DbType.HG: + case DbType.Dm: + case DbType.GBase: + case DbType.DB2: + case DbType.HANA: + case DbType.GoldenDB: + case DbType.Sqlite: + case DbType.DuckDB: + case DbType.QuestDB: + case DbType.Doris: + case DbType.Xugu: + case DbType.Vastbase: + default: + value = value + .Replace(wildcardStr, "\\\\" + wildcard); + break; + } + + return value; + } + + + 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 object QueryConverter(int index, ISqlSugarClient db, IDataReader dataReader, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("QueryConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { dataReader, index }); + 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 { - return currentConnectionConfig.MoreSettings.DbMinDate.Value; + isList = false; + } + return ExpressionBuilderHelper.CreateExpressionSelectField(entityInfo.Type, navInfo.PropertyName, properyType); + } + public static string RemoveEqualOne(string value) + { + value = value.TrimEnd(' ').TrimEnd('1').TrimEnd('='); + return value; + } + /// + /// Available only in Select,Handles logic that cannot be completed by an expression + /// + /// + /// + /// + internal static object GetFormatValue(object addValue, QueryableFormat valueFomatInfo) + { + if (valueFomatInfo.MethodName == "ToString") + { + if (valueFomatInfo.Type == UtilConstants.GuidType) + { + addValue = Guid.Parse(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ByteType) + { + addValue = Convert.ToByte(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.IntType) + { + addValue = Convert.ToInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.LongType) + { + addValue = Convert.ToInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.UIntType) + { + addValue = Convert.ToUInt32(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.ULongType) + { + addValue = Convert.ToUInt64(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DecType) + { + addValue = Convert.ToDecimal(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.Type == UtilConstants.DobType) + { + addValue = Convert.ToDouble(addValue + "").ToString(valueFomatInfo.Format); + } + else if (valueFomatInfo.TypeString == "Enum") + { + addValue = ChangeType2(addValue, valueFomatInfo.Type)?.ToString(); + } + } + else if (valueFomatInfo.MethodName == "OnlyInSelectConvertToString") + { + + var methodInfo = valueFomatInfo.MethodInfo; + if (methodInfo != null) + { + // 如果方法是静态的,传递null作为第一个参数,否则传递类的实例 + object instance = methodInfo.IsStatic ? null : Activator.CreateInstance(methodInfo.ReflectedType); + + // 创建一个包含参数值的object数组 + object[] parameters = new object[] { addValue }; + + // 调用方法 + addValue = methodInfo.Invoke(instance, parameters); + } + } + return addValue; + } + 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)) @@ -52,7 +659,33 @@ namespace SqlSugar.OceanBaseForOracle { 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; + } + } + else if (value is byte[] bytes && bytes.Length == 1 && destinationType == typeof(char)) + { + return (char)(bytes)[0]; + } + else if (value is DateTime && destinationType == typeof(TimeSpan)) + { + value = Convert.ToDateTime(value).TimeOfDay; + } + else if (value is DateTime && destinationType.FullName == "System.TimeOnly") + { + value = Convert.ToDateTime(value).TimeOfDay; + } var destinationConverter = TypeDescriptor.GetConverter(destinationType); if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) return destinationConverter.ConvertFrom(null, culture, value); @@ -64,6 +697,19 @@ namespace SqlSugar.OceanBaseForOracle 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); } @@ -83,6 +729,119 @@ namespace SqlSugar.OceanBaseForOracle 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, + CheckConnectionExecuted = it.AopEvents?.CheckConnectionExecuted, + CheckConnectionExecuting = it.AopEvents?.CheckConnectionExecuting, + OnGetDataReadered = it.AopEvents?.OnGetDataReadered, + OnGetDataReadering = it.AopEvents?.OnGetDataReadering, + }, + 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, + PgSqlIsAutoToLowerSchema = it.MoreSettings.PgSqlIsAutoToLowerSchema + + }, + 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) @@ -109,6 +868,10 @@ namespace SqlSugar.OceanBaseForOracle { 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); @@ -146,15 +909,50 @@ namespace SqlSugar.OceanBaseForOracle 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 Type GetUnderType(Type oldType) + + 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); @@ -206,16 +1004,20 @@ namespace SqlSugar.OceanBaseForOracle 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; - //} + 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; @@ -226,6 +1028,7 @@ namespace SqlSugar.OceanBaseForOracle 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]; @@ -235,6 +1038,10 @@ namespace SqlSugar.OceanBaseForOracle 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); } @@ -255,20 +1062,39 @@ namespace SqlSugar.OceanBaseForOracle 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(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) { @@ -289,11 +1115,11 @@ namespace SqlSugar.OceanBaseForOracle { return x => Convert.ToInt64(x); } - else if (value is DateTime|| value is DateTime?) + else if (value is DateTime || value is DateTime?) { return x => Convert.ToDateTime(x); } - else if (value is bool||value is bool?) + else if (value is bool || value is bool?) { return x => Convert.ToBoolean(x); } @@ -306,7 +1132,7 @@ namespace SqlSugar.OceanBaseForOracle { return null; } - else + else { return value.GetType().Name; } @@ -316,7 +1142,10 @@ namespace SqlSugar.OceanBaseForOracle { if (Regex.IsMatch(dbTypeName, @"\(.+\)")) { - dbTypeName = Regex.Replace(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; @@ -356,21 +1185,25 @@ namespace SqlSugar.OceanBaseForOracle return byte2String; } - //public static string EncodeBase64(string 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 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); @@ -394,56 +1227,83 @@ namespace SqlSugar.OceanBaseForOracle return sb.ToString(); } - //public static string DecodeBase64(string code) - //{ - // try - // { - // 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 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 (callExpresion.Arguments.Count == 0) + if (item != null) { - methodInfo.Invoke(item, null); - } - else - { - List methodParameters = new List(); - foreach (var callItem in callExpresion.Arguments) + if (callExpresion.Arguments.Count == 0) { - 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, 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()); } - methodInfo.Invoke(item, methodParameters.ToArray()); } } } @@ -464,44 +1324,591 @@ namespace SqlSugar.OceanBaseForOracle } return dic; } - //public static object ConvertDataByTypeName(string ctypename,string value) - //{ - // var item = new ConditionalModel() { - // CSharpTypeName = ctypename, - // FieldValue = value - // }; - // 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.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)) - // { - // return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue)); - // } - // else - // { - // return item.FieldValue; - // } - //} + + 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("float")) + { + return Convert.ToSingle(item.FieldValue); + } + else if (item.CSharpTypeName.EqualCase("single")) + { + return Convert.ToSingle(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 guid = Guid.NewGuid() + ""; + var result = sqlObj.Key; + if (sqlObj.Value != null) + { + foreach (var item in UtilMethods.CopySugarParameters(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 && PostgreSQLDbBind.MappingTypesConst.Any(x => x.Value.ToString().EqualCase(item.Value.GetType().Name))) + { + var type = PostgreSQLDbBind.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().Replace("@", guid).ToSqlFilter()}'"); + } + else + { + result = result.Replace(item.ParameterName, $"N'{item.Value.ObjToString().Replace("@", guid).ToSqlFilter()}'"); + } + } + } + result = result.Replace(guid, "@"); + 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; + } + + internal static ConnMoreSettings GetMoreSetting(ExpressionContext context) + { + return context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings ?? new ConnMoreSettings(); + } } } diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs index 6c655487d..72583bf67 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs @@ -8,6 +8,7 @@ namespace SqlSugar.TDSQLForPGODBC { public override string GetDbTypeName(string csharpTypeName) { + csharpTypeName = GetValidCsharpTypeName(csharpTypeName); if (csharpTypeName == UtilConstants.ByteArrayType.Name) return "bytea"; if (csharpTypeName.ToLower() == "int32") @@ -26,18 +27,38 @@ namespace SqlSugar.TDSQLForPGODBC else return "varchar"; } + + private string GetValidCsharpTypeName(string csharpTypeName) + { + if (csharpTypeName?.StartsWith("ora") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("ora", ""); + } + else if (csharpTypeName?.StartsWith("mssql_") == true && this.Context.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase) + { + csharpTypeName = csharpTypeName.Replace("mssql_", ""); + } + else if (csharpTypeName?.StartsWith("sys.") == true) + { + csharpTypeName = csharpTypeName.Replace("sys.", ""); + } + return csharpTypeName; + } + public override string GetPropertyTypeName(string dbTypeName) { dbTypeName = dbTypeName.ToLower(); + dbTypeName = GetValidCsharpTypeName(dbTypeName); 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") + else if (dbTypeName == "xml" || dbTypeName == "string" || dbTypeName == "jsonb" || dbTypeName == "json") { return "string"; - }else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar + } + else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar { return "char"; } @@ -50,7 +71,11 @@ namespace SqlSugar.TDSQLForPGODBC 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(); + return MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName2 || it.Key.ToLower() == dbTypeName2).Select(it => it.Value + "[]").First(); + } + else if (dbTypeName.EndsWith("geometry") || dbTypeName.EndsWith("geography")) + { + return CSharpDataType.@string.ToString(); } Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName)); return null; @@ -85,7 +110,7 @@ namespace SqlSugar.TDSQLForPGODBC //new KeyValuePair("int1",CSharpDataType.@byte), new KeyValuePair("smallint",CSharpDataType.@short), new KeyValuePair("smallint",CSharpDataType.@byte), - new KeyValuePair("int4",CSharpDataType.@int), + new KeyValuePair("int4",CSharpDataType.@int), new KeyValuePair("serial",CSharpDataType.@int), new KeyValuePair("integer",CSharpDataType.@int), new KeyValuePair("int8",CSharpDataType.@long), @@ -146,7 +171,16 @@ namespace SqlSugar.TDSQLForPGODBC new KeyValuePair("time",CSharpDataType.TimeSpan), new KeyValuePair("public.geometry",CSharpDataType.@object), new KeyValuePair("public.geography",CSharpDataType.@object), - new KeyValuePair("inet",CSharpDataType.@object) + new KeyValuePair("inet",CSharpDataType.@object), + + new KeyValuePair("number",CSharpDataType.@int), + new KeyValuePair("number",CSharpDataType.@float), + new KeyValuePair("number",CSharpDataType.@short), + new KeyValuePair("number",CSharpDataType.@byte), + new KeyValuePair("number",CSharpDataType.@double), + new KeyValuePair("number",CSharpDataType.@long), + new KeyValuePair("number",CSharpDataType.@bool), + new KeyValuePair("number",CSharpDataType.@decimal), }; public override List StringThrow { diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs index e86932bb3..c5a8e717a 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/DbMaintenance/TDSQLForPGODBCDbMaintenance.cs @@ -30,8 +30,11 @@ namespace SqlSugar.TDSQLForPGODBC 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 (current_setting('server_version_num')::INT >= 100000 AND pcolumn.is_identity = 'YES') THEN true + 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 @@ -70,7 +73,7 @@ namespace SqlSugar.TDSQLForPGODBC { get { - return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema()+"' "; + return @"select table_name as name from information_schema.views where table_schema ='" + GetSchema() + "' "; } } #endregion @@ -247,6 +250,18 @@ namespace SqlSugar.TDSQLForPGODBC #endregion #region Methods + public override bool IsAnyTable(string tableName, bool isCache = true) + { + if (isCache == false) + { + var sql = $" SELECT 1 FROM pg_catalog.pg_tables \r\n WHERE schemaname = '" + GetSchema() + "' \r\n AND Lower(tablename) = '" + tableName.ToLower() + "' "; + return this.Context.Ado.GetInt(sql) > 0; + } + else + { + return base.IsAnyTable(tableName, isCache); + } + } public override List GetDbTypes() { var result = this.Context.Ado.SqlQuery(@"SELECT DISTINCT data_type @@ -260,7 +275,7 @@ FROM information_schema.columns"); result.Add("time"); result.Add("date"); result.Add("float8"); - result.Add("float4"); + result.Add("float4"); result.Add("json"); result.Add("jsonp"); return result.Distinct().ToList(); @@ -269,7 +284,7 @@ FROM information_schema.columns"); { return this.Context.Ado.SqlQuery(@"SELECT tgname FROM pg_trigger -WHERE tgrelid = '"+tableName+"'::regclass"); +WHERE tgrelid = '" + tableName + "'::regclass"); } public override List GetFuncList() { @@ -287,26 +302,26 @@ WHERE tgrelid = '"+tableName+"'::regclass"); } 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'")) + 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); + 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 ); + 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+"'"); + 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('\'')); + 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) @@ -341,11 +356,11 @@ WHERE tgrelid = '"+tableName+"'::regclass"); { ConvertCreateColumnInfo(columnInfo); tableName = this.SqlBuilder.GetTranslationTableName(tableName); - var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); + 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)); + 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; } @@ -382,7 +397,16 @@ WHERE tgrelid = '"+tableName+"'::regclass"); } var oldDatabaseName = this.Context.Ado.Connection.Database; var connection = this.Context.CurrentConnectionConfig.ConnectionString; - connection = connection.Replace(oldDatabaseName, "postgres"); + if (Regex.Matches(connection, oldDatabaseName).Count > 1) + { + var builder = new Npgsql.NpgsqlConnectionStringBuilder(connection); + builder.Database = "postgres"; + connection = builder.ConnectionString; + } + else + { + connection = connection.Replace(oldDatabaseName, "postgres"); + } var newDb = new SqlSugarClient(new ConnectionConfig() { DbType = this.Context.CurrentConnectionConfig.DbType, @@ -391,13 +415,13 @@ WHERE tgrelid = '"+tableName+"'::regclass"); }); if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase))) { - var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel==DbType.Vastbase; + var isVast = this.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase; var dbcompatibility = ""; - if (isVast) + if (isVast) { - dbcompatibility=" dbcompatibility = 'PG'"; + dbcompatibility = " dbcompatibility = 'PG'"; } - newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft+databaseName+this.SqlBuilder.SqlTranslationRight, databaseDirectory)+ dbcompatibility); + newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft + databaseName + this.SqlBuilder.SqlTranslationRight, databaseDirectory) + dbcompatibility); } return true; } @@ -451,7 +475,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); 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) + if (defaultValue?.StartsWith("NULL::") == true) { return false; } @@ -475,7 +499,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); // dataType = "varchar"; //} string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null; - if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric") + if (item.DecimalDigits > 0 && item.Length > 0 && dataType == "numeric") { dataSize = $"({item.Length},{item.DecimalDigits})"; } @@ -484,7 +508,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, nullType, primaryKey, ""); if (item.IsIdentity) { - if (dataType?.ToLower() == "int") + if (dataType?.ToLower() == "int") { dataSize = "int4"; } @@ -513,7 +537,7 @@ WHERE tgrelid = '"+tableName+"'::regclass"); public override List GetColumnInfosByTableName(string tableName, bool isCache = true) { - var result= base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); + var result = base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache); if (result == null || result.Count() == 0) { result = base.GetColumnInfosByTableName(tableName, isCache); @@ -533,24 +557,24 @@ WHERE tgrelid = '"+tableName+"'::regclass"); List pkList = new List(); if (isCache) { - pkList=GetListOrCache("GetColumnInfosByTableName_N_Pk"+tableName, sql); + pkList = GetListOrCache("GetColumnInfosByTableName_N_Pk" + tableName, sql); } else { pkList = this.Context.Ado.SqlQuery(sql); } - if (pkList.Count >1) + if (pkList.Count > 1) { foreach (var item in result) { - if (pkList.Select(it=>it.ToUpper()).Contains(item.DbColumnName.ToUpper())) + if (pkList.Select(it => it.ToUpper()).Contains(item.DbColumnName.ToUpper())) { item.IsPrimarykey = true; } } } } - catch + catch { } @@ -579,28 +603,50 @@ WHERE tgrelid = '"+tableName+"'::regclass"); private string GetSchema() { var schema = "public"; - if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) + var pgSqlIsAutoToLowerSchema = this.Context?.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLowerSchema == false; + if (pgSqlIsAutoToLowerSchema) { - var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value; - if (regValue.HasValue()) + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "searchpath=", RegexOptions.IgnoreCase)) { - schema = regValue; + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString, @"searchpath\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } + } + else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString, "search path=", RegexOptions.IgnoreCase)) + { + var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; + if (regValue.HasValue()) + { + schema = regValue; + } } } - else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path=")) + else { - var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value; - if (regValue.HasValue()) + if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath=")) { - schema = regValue; + 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" }; + string[] array = new string[] { "uuid", "int4", "text", "int2", "int8", "date", "bit", "text", "timestamp" }; if (array.Contains(x.DataType?.ToLower())) { diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs index 939dafc6c..8342eee35 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCExpressionContext.cs @@ -54,7 +54,7 @@ namespace SqlSugar.TDSQLForPGODBC { var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase)); - var tableName = mappingInfo?.DbTableName+""; + var tableName = mappingInfo?.DbTableName + ""; if (tableName.Contains(".")) { tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it))); @@ -102,7 +102,7 @@ namespace SqlSugar.TDSQLForPGODBC } } - public string GetValue(object entityValue) + public string GetValue(object entityValue) { if (entityValue == null) return null; @@ -120,7 +120,7 @@ namespace SqlSugar.TDSQLForPGODBC } }); } - else + else { return this.DbMehtods.ToString(new MethodCallExpressionModel() { @@ -180,7 +180,7 @@ namespace SqlSugar.TDSQLForPGODBC var parameter = model.Args[0]; var parameter2 = model.Args[1]; var parameter3 = model.Args[2]; - if (parameter.Type == UtilConstants.BoolType) + if (parameter.Type == UtilConstants.BoolType) { parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true"); parameter2.MemberName = false; @@ -229,7 +229,7 @@ namespace SqlSugar.TDSQLForPGODBC { return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) "; } - + return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName); } @@ -237,13 +237,19 @@ namespace SqlSugar.TDSQLForPGODBC { var parameter = model.Args[0]; var parameter2 = model.Args[1]; - return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName ); + 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]; + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = parameter2.MemberValue + "%"; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName); } @@ -251,7 +257,13 @@ namespace SqlSugar.TDSQLForPGODBC { var parameter = model.Args[0]; var parameter2 = model.Args[1]; - return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName,parameter2.MemberName); + var parameter2Info = model.Parameters?.FirstOrDefault(it => it.ParameterName.EqualCase(parameter2.MemberName + "")); + if (parameter2Info != null && parameter2.MemberName?.ToString()?.StartsWith("@MethodConst") == true) + { + parameter2Info.Value = "%" + parameter2.MemberValue; + return string.Format(" ({0} like {1} ) ", parameter.MemberName, parameter2.MemberName); + } + return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName, parameter2.MemberName); } public override string DateIsSameDay(MethodCallExpressionModel model) @@ -272,11 +284,11 @@ namespace SqlSugar.TDSQLForPGODBC var parameter = model.Args[0]; var parameter2 = model.Args[1]; var parameter3 = model.Args[2]; - DateType dateType =(DateType)parameter3.MemberValue; + 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); + return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName, format); } switch (dateType) { @@ -375,8 +387,8 @@ namespace SqlSugar.TDSQLForPGODBC } public override string IsNullOrEmpty(MethodCallExpressionModel model) { - if ( - model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase|| + if ( + model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.Vastbase || model.Conext?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.GaussDB) { var parameter = model.Args[0]; @@ -390,7 +402,7 @@ namespace SqlSugar.TDSQLForPGODBC public override string MergeString(params string[] strings) { var key = Guid.NewGuid() + ""; - return " concat("+string.Join(",", strings.Select(it=>it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; + return " concat(" + string.Join(",", strings.Select(it => it?.Replace("+", key))).Replace("+", "").Replace(key, "+") + ") "; } public override string IsNull(MethodCallExpressionModel model) { @@ -418,10 +430,10 @@ namespace SqlSugar.TDSQLForPGODBC 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) + 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); + result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3); } if (model.Args.Count > 3) { @@ -445,13 +457,13 @@ namespace SqlSugar.TDSQLForPGODBC return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})"; } - private string GetJson(object memberName1, object memberName2,bool isLast) + private string GetJson(object memberName1, object memberName2, bool isLast) { if (isLast) { return $"({memberName1}::json->>{memberName2})"; } - else + else { return $"({memberName1}->{memberName2})"; } @@ -477,11 +489,20 @@ namespace SqlSugar.TDSQLForPGODBC { return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb "; } - else + else { return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb "; } } + public override string GetStringJoinSelector(string result, string separator) + { + if (result?.ToLower()?.Contains("distinct") == true) + { + return $"string_agg({result},'{separator}') "; + } + return $"string_agg(({result})::text,'{separator}') "; + } + public override string JsonListObjectAny(MethodCallExpressionModel model) { if (UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name)) diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs index fd3e00ce9..dc41d9793 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCInsertBuilder.cs @@ -242,6 +242,10 @@ namespace SqlSugar.TDSQLForPGODBC { return v.ToString(CultureInfo.InvariantCulture); } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } else { return N + "'" + value.ToString() + "'"; diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs index f60158385..fee5d3802 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/TDSQLForPG/SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs @@ -91,6 +91,10 @@ namespace SqlSugar.TDSQLForPGODBC { return v.ToString(CultureInfo.InvariantCulture); } + else if (value is double dou) + { + return dou.ToString(CultureInfo.InvariantCulture); + } else { return "'" + value.ToString() + "'"; @@ -285,3 +289,4 @@ namespace SqlSugar.TDSQLForPGODBC } } } + diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs index 86ce50d2f..a442ca6d9 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilConstants.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Dynamic; using System.Linq; +using System.Linq.Expressions; using System.Text; namespace SqlSugar.TDSQLForPGODBC { @@ -11,9 +12,10 @@ namespace SqlSugar.TDSQLForPGODBC public const char DotChar = '.'; internal const string Space = " "; internal const char SpaceChar = ' '; - internal const string AssemblyName = "SqlSugar"; + internal const string AssemblyName = "SqlSugar.TDSQLForPGODBC"; internal static string ReplaceKey = "{" + Guid.NewGuid() + "}"; internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}"; + internal const string GroupReplaceKey = "{GroupReplaceKey_l33asdysaas1231s}"; internal static Type UShortType = typeof(ushort); internal static Type ULongType = typeof(ulong); @@ -62,7 +64,7 @@ namespace SqlSugar.TDSQLForPGODBC typeof(short), typeof(ushort), }; - + //internal static CultureInfo EnCultureInfo = new CultureInfo("en"); internal static string[] DateTypeStringList = new string[] { @@ -75,5 +77,8 @@ namespace SqlSugar.TDSQLForPGODBC "Millisecond", "Date" }; + + public static ConstantExpression ExpTrue = Expression.Constant(true); + public static ConstantExpression ExpFalse = Expression.Constant(false); } } diff --git a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs index 2a8ab2cf2..3f10fd70b 100644 --- a/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar.TDSQLForPGODBC/Tools/UtilMethods.cs @@ -18,6 +18,66 @@ namespace SqlSugar.TDSQLForPGODBC { public class UtilMethods { + public static string EscapeLikeValue(ISqlSugarClient db, string value, char wildcard = '%') + { + var dbType = db.CurrentConnectionConfig.DbType; + if (db.CurrentConnectionConfig?.MoreSettings?.DatabaseModel != null) + { + dbType = db.CurrentConnectionConfig.MoreSettings.DatabaseModel.Value; + } + if (string.IsNullOrEmpty(value)) + return value; + + string wildcardStr = wildcard.ToString(); + + switch (dbType) + { + // 支持标准 SQL LIKE 转义,通常使用中括号 [] 或反斜杠 \ 进行转义 + case DbType.SqlServer: + case DbType.Access: + case DbType.Odbc: + case DbType.TDSQLForPGODBC: + // SQL Server 使用中括号转义 %, _ 等 + value = value.Replace("[", "[[]") + .Replace("]", "[]]") + .Replace(wildcardStr, $"[{wildcard}]"); + break; + + // PostgreSQL 风格数据库,使用反斜杠进行 LIKE 转义 + case DbType.PostgreSQL: + case DbType.OpenGauss: + case DbType.TDSQL: + case DbType.GaussDB: + case DbType.GaussDBNative: + // MySQL 和兼容库,使用反斜杠进行转义 + case DbType.MySql: + case DbType.MySqlConnector: + case DbType.Tidb: + case DbType.PolarDB: + case DbType.OceanBase: + case DbType.Oracle: + case DbType.OceanBaseForOracle: + case DbType.HG: + case DbType.Dm: + case DbType.GBase: + case DbType.DB2: + case DbType.HANA: + case DbType.GoldenDB: + case DbType.Sqlite: + case DbType.DuckDB: + case DbType.QuestDB: + case DbType.Doris: + case DbType.Xugu: + case DbType.Vastbase: + default: + value = value + .Replace(wildcardStr, "\\\\" + wildcard); + break; + } + + return value; + } + public static List CopySugarParameters(List pars) { @@ -193,6 +253,14 @@ namespace SqlSugar.TDSQLForPGODBC var p = ParameterConverter.Invoke(obj, new object[] { value, 100 + index }) as SugarParameter; return p; } + internal static object QueryConverter(int index, ISqlSugarClient db, IDataReader dataReader, EntityInfo entity, EntityColumnInfo columnInfo) + { + var type = columnInfo.SqlParameterDbType as Type; + var ParameterConverter = type.GetMethod("QueryConverter").MakeGenericMethod(columnInfo.PropertyInfo.PropertyType); + var obj = Activator.CreateInstance(type); + var p = ParameterConverter.Invoke(obj, new object[] { dataReader, index }); + return p; + } internal static bool IsErrorParameterName(ConnectionConfig connectionConfig, DbColumnInfo columnInfo) { return connectionConfig.MoreSettings?.IsCorrectErrorSqlParameterName == true && @@ -610,6 +678,14 @@ namespace SqlSugar.TDSQLForPGODBC { return (char)(bytes)[0]; } + else if (value is DateTime && destinationType == typeof(TimeSpan)) + { + value = Convert.ToDateTime(value).TimeOfDay; + } + else if (value is DateTime && destinationType.FullName == "System.TimeOnly") + { + value = Convert.ToDateTime(value).TimeOfDay; + } var destinationConverter = TypeDescriptor.GetConverter(destinationType); if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) return destinationConverter.ConvertFrom(null, culture, value); @@ -722,7 +798,8 @@ namespace SqlSugar.TDSQLForPGODBC DisableQueryWhereColumnRemoveTrim = it.MoreSettings.DisableQueryWhereColumnRemoveTrim, DatabaseModel = it.MoreSettings.DatabaseModel, EnableILike = it.MoreSettings.EnableILike, - ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal + ClickHouseEnableFinal = it.MoreSettings.ClickHouseEnableFinal, + PgSqlIsAutoToLowerSchema = it.MoreSettings.PgSqlIsAutoToLowerSchema }, SqlMiddle = it.SqlMiddle == null ? null : new SqlMiddle