From 788b054a0657147f9a490e75d1d0edc76fb699db Mon Sep 17 00:00:00 2001 From: walon Date: Sun, 7 Feb 2021 18:15:25 +0800 Subject: [PATCH] =?UTF-8?q?-=20db=20=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=B1=E5=90=8C=E6=AD=A5=E4=BA=8B=E5=8A=A1=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E4=BA=8B=E5=8A=A1=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=20db=20=E5=AF=B9dynamic=5Fbean=E7=B1=BB=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=9A=84=E5=BA=8F=E5=88=97=E5=8C=96=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=94=99=E8=AF=AF=E7=94=9F=E6=88=90=20BEAN=E7=B1=BB?= =?UTF-8?q?=E5=9E=8Btag=E7=9A=84bug=EF=BC=8C=E6=AD=A3=E7=A1=AE=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E6=98=AFDYNAMIC=5FBEAN=20-=20=E4=BF=AE=E5=A4=8D=20db?= =?UTF-8?q?=20=E5=AF=B9=E4=BA=8E=E5=AE=B9=E5=99=A8=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=9C=AA=E7=94=9F=E6=88=90InitChild?= =?UTF-8?q?renRoot=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=9C=AA=E8=83=BD=E6=AD=A3=E7=A1=AE=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?root=E7=9A=84bug=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/TypeVisitors/TagNameVisitor.cs | 2 +- .../Source/Generate/AsyncCsRender.cs | 322 ++++++++++++++++++ .../Generate/{CsRender.cs => SyncCsRender.cs} | 2 +- src/Luban.Job.Db/Source/JobController.cs | 2 +- .../NeedSetChildrenRootVisitor.cs | 9 +- 5 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 src/Luban.Job.Db/Source/Generate/AsyncCsRender.cs rename src/Luban.Job.Db/Source/Generate/{CsRender.cs => SyncCsRender.cs} (99%) diff --git a/src/Luban.Job.Common/Source/TypeVisitors/TagNameVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/TagNameVisitor.cs index 6bf2cca..ab2d5b0 100644 --- a/src/Luban.Job.Common/Source/TypeVisitors/TagNameVisitor.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/TagNameVisitor.cs @@ -83,7 +83,7 @@ namespace Luban.Job.Common.TypeVisitors public string Accept(TBean type) { - return "BEAN"; + return type.IsDynamic ? "DYNAMIC_BEAN" : "BEAN"; } public string Accept(TArray type) diff --git a/src/Luban.Job.Db/Source/Generate/AsyncCsRender.cs b/src/Luban.Job.Db/Source/Generate/AsyncCsRender.cs new file mode 100644 index 0000000..fabdb18 --- /dev/null +++ b/src/Luban.Job.Db/Source/Generate/AsyncCsRender.cs @@ -0,0 +1,322 @@ +using Luban.Job.Common.Defs; +using Luban.Job.Common.Utils; +using Luban.Job.Db.Defs; +using Scriban; +using System; +using System.Collections.Generic; + +namespace Luban.Job.Db.Generate +{ + class AsyncCsRender + { + public string RenderAny(object o) + { + switch (o) + { + case DefConst c: return Render(c); + case DefEnum e: return Render(e); + case DefBean b: return Render(b); + case DefTable p: return Render(p); + default: throw new Exception($"unknown render type:{o}"); + } + } + + public string Render(DefConst c) + { + return RenderUtil.RenderCsConstClass(c); + } + + public string Render(DefEnum e) + { + return RenderUtil.RenderCsEnumClass(e); + } + + [ThreadStatic] + private static Template t_beanRender; + public string Render(DefBean b) + { + var template = t_beanRender ??= Template.Parse(@" +{{ + name = x.name + full_name = x.full_name + parent_def_type = x.parent_def_type + fields = x.fields + hierarchy_fields = x.hierarchy_fields + is_abstract_type = x.is_abstract_type +}} +using Bright.Serialization; + +namespace {{x.namespace_with_top_module}} +{ + +public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Transaction.TxnBeanBase {{end}} +{ + {{~ for field in fields~}} + {{if is_abstract_type}}protected{{else}}private{{end}} {{db_cs_define_type field.ctype}} {{field.internal_name}}; + {{~end}} + + public {{name}}() + { + {{~ for field in fields~}} + {{if cs_need_init field.ctype}}{{db_cs_init_field field.internal_name field.log_type field.ctype }} {{end}} + {{~end~}} + } + + {{~ for field in fields~}} + {{~if has_setter field.ctype~}} + + private sealed class {{field.log_type}} : Bright.Transaction.FieldLogger<{{name}}, {{db_cs_define_type field.ctype}}> + { + public {{field.log_type}}({{name}} self, {{db_cs_define_type field.ctype}} value) : base(self, value) { } + + public override long FieldId => host._objectId_ + {{field.id}}; + + public override void Commit() { this.host.{{field.internal_name}} = this.Value; } + + + public override void WriteBlob(ByteBuf _buf) + { + _buf.WriteInt(FieldTag.{{tag_name field.ctype}}); + {{cs_write_blob '_buf' 'this.Value' field.ctype}} + } + } + + public {{db_cs_define_type field.ctype}} {{field.cs_style_name}} + { + get + { + if (this.InitedObjectId) + { + var txn = Bright.Transaction.TransactionContext.AsyncLocalCtx; + if (txn == null) return {{field.internal_name}}; + var log = ({{field.log_type}})txn.GetField(_objectId_ + {{field.id}}); + return log != null ? log.Value : {{field.internal_name}}; + } + else + { + return {{field.internal_name}}; + } + } + set + { + {{~if db_field_cannot_null~}} + if (value == null) throw new ArgumentNullException(); + {{~end~}} + if (this.InitedObjectId) + { + var txn = Bright.Transaction.TransactionContext.AsyncLocalCtx; + txn.PutField(_objectId_ + {{field.id}}, new {{field.log_type}}(this, value)); + {{~if field.ctype.need_set_children_root}} + value?.InitRoot(GetRoot()); + {{end}} + } + else + { + {{field.internal_name}} = value; + } + } + } + {{~else~}} + {{~if field.ctype.is_collection~}} + private class {{field.log_type}} : {{db_cs_define_type field.ctype}}.Log + { + private readonly {{name}} host; + public {{field.log_type}}({{name}} host, {{cs_immutable_type field.ctype}} value) : base(value) { this.host = host; } + + public override long FieldId => host._objectId_ + {{field.id}}; + + public override Bright.Transaction.TxnBeanBase Host => host; + + public override void Commit() + { + Commit(host.{{field.internal_name}}); + } + + public override void WriteBlob(ByteBuf _buf) + { + _buf.WriteInt(FieldTag.{{tag_name field.ctype}}); + {{cs_write_blob '_buf' 'this.Value' field.ctype}} + } + } + {{~end~}} + + public {{db_cs_define_type field.ctype}} {{field.cs_style_name}} => {{field.internal_name}}; + {{~end~}} + {{~end~}} + + {{~if is_abstract_type~}} + public static void Serialize{{name}}(ByteBuf _buf, {{name}} x) + { + if (x == null) { _buf.WriteInt(0); return; } + _buf.WriteInt(x.GetTypeId()); + x.Serialize(_buf); + } + + public static {{name}} Deserialize{{name}}(ByteBuf _buf) + { + {{name}} x; + switch (_buf.ReadInt()) + { + case 0 : return null; + {{~ for child in x.hierarchy_not_abstract_children~}} + case {{child.full_name}}.ID: x = new {{child.full_name}}(); break; + {{~end~}} + default: throw new SerializationException(); + } + x.Deserialize(_buf); + return x; + } + {{~else~}} + public override void Serialize(ByteBuf _buf) + { + _buf.WriteLong(_objectId_); + {{~ for field in hierarchy_fields~}} + { _buf.WriteInt(FieldTag.{{tag_name field.ctype}} | ({{field.id}} << FieldTag.TAG_SHIFT)); {{db_cs_compatible_serialize '_buf' field.internal_name field.ctype}} } + {{~end}} + } + + public override void Deserialize(ByteBuf _buf) + { + _objectId_ = _buf.ReadLong(); + while(_buf.NotEmpty) + { + int _tag_ = _buf.ReadInt(); + switch (_tag_) + { + {{~ for field in hierarchy_fields~}} + case FieldTag.{{tag_name field.ctype}} | ({{field.id}} << FieldTag.TAG_SHIFT) : { {{db_cs_compatible_deserialize '_buf' field.internal_name field.ctype}} break; } + {{~end~}} + default: { _buf.SkipUnknownField(_tag_); break; } + } + } + } + + public const int ID = {{x.id}}; + public override int GetTypeId() => ID; + {{~end~}} + + protected override void InitChildrenRoot(Bright.Storage.TKey root) + { + {{~ for field in hierarchy_fields~}} + {{if need_set_children_root field.ctype}}{{field.internal_name}}?.InitRoot(root);{{end}} + {{~end}} + } + + public override string ToString() + { + return ""{{full_name}}{ "" + {{~ for field in hierarchy_fields~}} + + ""{{field.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "","" + {{~end~}} + + ""}""; + } +} + +} +"); + var result = template.RenderCode(b); + return result; + } + + [ThreadStatic] + private static Template t_tableRender; + public string Render(DefTable p) + { + var template = t_tableRender ??= Template.Parse(@" +{{ + name = x.name + key_ttype = x.key_ttype + value_ttype = x.value_ttype + base_table_type = x.base_table_type + internal_table_type = x.internal_table_type +}} +using System; +using System.Threading.Tasks; + +namespace {{x.namespace_with_top_module}} +{ + +public sealed class {{name}} +{ + public static {{base_table_type}} Table { get; } = new {{internal_table_type}}(); + + private class {{internal_table_type}} : {{base_table_type}} + { + public {{internal_table_type}}() : base({{x.table_uid}}, ""{{x.full_name}}"") + { + + } + }; + + public static ValueTask<{{db_cs_define_type value_ttype}}> GetAsync({{db_cs_define_type key_ttype}} key) + { + return Table.GetAsync(key); + } + + public static ValueTask<{{db_cs_define_type value_ttype}}> CreateIfNotExistAsync({{db_cs_define_type key_ttype}} key) + { + return Table.CreateIfNotExistAsync(key); + } + + public static Task InsertAsync({{db_cs_define_type key_ttype}} key, {{db_cs_define_type value_ttype}} value) + { + return Table.InsertAsync(key, value); + } + + public static Task RemoveAsync({{db_cs_define_type key_ttype}} key) + { + return Table.RemoveAsync(key); + } + + public static Task PutAsync({{db_cs_define_type key_ttype}} key, {{db_cs_define_type value_ttype}} value) + { + return Table.PutAsync(key, value); + } + + public static ValueTask<{{db_cs_define_type value_ttype}}> SelectAsync({{db_cs_define_type key_ttype}} key) + { + return Table.SelectAsync(key); + } +} +} + +"); + var result = template.RenderCode(p); + + return result; + } + + [ThreadStatic] + private static Template t_stubRender; + public string RenderTables(string name, string module, List tables) + { + var template = t_stubRender ??= Template.Parse(@" +using Bright.Serialization; + +namespace {{namespace}} +{ + +public static class {{name}} +{ + public static System.Collections.Generic.List TableList { get; } = new System.Collections.Generic.List + { + {{~ for table in tables~}} + {{table.full_name}}.Table, + {{~end}} + }; +} + +} + +"); + var result = template.Render(new + { + Name = name, + Namespace = module, + Tables = tables, + }); + + return result; + } + } +} diff --git a/src/Luban.Job.Db/Source/Generate/CsRender.cs b/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs similarity index 99% rename from src/Luban.Job.Db/Source/Generate/CsRender.cs rename to src/Luban.Job.Db/Source/Generate/SyncCsRender.cs index 83f06ab..dbd2273 100644 --- a/src/Luban.Job.Db/Source/Generate/CsRender.cs +++ b/src/Luban.Job.Db/Source/Generate/SyncCsRender.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace Luban.Job.Db.Generate { - class CsRender + class SyncCsRender { public string RenderAny(object o) { diff --git a/src/Luban.Job.Db/Source/JobController.cs b/src/Luban.Job.Db/Source/JobController.cs index 6138d5c..3d31c39 100644 --- a/src/Luban.Job.Db/Source/JobController.cs +++ b/src/Luban.Job.Db/Source/JobController.cs @@ -99,7 +99,7 @@ namespace Luban.Job.Db { case "cs": { - var render = new CsRender(); + var render = new AsyncCsRender(); foreach (var c in ass.Types.Values) { tasks.Add(Task.Run(() => diff --git a/src/Luban.Job.Db/Source/TypeVisitors/NeedSetChildrenRootVisitor.cs b/src/Luban.Job.Db/Source/TypeVisitors/NeedSetChildrenRootVisitor.cs index 480dcf2..8fb481c 100644 --- a/src/Luban.Job.Db/Source/TypeVisitors/NeedSetChildrenRootVisitor.cs +++ b/src/Luban.Job.Db/Source/TypeVisitors/NeedSetChildrenRootVisitor.cs @@ -19,12 +19,17 @@ namespace Luban.Job.Db.TypeVisitors public override bool Accept(TList type) { - return type.ElementType is TBean; + return true; + } + + public override bool Accept(TSet type) + { + return true; } public override bool Accept(TMap type) { - return type.ValueType is TBean; + return true; } } }