Clickhouse Array泛型映射功能添加

This commit is contained in:
d4ilys 2023-11-21 11:20:54 +08:00
parent 84f2ab4d41
commit 322332cf73
3 changed files with 106 additions and 16 deletions

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -20,7 +21,7 @@ namespace FreeSql.Tests.ClickHouse
_fsql = new FreeSqlBuilder().UseConnectionString(DataType.ClickHouse, _fsql = new FreeSqlBuilder().UseConnectionString(DataType.ClickHouse,
"Host=192.168.1.123;Port=8123;Database=test;Compress=True;Min Pool Size=1") "Host=192.168.1.123;Port=8123;Database=test;Compress=True;Min Pool Size=1")
.UseMonitorCommand(cmd => _output.WriteLine($"线程:{cmd.CommandText}\r\n")) .UseMonitorCommand(cmd => _output.WriteLine($"线程:{cmd.CommandText}\r\n"))
.UseNoneCommandParameter(false) .UseNoneCommandParameter(true)
.Build(); .Build();
} }
@ -106,6 +107,15 @@ namespace FreeSql.Tests.ClickHouse
{ {
var list = _fsql.Select<BoolMappingTest>().ToList(); var list = _fsql.Select<BoolMappingTest>().ToList();
} }
/// <summary>
/// 测试Array类型映射
/// </summary>
[Fact]
public void ArrayBoolMappingSync()
{
_fsql.CodeFirst.SyncStructure(typeof(ArrayMappingTest));
}
} }
[Table(Name = "table_test_bool")] [Table(Name = "table_test_bool")]
@ -122,4 +132,25 @@ namespace FreeSql.Tests.ClickHouse
[Column(Name = "is_enable")] public bool? IsEnable { get; set; } [Column(Name = "is_enable")] public bool? IsEnable { get; set; }
} }
[Table(Name = "table_test_array")]
public class ArrayMappingTest
{
[Column(Name = "name", IsPrimary = true)]
public string Name { get; set; }
[Column(Name = "tags1")] public IEnumerable<string> Tags1 { get; set; }
[Column(Name = "tags2")] public IList<string> Tags2 { get; set; }
[Column(Name = "tags3")] public List<string> Tags3 { get; set; }
[Column(Name = "tags4")] public ArrayList Tags4 { get; set; }
[Column(Name = "tags5")] public Array Tags5 { get; set; }
[Column(Name = "tags6")] public List<int> Tags6 { get; set; }
[Column(Name = "tags7")] public IEnumerable<bool> Tags7 { get; set; }
}
} }

View File

@ -29,6 +29,11 @@
测试bool类型查询 测试bool类型查询
</summary> </summary>
</member> </member>
<member name="M:FreeSql.Tests.ClickHouse.ClickHouseTest3.ArrayBoolMappingSync">
<summary>
测试Array类型映射
</summary>
</member>
<member name="T:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01"> <member name="T:FreeSql.Tests.ClickHouse.CollectDataEntityUpdate01">
<summary> <summary>
实时数据 实时数据

View File

@ -1,6 +1,7 @@
using FreeSql.Internal; using FreeSql.Internal;
using FreeSql.Internal.Model; using FreeSql.Internal.Model;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
@ -50,7 +51,8 @@ namespace FreeSql.ClickHouse
{ typeof(float?).FullName, CsToDb.New(DbType.Single, "Float32", "Nullable(Float32)", false, true, null) }, { typeof(float?).FullName, CsToDb.New(DbType.Single, "Float32", "Nullable(Float32)", false, true, null) },
{ {
typeof(decimal).FullName, 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, typeof(decimal?).FullName,
@ -75,16 +77,68 @@ namespace FreeSql.ClickHouse
{ typeof(Guid?).FullName, CsToDb.New(DbType.String, "String", "Nullable(String)", false, true, null) }, { typeof(Guid?).FullName, CsToDb.New(DbType.String, "String", "Nullable(String)", false, true, null) },
}; };
public override DbInfoResult GetDbInfo(Type type) public override DbInfoResult GetDbInfo(Type type)
{ {
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) if (_dicCsToDb.TryGetValue(type.FullName, out var trydc))
return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable,
trydc.defaultValue); trydc.defaultValue);
if (type.IsArray)
return null; //判断是否是集合
var isCollection = IsCollection(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; return null;
} }
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) protected override string GetComparisonDDLStatements(params TypeAndName[] objects)
{ {
Object<DbConnection> conn = null; Object<DbConnection> conn = null;
@ -299,7 +353,8 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
//添加列 //添加列
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])) 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); .Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" &&
tbcol.Attribute.IsIdentity == false) tbcol.Attribute.IsIdentity == false)
@ -483,7 +538,7 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
var before = new Aop.CommandBeforeEventArgs(cmd); 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; Exception afterException = null;
try try
{ {
@ -496,7 +551,8 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
} }
finally 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));
} }
} }
} }
@ -511,12 +567,13 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
{ {
if (isPrimary) if (isPrimary)
{ {
if (dbType.Contains("Nullable")) if (dbType.Contains("Nullable"))
return dbType.Replace("Nullable(", "") return dbType.Replace("Nullable(", "")
.Replace(")", "") .Replace(")", "")
.Replace(" NOT NULL", ""); .Replace(" NOT NULL", "");
return dbType; return dbType;
} }
return dbType.Replace(" NOT NULL", ""); return dbType.Replace(" NOT NULL", "");
} }
@ -524,6 +581,9 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
string CkIntAdapter(string dbType) string CkIntAdapter(string dbType)
{ {
var result = dbType; var result = dbType;
if (dbType.Contains("Array"))
return dbType;
if (dbType.ToLower().Contains("int64")) if (dbType.ToLower().Contains("int64"))
{ {
if (dbType.Contains("Nullable")) if (dbType.Contains("Nullable"))
@ -578,13 +638,7 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
internal class ClickHouseTableIndex internal class ClickHouseTableIndex
{ {
public string name public string name { get; set; }
{ public string expr { get; set; }
get; set;
}
public string expr
{
get; set;
}
} }
} }