diff --git a/src/Luban.Job.Common/Source/Types/TMap.cs b/src/Luban.Job.Common/Source/Types/TMap.cs index 9753ba7..d7a5917 100644 --- a/src/Luban.Job.Common/Source/Types/TMap.cs +++ b/src/Luban.Job.Common/Source/Types/TMap.cs @@ -5,6 +5,8 @@ namespace Luban.Job.Common.Types { public class TMap : TType { + public bool IsMap => true; + public TType KeyType { get; } public TType ValueType { get; } diff --git a/src/Luban.Job.Db/Source/Defs/TTypeTemplateExtends.cs b/src/Luban.Job.Db/Source/Defs/TTypeTemplateExtends.cs index e6150cf..3b4dec0 100644 --- a/src/Luban.Job.Db/Source/Defs/TTypeTemplateExtends.cs +++ b/src/Luban.Job.Db/Source/Defs/TTypeTemplateExtends.cs @@ -12,6 +12,11 @@ namespace Luban.Job.Db.Defs return type.Apply(DbCsDefineTypeVisitor.Ins); } + public static string DbCsReadonlyDefineType(TType type) + { + return type.Apply(DbCsReadOnlyDefineTypeVisitor.Ins); + } + public static string CsImmutableType(TType type) { return type.Apply(ImmutableTypeName.Ins); diff --git a/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs b/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs index 9da45ea..bc3886d 100644 --- a/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs +++ b/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs @@ -43,13 +43,21 @@ namespace Luban.Job.Db.Generate fields = x.fields hierarchy_fields = x.hierarchy_fields is_abstract_type = x.is_abstract_type + readonly_name = ""IReadOnly"" + name }} using Bright.Serialization; namespace {{x.namespace_with_top_module}} { + +public interface {{readonly_name}} {{if parent_def_type}}: IReadOnly{{x.parent}} {{end}} +{ + {{~ for field in fields~}} + {{db_cs_readonly_define_type field.ctype}} {{field.cs_style_name}} {get;} + {{~end~}} +} -public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Transaction.TxnBeanBase {{end}}, Bright.Transaction.IUnsafeBean +public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Transaction.TxnBeanBase {{end}}, {{readonly_name}} , Bright.Transaction.IUnsafeBean { {{~ for field in fields~}} {{if is_abstract_type}}protected{{else}}private{{end}} {{db_cs_define_type field.ctype}} {{field.internal_name}}; @@ -63,6 +71,7 @@ public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.paren } {{~ for field in fields~}} + {{ctype = field.ctype}} {{~if has_setter field.ctype~}} private sealed class {{field.log_type}} : Bright.Transaction.FieldLogger<{{name}}, {{db_cs_define_type field.ctype}}> @@ -142,6 +151,12 @@ public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.paren public {{db_cs_define_type field.ctype}} {{field.cs_style_name}} => {{field.internal_name}}; {{~end~}} + + {{~if ctype.bean || ctype.element_type ~}} + {{db_cs_readonly_define_type ctype}} {{readonly_name}}.{{field.cs_style_name}} => {{field.internal_name}}; + {{~else if ctype.is_map~}} + {{db_cs_readonly_define_type ctype}} {{readonly_name}}.{{field.cs_style_name}} => new Bright.Transaction.Collections.PReadOnlyMap<{{db_cs_readonly_define_type ctype.key_type}}, {{db_cs_readonly_define_type ctype.value_type}}, {{db_cs_define_type ctype.value_type}}>({{field.internal_name}}); + {{~end~}} {{~end~}} {{~if is_abstract_type~}} @@ -273,14 +288,14 @@ public sealed class {{name}} Table.Put(key, value); } - public static {{db_cs_define_type value_ttype}} Select({{db_cs_define_type key_ttype}} key) + public static {{db_cs_readonly_define_type value_ttype}} Select({{db_cs_define_type key_ttype}} key) { return Table.Select(key); } - public static ValueTask<{{db_cs_define_type value_ttype}}> SelectAsync({{db_cs_define_type key_ttype}} key) + public static ValueTask<{{db_cs_readonly_define_type value_ttype}}> SelectAsync({{db_cs_define_type key_ttype}} key) { - return Table.SelectAsync<{{db_cs_define_type value_ttype}}>(key); + return Table.SelectAsync<{{db_cs_readonly_define_type value_ttype}}>(key); } } } diff --git a/src/Luban.Job.Db/Source/TypeVisitors/DbCsReadOnlyDefineTypeVisitor.cs b/src/Luban.Job.Db/Source/TypeVisitors/DbCsReadOnlyDefineTypeVisitor.cs new file mode 100644 index 0000000..4efac45 --- /dev/null +++ b/src/Luban.Job.Db/Source/TypeVisitors/DbCsReadOnlyDefineTypeVisitor.cs @@ -0,0 +1,36 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; + +namespace Luban.Job.Db.TypeVisitors +{ + class DbCsReadOnlyDefineTypeVisitor : DecoratorFuncVisitor + { + public static DbCsReadOnlyDefineTypeVisitor Ins { get; } = new DbCsReadOnlyDefineTypeVisitor(); + + + public override string DoAccept(TType type) + { + return type.Apply(CsDefineTypeName.Ins); + } + + public override string Accept(TBean type) + { + return $"{type.Bean.NamespaceWithTopModule}.IReadOnly{type.Bean.Name}"; + } + + public override string Accept(TList type) + { + return $"System.Collections.Generic.IReadOnlyList<{type.ElementType.Apply(this)}>"; + } + + public override string Accept(TSet type) + { + return $"System.Collections.Generic.IReadOnlySet<{type.ElementType.Apply(this)}>"; + } + + public override string Accept(TMap type) + { + return $"System.Collections.Generic.IReadOnlyDictionary<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>"; + } + } +}