suppourt ndty orm

This commit is contained in:
gbase_contributors
2021-12-15 14:48:26 +08:00
parent 563f695d09
commit fdcb76eaa2
53 changed files with 12244 additions and 187 deletions

View File

@ -61,6 +61,12 @@ namespace FreeSql
/// 注意:该类型不提供 DbFirst/CodeFirst 功能
/// </summary>
Custom,
ClickHouse
ClickHouse,
/// <summary>
/// 天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现
/// </summary>
GBase
}
}

View File

@ -471,6 +471,15 @@ namespace FreeSql
expContext.Result = $"list({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})";
return null;
}
public static string StringJoinGBaseWmConcatText(object column, object delimiter)
{
if (expContext.ParsedContent["delimiter"] == "','")
expContext.Result = $"wm_concat_text({expContext.ParsedContent["column"]})";
else
throw new NotImplementedException("GBase 暂时不支持逗号以外的分割符");
//expContext.Result = $"replace(wm_concat_text({expContext.ParsedContent["column"]}), ',', {expContext.ParsedContent["delimiter"]})";
return null;
}
#endregion
}
}

View File

@ -418,9 +418,25 @@ public static partial class FreeSqlGlobalExtensions
if (select._orm.CodeFirst.IsSyncStructureToLower) cteName = cteName.ToLower();
if (select._orm.CodeFirst.IsSyncStructureToUpper) cteName = cteName.ToUpper();
switch (select._orm.Ado.DataType) //MySql5.6
switch (select._orm.Ado.DataType)
{
case DataType.MySql:
case DataType.GBase:
//select t.parentid, t.subid, level
//from a_test t
//start with subid = '7'
//connect by prior subid = parentid;
var gbsb = new StringBuilder();
var gbsbWhere = select._where.ToString();
select._where.Clear();
if (gbsbWhere.StartsWith(" AND ")) gbsbWhere = gbsbWhere.Remove(0, 5);
gbsb.Append(select._tosqlAppendContent).Append(" \r\nstart with ").Append(gbsbWhere).Append(" \r\nconnect by prior ");
if (up) gbsb.Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)).Append(" = ").Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name));
else gbsb.Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.Columns[0].Attribute.Name)).Append(" = ").Append("a.").Append(select._commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name));
var gbswstr = gbsb.ToString();
gbsb.Clear();
select.AsAlias((_, old) => $"{old} {gbswstr}");
return select;
case DataType.MySql: //MySql5.6
case DataType.OdbcMySql:
var mysqlConnectionString = select._orm.Ado?.ConnectionString ?? select._connection?.ConnectionString ?? "";
if (_dicMySqlVersion.TryGetValue(mysqlConnectionString, out var mysqlVersion) == false)
@ -580,6 +596,7 @@ JOIN {select._commonUtils.QuoteSqlName(tb.DbName)} a ON cte_tbc.cte_id = a.{sele
case DataType.OdbcOracle:
case DataType.Dameng: //递归 WITH 子句必须具有列别名列表
case DataType.OdbcDameng:
case DataType.GBase:
nsselsb.Append($"(cte_level, {(pathSelector == null ? "" : "cte_path, ")}{sql2Field.Replace("wct2.", "")})");
break;
}

View File

@ -661,6 +661,11 @@
注意:该类型不提供 DbFirst/CodeFirst 功能
</summary>
</member>
<member name="F:FreeSql.DataType.GBase">
<summary>
天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现
</summary>
</member>
<member name="M:FreeSql.AdoNetExtensions.GetIFreeSql(System.Data.IDbConnection)">
<summary>
获取 IDbConnection 对应的 IFreeSql 实例
@ -3191,177 +3196,6 @@
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteConnectTestAsync(System.Int32,System.Threading.CancellationToken)">
<summary>
测试数据库是否连接正确,本方法执行如下命令:<para></para>
MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1<para></para>
Oracle: SELECT 1 FROM dual<para></para>
</summary>
<param name="commandTimeout">命令超时设置(秒)</param>
<param name="cancellationToken"></param>
<returns>true: 成功, false: 失败</returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询若使用读写分离查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
</summary>
<param name="readerHander"></param>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="readerHander"></param>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User, Address&gt;("select * from user where age > @age; select * from address", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="E:FreeSql.IAop.ParseExpression">
<summary>
可自定义解析表达式
@ -4256,12 +4090,6 @@
<param name="timeout">超时</param>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.GetAsync">
<summary>
获取资源
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
<summary>
使用完毕后,归还资源
@ -4332,12 +4160,6 @@
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnGetAsync(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
归还对象给对象池的时候触发

View File

@ -270,6 +270,11 @@ namespace FreeSql
if (type == null) throwNotFind("FreeSql.Provider.ClickHouse.dll", "FreeSql.ClickHouse.ClickHouseProvider<>");
break;
case DataType.GBase:
type = Type.GetType("FreeSql.GBase.GBaseProvider`1,FreeSql.Provider.GBase")?.MakeGenericType(typeof(TMark));
if (type == null) throwNotFind("FreeSql.Provider.GBase.dll", "FreeSql.GBase.GBaseProvider<>");
break;
default: throw new Exception("未指定 UseConnectionString 或者 UseConnectionFactory");
}
}

View File

@ -1011,6 +1011,7 @@ namespace FreeSql.Internal
case DataType.OdbcOracle:
case DataType.Dameng:
case DataType.OdbcDameng:
case DataType.GBase:
break;
default:
fsqlSelect0._limit = 1; //#462 ORACLE rownum <= 2 会影响索引变慢
@ -1305,6 +1306,7 @@ namespace FreeSql.Internal
{
case DataType.MySql:
case DataType.OdbcMySql:
case DataType.GBase:
if (exp3.Method.Name == "ToList")
return $"( SELECT * FROM ({sqlFirst.Replace(" \r\n", " \r\n ")}) ftblmt50 )";
break;
@ -1877,6 +1879,7 @@ namespace FreeSql.Internal
{
if (obj == null) return "NULL";
var paramName = $"exp_{dbParams.Count}";
if (_common._orm?.Ado.DataType == DataType.GBase) paramName = "?";
var parm = _common.AppendParamter(dbParams, paramName, mapColumn,
mapType ?? mapColumn?.Attribute.MapType ?? obj?.GetType(), mapType == null ? obj : Utils.GetDataReaderValue(mapType, obj));
return _common.QuoteParamterName(paramName);

View File

@ -111,6 +111,7 @@ namespace FreeSql.Internal.CommonProvider
{
case DataType.Oracle:
case DataType.OdbcOracle:
case DataType.GBase:
ExecuteNonQuery(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout);
return true;
case DataType.Firebird:

View File

@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider
{
case DataType.Oracle:
case DataType.OdbcOracle:
case DataType.GBase:
await ExecuteNonQueryAsync(null, null, CommandType.Text, " SELECT 1 FROM dual", commandTimeout, null, cancellationToken);
return true;
case DataType.Firebird:
@ -476,7 +477,7 @@ namespace FreeSql.Internal.CommonProvider
public Task ExecuteReaderAsync(Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken);
public Task ExecuteReaderAsync(DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken);
public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken);
public async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, int, Task> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default)
async public Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, int, Task> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(cmdText)) return;
var dt = DateTime.Now;

View File

@ -182,6 +182,7 @@ namespace FreeSql.Internal.CommonProvider
case DataType.Oracle:
case DataType.OdbcDameng:
case DataType.Dameng:
case DataType.GBase:
sb.Append(" FROM dual");
break;
case DataType.Firebird:

View File

@ -352,6 +352,7 @@ namespace FreeSql.Internal.CommonProvider
case DataType.Oracle:
case DataType.OdbcOracle:
case DataType.Firebird:
case DataType.GBase:
break;
default:
_select = "SELECT ";
@ -407,6 +408,7 @@ namespace FreeSql.Internal.CommonProvider
case DataType.Oracle:
case DataType.OdbcOracle:
case DataType.Firebird:
case DataType.GBase:
break;
default:
var beforeSql = this._select;
@ -440,6 +442,7 @@ namespace FreeSql.Internal.CommonProvider
case DataType.Oracle:
case DataType.OdbcOracle:
case DataType.Firebird:
case DataType.GBase:
break;
default:
var beforeSql = this._select;
@ -755,6 +758,7 @@ namespace FreeSql.Internal.CommonProvider
break;
case DataType.Sqlite:
break;
case DataType.GBase:
case DataType.ShenTong: //神通测试中发现,不支持 nowait
_tosqlAppendContent = $"{_tosqlAppendContent} for update";
break;

View File

@ -159,6 +159,7 @@ namespace FreeSql.Internal.CommonProvider
case DataType.OdbcOracle:
case DataType.Dameng:
case DataType.OdbcDameng: //Oracle、Dameng 分组时,嵌套分页
case DataType.GBase:
isNestedPageSql = true;
break;
default:

View File

@ -204,6 +204,36 @@ namespace FreeSql.Internal
// else if (Math.Abs(dt.Subtract(DateTime.UtcNow).TotalSeconds) < 60)
// col.DbDefaultValue = common.NowUtc;
//}
if (common._orm.Ado.DataType == DataType.GBase)
{
if (colattr.IsIdentity == true)
{
var colType = col.CsType.NullableTypeOrThis();
if (colType == typeof(int) || colType == typeof(uint))
colattr.DbType = "SERIAL";
else if (colType == typeof(long) || colType == typeof(ulong))
colattr.DbType = "SERIAL8";
}
if (colattr.MapType.NullableTypeOrThis() == typeof(DateTime))
{
if (colattr._Precision == null)
{
colattr.DbType = "DATETIME YEAR TO FRACTION(3)";
colattr.Precision = 3;
col.DbPrecision = 3;
}
else if (colattr._Precision == 0)
{
colattr.DbType = "DATETIME YEAR TO SECOND";
}
else if (colattr._Precision > 0)
{
colattr.DbType = $"DATETIME YEAR TO FRACTION({colattr.Precision})";
col.DbPrecision = (byte)colattr.Precision;
}
}
}
if (colattr.ServerTime != DateTimeKind.Unspecified && new[] { typeof(DateTime), typeof(DateTimeOffset) }.Contains(colattr.MapType.NullableTypeOrThis()))
{
var commonNow = common.Now;
@ -283,6 +313,10 @@ namespace FreeSql.Internal
if (strlen < 0) colattr.DbType = "BLOB SUB_TYPE 1";
else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})");
break;
case DataType.GBase:
if (strlen < 0) colattr.DbType = "TEXT";
else colattr.DbType = Regex.Replace(colattr.DbType, charPatten, $"$1({strlen})");
break;
}
}
if (colattr.MapType == typeof(byte[]) && colattr.IsVersion == true) colattr.StringLength = 16;
@ -330,6 +364,9 @@ namespace FreeSql.Internal
case DataType.Firebird:
colattr.DbType = "BLOB";
break;
case DataType.GBase:
colattr.DbType = "BYTE";
break;
}
}
if (colattr.MapType.NullableTypeOrThis() == typeof(decimal) && (colattr.Precision > 0 || colattr.Scale > 0))
@ -1352,6 +1389,7 @@ namespace FreeSql.Internal
switch (orm.Ado.DataType)
{
case DataType.Dameng: //OdbcDameng 不会报错
case DataType.GBase:
if (dr.IsDBNull(index)) return null;
break;
}