【特性】非多态bean类型也支持可空。bean的bin输出模式下的格式与其他原生类型一致(强迫先bool表示是否为,再读取类型字段),也调整excel识别非多态bean类型的办法。

main
walon 2021-06-29 19:02:46 +08:00
parent 9e32c2f4fd
commit a471f13488
15 changed files with 80 additions and 31 deletions

Binary file not shown.

View File

@ -185,6 +185,16 @@
</bean>
<table name="TbMultiRowTitle" value="MultiRowTitle" input="test/multi_level_title.xlsx"/>
<bean name="TestNull">
<var name="id" type="int"/>
<var name="x1" type="int?"/>
<var name="x2" type="DemoEnum?"/>
<var name="x3" type="DemoType1?"/>
<var name="x4" type="DemoDynamic?"/>
</bean>
<table name="TbTestNull" value="TestNull" input="test/test_null.xlsx"/>
<!--table name="TbDynamic" value="DemoDynamic" input="多态数据源"/-->
<module name="login">
@ -199,4 +209,5 @@
<var name="value" type="string"/>
</bean>
<table name="TbTestTag" value="TestTag" input="test/tag_datas"/>
</module>

View File

@ -20,4 +20,8 @@
<ProjectReference Include="..\Luban.Job.Common\Luban.Job.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Source\DataCreators\" />
</ItemGroup>
</Project>

View File

@ -94,12 +94,12 @@ namespace Luban.Job.Cfg.DataVisitors
var bean = type.Type;
if (bean.IsAbstractType)
{
// null 时特殊处理
if (type.ImplType == null)
{
x.WriteInt(0);
return;
}
// 调整设计后多态bean不会为空
//if (type.ImplType == null)
//{
// x.WriteInt(0);
// return;
//}
x.WriteInt(type.ImplType.Id);
}
int index = -1;
@ -111,8 +111,7 @@ namespace Luban.Job.Cfg.DataVisitors
{
continue;
}
if (defField.CType.Apply(NeedMarshalBoolPrefixVisitor.Ins))
if (defField.CType.IsNullable)
{
if (field != null)
{

View File

@ -113,7 +113,7 @@ namespace Luban.Job.Cfg.DataVisitors
public void Accept(DBean record, DefAssembly assembly)
{
if (record.ImplType == null)
if (record == null)
{
return;
}

View File

@ -12,6 +12,9 @@ namespace Luban.Job.Cfg.Defs
{
public const string TYPE_NAME_KEY = "__type__";
public const string BEAN_NULL_STR = "{null}";
public const string BEAN_NOT_NULL_STR = "{}";
public string Alias { get; }

View File

@ -87,7 +87,7 @@ namespace Luban.Job.Cfg.Defs
{
var name = field.CsStyleName;
TType type = field.CType;
if (field.CType.Apply(NeedMarshalBoolPrefixVisitor.Ins))
if (field.CType.IsNullable)
{
return $"{{ var _exists bool; if _exists, err = {bufName}.ReadBool(); err != nil {{ return }}; if _exists {{ if _v.{name}, err = {type.Apply(GoDeserializeVisitor.Ins, bufName)}; err != nil {{ return }} }} }}";
}

View File

@ -233,7 +233,6 @@ namespace {{x.top_module}}
if (!_buf.readInt(id)) return false;
switch (id)
{
case 0 : { _out = nullptr; return true; }
{{- for child in type.hierarchy_not_abstract_children}}
case {{child.cpp_full_name}}::ID: { _out = new {{child.cpp_full_name}}(); if (_out->deserialize(_buf)) { return true; } else { delete _out; _out = nullptr; return false;} }
{{-end}}

View File

@ -59,7 +59,6 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
{{if x.is_abstract_type}}
switch (_buf.ReadInt())
{
case 0 : return null;
{{- for child in x.hierarchy_not_abstract_children}}
case {{child.full_name}}.ID: return new {{child.full_name}}(_buf);
{{-end}}

View File

@ -327,9 +327,13 @@ namespace Luban.Job.Cfg.TypeVisitors
if (originBean.IsAbstractType)
{
string subType = x.Read().ToString();
if (subType.ToLower().Trim() == "null")
if (subType.ToLower().Trim() == DefBean.BEAN_NULL_STR)
{
return new DBean(originBean, null, null);
if (!type.IsNullable)
{
throw new InvalidExcelDataException($"type:{type.Bean.FullName}不是可空类型. 不能为空");
}
return null;
}
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
@ -341,6 +345,18 @@ namespace Luban.Job.Cfg.TypeVisitors
}
else
{
if (type.IsNullable)
{
string subType = x.Read().ToString().Trim();
if (subType == DefBean.BEAN_NULL_STR)
{
return null;
}
else if (subType != DefBean.BEAN_NOT_NULL_STR)
{
throw new Exception($"type:{type.Bean.FullName} 可空标识 不合法(只能为{DefBean.BEAN_NOT_NULL_STR}或{DefBean.BEAN_NULL_STR})");
}
}
return new DBean(originBean, originBean, CreateBeanFields(originBean, x, ass));
}
}

View File

@ -2,6 +2,7 @@ using Luban.Common.Utils;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.TypeVisitors;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
@ -175,15 +176,20 @@ namespace Luban.Job.Cfg.TypeVisitors
return list;
}
public DType Accept(TBean type, Sheet.NamedRow row, bool multirow, bool nullable)
{
var originBean = (DefBean)type.Bean;
if (originBean.IsAbstractType)
{
string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim();
if (subType.ToLower() == "null")
if (subType.ToLower() == DefBean.BEAN_NULL_STR)
{
return new DBean(originBean, null, null);
if (!type.IsNullable)
{
throw new Exception($"type:{type} 不是可空类型 {type.Bean.FullName}? , 不能为空");
}
return null;
}
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
@ -195,6 +201,19 @@ namespace Luban.Job.Cfg.TypeVisitors
}
else
{
if (type.IsNullable)
{
string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim();
if (subType == DefBean.BEAN_NULL_STR)
{
return null;
}
else if (subType != DefBean.BEAN_NOT_NULL_STR)
{
throw new Exception($"type:{type.Bean.FullName} {DefBean.TYPE_NAME_KEY} 不合法(只能为{DefBean.BEAN_NOT_NULL_STR}或{DefBean.BEAN_NULL_STR})");
}
}
return new DBean(originBean, originBean, CreateBeanFields(originBean, row));
}
}

View File

@ -13,7 +13,7 @@ namespace Luban.Job.Common.Defs
public static bool NeedMarshalBoolPrefix(TType type)
{
return type.Apply(NeedMarshalBoolPrefixVisitor.Ins);
return type.IsNullable;
}
public static bool CsNeedInit(TType type)

View File

@ -19,9 +19,9 @@ namespace Luban.Job.Common.TypeVisitors
}
}
public override string Accept(TBean type, string bufName, string fieldName)
{
return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName);
}
//public override string Accept(TBean type, string bufName, string fieldName)
//{
// return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName);
//}
}
}

View File

@ -2,13 +2,13 @@ using Luban.Job.Common.Types;
namespace Luban.Job.Common.TypeVisitors
{
public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor<bool>
{
public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor();
//public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor<bool>
//{
// //public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor();
public override bool DoAccept(TType type)
{
return type.IsNullable && !(type is TBean bean && bean.IsDynamic);
}
}
// public override bool DoAccept(TType type)
// {
// return type.IsNullable && !(type is TBean bean && bean.IsDynamic);
// }
//}
}

View File

@ -10,8 +10,7 @@ namespace Luban.Job.Common.Types
public T GetBeanAs<T>() where T : DefBeanBase => (T)Bean;
// TODO bean 允许指定是否可空
public TBean(DefBeanBase defBean, bool isNullable) : base(defBean.IsAbstractType)
public TBean(DefBeanBase defBean, bool isNullable) : base(isNullable)
{
this.Bean = defBean;
}