Skip to content

Commit

Permalink
Merge pull request #1676 from d4ilys/master
Browse files Browse the repository at this point in the history
Clickhouse - Array/Bool数据类型适配
  • Loading branch information
2881099 authored Nov 30, 2023
2 parents 02ffe93 + 9608d43 commit 175011a
Show file tree
Hide file tree
Showing 10 changed files with 783 additions and 55 deletions.
4 changes: 4 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
using System.ComponentModel.DataAnnotations;
using FreeSql.DataAnnotations;
using Xunit;
using Xunit.Abstractions;

namespace FreeSql.Tests.ClickHouse
{
public class ClickHouseTest2
{


private static IFreeSql fsql = new FreeSqlBuilder().UseConnectionString(DataType.ClickHouse,
"Host=127.0.0.1;Port=8123;Database=test;Compress=True;Min Pool Size=1")
.UseMonitorCommand(cmd => Console.WriteLine($"线程:{cmd.CommandText}\r\n"))
Expand All @@ -29,6 +32,7 @@ public void Issuse1587Test()
{
fsql.CodeFirst.SyncStructure(typeof(PositionInfoModel));
}

[Fact]
public void Issuse1587TestOnePrimary()
{
Expand Down
456 changes: 456 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest3.cs

Large diffs are not rendered by default.

122 changes: 122 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected string AddslashesIEnumerable(object param, Type mapType, ColumnInfo ma
sb.Append(AddslashesProcessParam(z, mapType, mapColumn));
}

return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "[").Append("]").ToString();
}

public static bool IsFromSlave(string cmdText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public override object AddslashesProcessParam(object param, Type mapType, Column
param = Utils.GetDataReaderValue(mapType, param);

if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
return (bool)param; //不需要转0/1
else if (param is string)
return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠
else if (param is char)
Expand Down
117 changes: 95 additions & 22 deletions Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using FreeSql.Internal;
using FreeSql.Internal.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
Expand All @@ -23,8 +24,8 @@ public ClickHouseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpressi

static Dictionary<string, CsToDb<DbType>> _dicCsToDb = new Dictionary<string, CsToDb<DbType>>()
{
{ typeof(bool).FullName, CsToDb.New(DbType.SByte, "Int8", "Int8", null, false, false) },
{ typeof(bool?).FullName, CsToDb.New(DbType.SByte, "Int8", "Nullable(Int8)", null, true, null) },
{ typeof(bool).FullName, CsToDb.New(DbType.SByte, "Bool", "Bool", null, false, false) },
{ typeof(bool?).FullName, CsToDb.New(DbType.SByte, "Bool", "Nullable(Bool)", null, true, null) },

{ typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "Int8", "Int8", false, false, 0) },
{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "Int8", "Nullable(Int8)", false, true, null) },
Expand All @@ -50,7 +51,8 @@ public ClickHouseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpressi
{ typeof(float?).FullName, CsToDb.New(DbType.Single, "Float32", "Nullable(Float32)", false, true, null) },
{
typeof(decimal).FullName,
CsToDb.New(DbType.Decimal, "Decimal(38, 19)", "Decimal(38, 19)", false, false, 0) //Nullable(Decimal(38, 19))
CsToDb.New(DbType.Decimal, "Decimal(38, 19)", "Decimal(38, 19)", false, false,
0) //Nullable(Decimal(38, 19))
},
{
typeof(decimal?).FullName,
Expand All @@ -75,17 +77,84 @@ public ClickHouseCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpressi
{ typeof(Guid?).FullName, CsToDb.New(DbType.String, "String", "Nullable(String)", false, true, null) },
};


public override DbInfoResult GetDbInfo(Type type)
{
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc))
return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable,
trydc.defaultValue);
if (type.IsArray)
return null;

//判断是否是集合
var isCollection = IsArray(type);
if (isCollection.Item1)
{
var genericType = isCollection.Item2;
var genericTypeName = genericType?.FullName;
var tryGetValue = _dicCsToDb.TryGetValue(genericTypeName, out var value);
if (tryGetValue)
{
var arrayDbType = $"Array({value.dbtype})";
var defaultArray = new ArrayList(0);
return new DbInfoResult(Convert.ToInt32(DbType.Object), arrayDbType, arrayDbType, false,defaultArray);
}

}
return null;
}

protected override string GetComparisonDDLStatements(params TypeSchemaAndName[] objects)

private Tuple<bool, Type> IsArray(Type type)
{
var flag = false;
Type resultType = null;

if (type.IsArray)
{
flag = true;
resultType = type.GetElementType();
}

return new Tuple<bool, Type>(flag, resultType);
}

private Tuple<bool, Type> IsCollection(Type type)
{
var flag = false;
Type resultType = null;
var interfaces = type.GetInterfaces();

if (interfaces.Any(t => t.Name == "IList"))
flag = true;

if (interfaces.Any(t => t.Name == "ICollection"))
flag = true;

if (interfaces.Any(t => t.Name == "IEnumerable"))
flag = true;

if (type.Name == "Array")
{
flag = true;
resultType = typeof(string);
}

if (type.Name == "ArrayList")
{
flag = true;
resultType = typeof(string);
}

//是否是泛型
if (type.GetGenericArguments().Any())
{
var first = type.GetGenericArguments().First();
resultType = first;
}

return new Tuple<bool, Type>(flag, resultType);
}

protected override string GetComparisonDDLStatements(params TypeAndName[] objects)
{
Object<DbConnection> conn = null;
string database = null;
Expand All @@ -100,11 +169,11 @@ protected override string GetComparisonDDLStatements(params TypeSchemaAndName[]
{
if (sb.Length > 0)
sb.Append("\r\n");
var tb = obj.tableSchema;
var tb = _commonUtils.GetTableByEntity(obj.entityType);
if (tb == null)
throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.tableSchema.Type.FullName));
throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.entityType.FullName));
if (tb.Columns.Any() == false)
throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.tableSchema.Type.FullName));
throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.entityType.FullName));
var tbname = _commonUtils.SplitTableName(tb.DbName);
if (tbname?.Length == 1)
tbname = new[] { database, tbname[0] };
Expand Down Expand Up @@ -299,7 +368,8 @@ from system.columns a

//添加列
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1]))
.Append(" ADD Column ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ")
.Append(" ADD Column ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name))
.Append(" ")
.Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" &&
tbcol.Attribute.IsIdentity == false)
Expand Down Expand Up @@ -483,7 +553,7 @@ object LocalExecuteScalar(string db, string sql)
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
Expand All @@ -496,7 +566,8 @@ object LocalExecuteScalar(string db, string sql)
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm,
new Aop.CommandAfterEventArgs(before, afterException, null));
}
}
}
Expand All @@ -511,19 +582,27 @@ string CkNullableAdapter(string dbType, bool isPrimary)
{
if (isPrimary)
{
if (dbType.Contains("Nullable"))
return dbType.Replace("Nullable(", "")
if (dbType.Contains("Nullable"))
{
var res = dbType.Replace("Nullable(", "")
.Replace(")", "")
.Replace(" NOT NULL", "");
return res;
}

return dbType;
}

return dbType.Replace(" NOT NULL", "");
}


string CkIntAdapter(string dbType)
{
var result = dbType;
if (dbType.Contains("Array"))
return dbType;

if (dbType.ToLower().Contains("int64"))
{
if (dbType.Contains("Nullable"))
Expand Down Expand Up @@ -578,13 +657,7 @@ public override int ExecuteDDLStatements(string ddl)

internal class ClickHouseTableIndex
{
public string name
{
get; set;
}
public string expr
{
get; set;
}
public string name { get; set; }
public string expr { get; set; }
}
}
Loading

0 comments on commit 175011a

Please sign in to comment.