From 1bf233b4c81780c76e6f9389f462e10ea9f13f6f Mon Sep 17 00:00:00 2001 From: "guoshun.du" Date: Tue, 6 May 2025 10:34:06 +0800 Subject: [PATCH] =?UTF-8?q?TDSQLForPGODBC=E5=90=8C=E6=AD=A5TDSQL=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TDSQLForPG/DbBind/TDSQLForPGODBCDbBind.cs | 44 ++++++- .../TDSQLForPGODBCDbMaintenance.cs | 120 ++++++++++++------ .../TDSQLForPGODBCExpressionContext.cs | 57 ++++++--- .../SqlBuilder/TDSQLForPGODBCInsertBuilder.cs | 4 + .../SqlBuilder/TDSQLForPGODBCUpdateBuilder.cs | 5 + .../Tools/UtilConstants.cs | 9 +- .../Tools/UtilMethods.cs | 79 +++++++++++- 7 files changed, 255 insertions(+), 63 deletions(-) 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..dc69e851d 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