【特性】非多态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> </bean>
<table name="TbMultiRowTitle" value="MultiRowTitle" input="test/multi_level_title.xlsx"/> <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="多态数据源"/--> <!--table name="TbDynamic" value="DemoDynamic" input="多态数据源"/-->
<module name="login"> <module name="login">
@ -199,4 +209,5 @@
<var name="value" type="string"/> <var name="value" type="string"/>
</bean> </bean>
<table name="TbTestTag" value="TestTag" input="test/tag_datas"/> <table name="TbTestTag" value="TestTag" input="test/tag_datas"/>
</module> </module>

View File

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

View File

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

View File

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

View File

@ -12,6 +12,9 @@ namespace Luban.Job.Cfg.Defs
{ {
public const string TYPE_NAME_KEY = "__type__"; 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; } public string Alias { get; }

View File

@ -87,7 +87,7 @@ namespace Luban.Job.Cfg.Defs
{ {
var name = field.CsStyleName; var name = field.CsStyleName;
TType type = field.CType; 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 }} }} }}"; 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; if (!_buf.readInt(id)) return false;
switch (id) switch (id)
{ {
case 0 : { _out = nullptr; return true; }
{{- for child in type.hierarchy_not_abstract_children}} {{- 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;} } 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}} {{-end}}

View File

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

View File

@ -327,9 +327,13 @@ namespace Luban.Job.Cfg.TypeVisitors
if (originBean.IsAbstractType) if (originBean.IsAbstractType)
{ {
string subType = x.Read().ToString(); 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); string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType); DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
@ -341,6 +345,18 @@ namespace Luban.Job.Cfg.TypeVisitors
} }
else 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)); 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.Datas;
using Luban.Job.Cfg.DataSources.Excel; using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.TypeVisitors;
using Luban.Job.Common.Types; using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors; using Luban.Job.Common.TypeVisitors;
using System; using System;
@ -175,15 +176,20 @@ namespace Luban.Job.Cfg.TypeVisitors
return list; return list;
} }
public DType Accept(TBean type, Sheet.NamedRow row, bool multirow, bool nullable) public DType Accept(TBean type, Sheet.NamedRow row, bool multirow, bool nullable)
{ {
var originBean = (DefBean)type.Bean; var originBean = (DefBean)type.Bean;
if (originBean.IsAbstractType) if (originBean.IsAbstractType)
{ {
string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim(); 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); string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType); DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
@ -195,6 +201,19 @@ namespace Luban.Job.Cfg.TypeVisitors
} }
else 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)); 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) public static bool NeedMarshalBoolPrefix(TType type)
{ {
return type.Apply(NeedMarshalBoolPrefixVisitor.Ins); return type.IsNullable;
} }
public static bool CsNeedInit(TType type) 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) //public override string Accept(TBean type, string bufName, string fieldName)
{ //{
return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName); // return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName);
} //}
} }
} }

View File

@ -2,13 +2,13 @@ using Luban.Job.Common.Types;
namespace Luban.Job.Common.TypeVisitors namespace Luban.Job.Common.TypeVisitors
{ {
public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor<bool> //public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor<bool>
{ //{
public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor(); // //public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor();
public override bool DoAccept(TType type) // public override bool DoAccept(TType type)
{ // {
return type.IsNullable && !(type is TBean bean && bean.IsDynamic); // 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; public T GetBeanAs<T>() where T : DefBeanBase => (T)Bean;
// TODO bean 允许指定是否可空 public TBean(DefBeanBase defBean, bool isNullable) : base(isNullable)
public TBean(DefBeanBase defBean, bool isNullable) : base(defBean.IsAbstractType)
{ {
this.Bean = defBean; this.Bean = defBean;
} }