From 3550afbb21a00f9ab3cbf76015a996af412328ee Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Sat, 5 Jul 2025 13:30:05 +0800 Subject: [PATCH 1/3] fix(keyed-index): sort LevelFields in specified column order, not fd order --- internal/index/descriptor.go | 24 +++- internal/index/descriptor_test.go | 53 ++++++- internal/index/index_test.go | 8 ++ .../cpp-tableau-loader/src/protoconf/hub.pc.h | 5 + .../src/protoconf/hub_shard1.pc.cc | 7 + .../src/protoconf/test_conf.pc.cc | 60 ++++++++ .../src/protoconf/test_conf.pc.h | 32 +++++ .../protoconf/loader/hub.pc.go | 6 + .../protoconf/loader/test_conf.pc.go | 134 ++++++++++++++++++ test/proto/test_conf.proto | 18 +++ test/testdata/conf/TaskConf.json | 1 + 11 files changed, 339 insertions(+), 9 deletions(-) create mode 100644 test/testdata/conf/TaskConf.json diff --git a/internal/index/descriptor.go b/internal/index/descriptor.go index a15e6693..c35fa1b9 100644 --- a/internal/index/descriptor.go +++ b/internal/index/descriptor.go @@ -120,7 +120,18 @@ func parseRecursively(index *Index, prefix string, md protoreflect.MessageDescri } func parseInSameLevel(cols []string, prefix string, md protoreflect.MessageDescriptor, leveledFDList []protoreflect.FieldDescriptor) []*LevelField { + levelFieldMap := parseCols(cols, prefix, md, leveledFDList) var levelFields []*LevelField + for _, columnName := range cols { + if levelFieldMap[columnName] != nil { + levelFields = append(levelFields, levelFieldMap[columnName]) + } + } + return levelFields +} + +func parseCols(cols []string, prefix string, md protoreflect.MessageDescriptor, leveledFDList []protoreflect.FieldDescriptor) map[string]*LevelField { + levelFields := map[string]*LevelField{} // column name -> level field for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) opts := fd.Options().(*descriptorpb.FieldOptions) @@ -132,17 +143,18 @@ func parseInSameLevel(cols []string, prefix string, md protoreflect.MessageDescr FD: fd, LeveledFDList: append(leveledFDList, fd), } - levelFields = append(levelFields, field) + levelFields[columnName] = field break } else if fd.Kind() == protoreflect.MessageKind && !fd.IsMap() && !fd.IsList() && strings.HasPrefix(columnName, prefix+fieldOptName) { - levelFields = append(levelFields, - parseInSameLevel( - cols, prefix+fieldOptName, fd.Message(), - append(leveledFDList, fd), - )..., + subLevelFields := parseCols( + cols, prefix+fieldOptName, fd.Message(), + append(leveledFDList, fd), ) + for columnName, field := range subLevelFields { + levelFields[columnName] = field + } } } } diff --git a/internal/index/descriptor_test.go b/internal/index/descriptor_test.go index 365c83ea..8ad669c9 100644 --- a/internal/index/descriptor_test.go +++ b/internal/index/descriptor_test.go @@ -342,23 +342,70 @@ func Test_ParseIndexDescriptor(t *testing.T) { NextLevel: &LevelMessage{ FD: (&protoconf.Section{}).ProtoReflect().Descriptor().Fields().ByName("section_item_list"), NextLevel: &LevelMessage{ + FD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("decompose_item_list"), Indexes: []*LevelIndex{ { Index: &Index{ Cols: []string{"SectionItemID"}, Name: "Award", }, - MD: (&protoconf.Item{}).ProtoReflect().Descriptor(), + MD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor(), ColFields: []*LevelField{ { - FD: (&protoconf.Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("id"), }, }, }, }, }, + NextLevel: &LevelMessage{}, + }, + }, + }, + }, + }, + }, + }, + { + name: "TaskConf", + args: args{ + md: (&protoconf.TaskConf{}).ProtoReflect().Descriptor(), + }, + want: &IndexDescriptor{ + LevelMessage: &LevelMessage{ + FD: (&protoconf.TaskConf{}).ProtoReflect().Descriptor().Fields().ByName("task_map"), + NextLevel: &LevelMessage{ + Indexes: []*LevelIndex{ + { + Index: &Index{ + Cols: []string{"ActivityID"}, + Keys: []string{"Goal", "ID"}, + Name: "", + }, + MD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor(), + ColFields: []*LevelField{ + { + FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("activity_id"), + LeveledFDList: []protoreflect.FieldDescriptor{ + (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("activity_id"), + }, + }, + }, + KeyFields: []*LevelField{ + { + FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("goal"), + LeveledFDList: []protoreflect.FieldDescriptor{ + (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("goal"), + }, + }, + { + FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("id"), + LeveledFDList: []protoreflect.FieldDescriptor{ + (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("id"), + }, + }, }, }, }, diff --git a/internal/index/index_test.go b/internal/index/index_test.go index f46061c5..639bb141 100644 --- a/internal/index/index_test.go +++ b/internal/index/index_test.go @@ -52,6 +52,14 @@ func Test_parseColsFrom(t *testing.T) { Keys: []string{"Key6"}, }, }, + { + name: "zinotest", + input: "ActivityID", + want: &Index{ + Cols: []string{"ActivityID"}, + Keys: []string{"Goal", "ID"}, + }, + }, { name: "Multi-column with spaces around commas", input: "(Column7, Column8, Column9)@IndexName", diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.h b/test/cpp-tableau-loader/src/protoconf/hub.pc.h index 72c1593f..9611d52f 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.h @@ -144,6 +144,10 @@ class ChapterConf; template <> const std::shared_ptr Hub::Get() const; +class TaskConf; +template <> +const std::shared_ptr Hub::Get() const; + class ThemeConf; template <> const std::shared_ptr Hub::Get() const; @@ -171,6 +175,7 @@ class MessagerContainer { std::shared_ptr recursive_patch_conf_; std::shared_ptr activity_conf_; std::shared_ptr chapter_conf_; + std::shared_ptr task_conf_; std::shared_ptr theme_conf_; }; diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc index fdaf74b6..5778079d 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard1.pc.cc @@ -34,6 +34,11 @@ const std::shared_ptr Hub::Get() const { return GetMessagerContainer()->chapter_conf_; } +template <> +const std::shared_ptr Hub::Get() const { + return GetMessagerContainer()->task_conf_; +} + template <> const std::shared_ptr Hub::Get() const { return GetMessagerContainer()->theme_conf_; @@ -45,6 +50,7 @@ void MessagerContainer::InitShard1() { recursive_patch_conf_ = std::dynamic_pointer_cast((*msger_map_)["RecursivePatchConf"]); activity_conf_ = std::dynamic_pointer_cast((*msger_map_)["ActivityConf"]); chapter_conf_ = std::dynamic_pointer_cast((*msger_map_)["ChapterConf"]); + task_conf_ = std::dynamic_pointer_cast((*msger_map_)["TaskConf"]); theme_conf_ = std::dynamic_pointer_cast((*msger_map_)["ThemeConf"]); } @@ -54,6 +60,7 @@ void Registry::InitShard1() { Register(); Register(); Register(); + Register(); Register(); } } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc index be18610c..1a8f8582 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc @@ -286,4 +286,64 @@ const std::string* ThemeConf::Get(const std::string& name, const std::string& pa return &iter->second; } +const std::string TaskConf::kProtoName = "TaskConf"; + +bool TaskConf::Load(const std::string& dir, Format fmt, const LoadOptions* options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessage(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool TaskConf::ProcessAfterLoad() { + // Index init. + index_task_map_.clear(); + for (auto&& item1 : data_.task_map()) { + { + // Index: ActivityID + index_task_map_[item1.second.activity_id()].push_back(&item1.second); + } + } + // Index(sort): ActivityID + for (auto&& item : index_task_map_) { + std::sort(item.second.begin(), item.second.end(), + [](const protoconf::TaskConf::Task* a, const protoconf::TaskConf::Task* b) { + if (a->goal() != b->goal()) { + return a->goal() < b->goal(); + } + return a->id() < b->id(); + }); + } + return true; +} + +const protoconf::TaskConf::Task* TaskConf::Get(int64_t id) const { + auto iter = data_.task_map().find(id); + if (iter == data_.task_map().end()) { + return nullptr; + } + return &iter->second; +} + +// Index: ActivityID +const TaskConf::Index_TaskMap& TaskConf::FindTask() const { return index_task_map_ ;} + +const TaskConf::Index_TaskVector* TaskConf::FindTask(int64_t activity_id) const { + auto iter = index_task_map_.find(activity_id); + if (iter == index_task_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::TaskConf::Task* TaskConf::FindFirstTask(int64_t activity_id) const { + auto conf = FindTask(activity_id); + if (conf == nullptr || conf->size() == 0) { + return nullptr; + } + return (*conf)[0]; +} + + } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 6d434e9d..3947e957 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -130,6 +130,37 @@ class ThemeConf : public Messager { protoconf::ThemeConf data_; }; +class TaskConf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::string& dir, Format fmt, const LoadOptions* options = nullptr) override; + const protoconf::TaskConf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + public: + const protoconf::TaskConf::Task* Get(int64_t id) const; + + private: + static const std::string kProtoName; + protoconf::TaskConf data_; + + // Index accessers. + // Index: ActivityID + public: + using Index_TaskVector = std::vector; + using Index_TaskMap = std::unordered_map; + const Index_TaskMap& FindTask() const; + const Index_TaskVector* FindTask(int64_t activity_id) const; + const protoconf::TaskConf::Task* FindFirstTask(int64_t activity_id) const; + + private: + Index_TaskMap index_task_map_; + +}; + } // namespace tableau namespace protoconf { @@ -137,4 +168,5 @@ namespace protoconf { using ActivityConfMgr = tableau::ActivityConf; using ChapterConfMgr = tableau::ChapterConf; using ThemeConfMgr = tableau::ThemeConf; +using TaskConfMgr = tableau::TaskConf; } // namespace protoconf diff --git a/test/go-tableau-loader/protoconf/loader/hub.pc.go b/test/go-tableau-loader/protoconf/loader/hub.pc.go index 8aee1194..f70c49cf 100644 --- a/test/go-tableau-loader/protoconf/loader/hub.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hub.pc.go @@ -329,6 +329,7 @@ type messagerContainer struct { activityConf *ActivityConf chapterConf *ChapterConf themeConf *ThemeConf + taskConf *TaskConf } func newMessagerContainer(messagerMap MessagerMap) *messagerContainer { @@ -345,6 +346,7 @@ func newMessagerContainer(messagerMap MessagerMap) *messagerContainer { messagerContainer.activityConf, _ = messagerMap["ActivityConf"].(*ActivityConf) messagerContainer.chapterConf, _ = messagerMap["ChapterConf"].(*ChapterConf) messagerContainer.themeConf, _ = messagerMap["ThemeConf"].(*ThemeConf) + messagerContainer.taskConf, _ = messagerMap["TaskConf"].(*TaskConf) return messagerContainer } @@ -385,3 +387,7 @@ func (h *Hub) GetChapterConf() *ChapterConf { func (h *Hub) GetThemeConf() *ThemeConf { return h.messagerContainer.Load().themeConf } + +func (h *Hub) GetTaskConf() *TaskConf { + return h.messagerContainer.Load().taskConf +} diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index beaa009f..fbebbc1c 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -560,6 +560,137 @@ func (x *ThemeConf) Get2(name string, param string) (string, error) { } } +// Index types. +// Index: ActivityID +type TaskConf_Index_TaskMap = map[int64][]*protoconf.TaskConf_Task + +// TaskConf is a wrapper around protobuf message: protoconf.TaskConf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index... +type TaskConf struct { + UnimplementedMessager + data, originalData *protoconf.TaskConf + indexTaskMap TaskConf_Index_TaskMap +} + +// Name returns the TaskConf's message name. +func (x *TaskConf) Name() string { + if x != nil { + return string(x.data.ProtoReflect().Descriptor().Name()) + } + return "" +} + +// Data returns the TaskConf's inner message data. +func (x *TaskConf) Data() *protoconf.TaskConf { + if x != nil { + return x.data + } + return nil +} + +// Load fills TaskConf's inner message from file in the specified directory and format. +func (x *TaskConf) Load(dir string, format format.Format, options ...load.Option) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.TaskConf{} + err := load.Load(x.data, dir, format, options...) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.TaskConf) + } + return x.processAfterLoad() +} + +// Store writes TaskConf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *TaskConf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the TaskConf's inner message data. +func (x *TaskConf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *TaskConf) Messager() Messager { + return x +} + +// originalMessage returns the TaskConf's original inner message. +func (x *TaskConf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *TaskConf) processAfterLoad() error { + // Index init. + x.indexTaskMap = make(TaskConf_Index_TaskMap) + for _, item1 := range x.data.GetTaskMap() { + { + // Index: ActivityID + key := item1.GetActivityId() + x.indexTaskMap[key] = append(x.indexTaskMap[key], item1) + } + } + // Index(sort): ActivityID + for _, item := range x.indexTaskMap { + sort.Slice(item, func(i, j int) bool { + if item[i].GetGoal() != item[j].GetGoal() { + return item[i].GetGoal() < item[j].GetGoal() + } + return item[i].GetId() < item[j].GetId() + }) + } + return nil +} + +// Get1 finds value in the 1-level map. It will return +// NotFound error if the key is not found. +func (x *TaskConf) Get1(id int64) (*protoconf.TaskConf_Task, error) { + d := x.Data().GetTaskMap() + if val, ok := d[id]; !ok { + return nil, xerrors.Errorf(code.NotFound, "id(%v) not found", id) + } else { + return val, nil + } +} + +// Index: ActivityID + +// FindTaskMap returns the index(ActivityID) to value(protoconf.TaskConf_Task) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *TaskConf) FindTaskMap() TaskConf_Index_TaskMap { + return x.indexTaskMap +} + +// FindTask returns a slice of all values of the given key. +func (x *TaskConf) FindTask(activityId int64) []*protoconf.TaskConf_Task { + return x.indexTaskMap[activityId] +} + +// FindFirstTask returns the first value of the given key, +// or nil if the key correspond to no value. +func (x *TaskConf) FindFirstTask(activityId int64) *protoconf.TaskConf_Task { + val := x.indexTaskMap[activityId] + if len(val) > 0 { + return val[0] + } + return nil +} + func init() { Register(func() Messager { return new(ActivityConf) @@ -570,4 +701,7 @@ func init() { Register(func() Messager { return new(ThemeConf) }) + Register(func() Messager { + return new(TaskConf) + }) } diff --git a/test/proto/test_conf.proto b/test/proto/test_conf.proto index 39123b64..81d395cb 100644 --- a/test/proto/test_conf.proto +++ b/test/proto/test_conf.proto @@ -94,3 +94,21 @@ message ThemeConf { map param_map = 3 [(tableau.field) = { key: "Param" layout: LAYOUT_INCELL }]; } } + +message TaskConf { + option (tableau.worksheet) = { + name: "TaskConf" + index: "ActivityID" + }; + + map task_map = 1 [(tableau.field) = { key: "ID" layout: LAYOUT_VERTICAL }]; + message Task { + int64 id = 1 [(tableau.field) = { name: "ID" }]; + int64 activity_id = 2 [(tableau.field) = { name: "ActivityID" }]; + int64 goal = 3 [(tableau.field) = { + name: "Goal" + prop: { range: "0,~" } + }]; + protoconf.Item reward = 4 [(tableau.field) = { name: "Reward" }]; + } +} \ No newline at end of file diff --git a/test/testdata/conf/TaskConf.json b/test/testdata/conf/TaskConf.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/testdata/conf/TaskConf.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 04d0b519f2d06f829fef641df00c6ddf3f36f81d Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Sat, 5 Jul 2025 14:43:36 +0800 Subject: [PATCH 2/3] fix: cr --- internal/index/descriptor_test.go | 184 ++++++++++++++++-------------- test/proto/test_conf.proto | 5 +- 2 files changed, 98 insertions(+), 91 deletions(-) diff --git a/internal/index/descriptor_test.go b/internal/index/descriptor_test.go index 8ad669c9..37952b82 100644 --- a/internal/index/descriptor_test.go +++ b/internal/index/descriptor_test.go @@ -5,9 +5,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/tableauio/loader/test/go-tableau-loader/protoconf" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" ) +func md[T proto.Message]() protoreflect.MessageDescriptor { + var t T + return t.ProtoReflect().Descriptor() +} + +func fd[T proto.Message](name protoreflect.Name) protoreflect.FieldDescriptor { + return md[T]().Fields().ByName(name) +} + func Test_ParseIndexDescriptor(t *testing.T) { type args struct { md protoreflect.MessageDescriptor @@ -20,11 +30,11 @@ func Test_ParseIndexDescriptor(t *testing.T) { { name: "ItemConf", args: args{ - md: (&protoconf.ItemConf{}).ProtoReflect().Descriptor(), + md: md[*protoconf.ItemConf](), }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: (&protoconf.ItemConf{}).ProtoReflect().Descriptor().Fields().ByName("item_map"), + FD: fd[*protoconf.ItemConf]("item_map"), NextLevel: &LevelMessage{ Indexes: []*LevelIndex{ { @@ -32,12 +42,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"Type"}, Name: "", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + FD: fd[*protoconf.ItemConf_Item]("type"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + fd[*protoconf.ItemConf_Item]("type"), }, }, }, @@ -48,20 +58,20 @@ func Test_ParseIndexDescriptor(t *testing.T) { Keys: []string{"ID"}, Name: "ItemInfo", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("param_list"), + FD: fd[*protoconf.ItemConf_Item]("param_list"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("param_list"), + fd[*protoconf.ItemConf_Item]("param_list"), }, }, }, KeyFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.ItemConf_Item]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.ItemConf_Item]("id"), }, }, }, @@ -71,12 +81,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"Default"}, Name: "ItemDefaultInfo", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("default"), + FD: fd[*protoconf.ItemConf_Item]("default"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("default"), + fd[*protoconf.ItemConf_Item]("default"), }, }, }, @@ -86,12 +96,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"ExtType"}, Name: "ItemExtInfo", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("ext_type_list"), + FD: fd[*protoconf.ItemConf_Item]("ext_type_list"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("ext_type_list"), + fd[*protoconf.ItemConf_Item]("ext_type_list"), }, }, }, @@ -102,33 +112,33 @@ func Test_ParseIndexDescriptor(t *testing.T) { Keys: []string{"Type", "UseEffectType"}, Name: "AwardItem", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.ItemConf_Item]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.ItemConf_Item]("id"), }, }, { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("name"), + FD: fd[*protoconf.ItemConf_Item]("name"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("name"), + fd[*protoconf.ItemConf_Item]("name"), }, }, }, KeyFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + FD: fd[*protoconf.ItemConf_Item]("type"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + fd[*protoconf.ItemConf_Item]("type"), }, }, { - FD: (&protoconf.UseEffect{}).ProtoReflect().Descriptor().Fields().ByName("type"), + FD: fd[*protoconf.UseEffect]("type"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("use_effect"), - (&protoconf.UseEffect{}).ProtoReflect().Descriptor().Fields().ByName("type"), + fd[*protoconf.ItemConf_Item]("use_effect"), + fd[*protoconf.UseEffect]("type"), }, }, }, @@ -138,30 +148,30 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"ID", "Type", "Param", "ExtType"}, Name: "SpecialItem", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.ItemConf_Item]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.ItemConf_Item]("id"), }, }, { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + FD: fd[*protoconf.ItemConf_Item]("type"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("type"), + fd[*protoconf.ItemConf_Item]("type"), }, }, { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("param_list"), + FD: fd[*protoconf.ItemConf_Item]("param_list"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("param_list"), + fd[*protoconf.ItemConf_Item]("param_list"), }, }, { - FD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("ext_type_list"), + FD: fd[*protoconf.ItemConf_Item]("ext_type_list"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("ext_type_list"), + fd[*protoconf.ItemConf_Item]("ext_type_list"), }, }, }, @@ -171,13 +181,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"PathDir"}, Name: "ItemPathDir", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.Path{}).ProtoReflect().Descriptor().Fields().ByName("dir"), + FD: fd[*protoconf.Path]("dir"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("path"), - (&protoconf.Path{}).ProtoReflect().Descriptor().Fields().ByName("dir"), + fd[*protoconf.ItemConf_Item]("path"), + fd[*protoconf.Path]("dir"), }, }, }, @@ -187,13 +197,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"PathName"}, Name: "ItemPathName", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.Path{}).ProtoReflect().Descriptor().Fields().ByName("name_list"), + FD: fd[*protoconf.Path]("name_list"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("path"), - (&protoconf.Path{}).ProtoReflect().Descriptor().Fields().ByName("name_list"), + fd[*protoconf.ItemConf_Item]("path"), + fd[*protoconf.Path]("name_list"), }, }, }, @@ -203,14 +213,14 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"PathFriendID"}, Name: "ItemPathFriendID", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.Path_Friend{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.Path_Friend]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("path"), - (&protoconf.Path{}).ProtoReflect().Descriptor().Fields().ByName("friend"), - (&protoconf.Path_Friend{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.ItemConf_Item]("path"), + fd[*protoconf.Path]("friend"), + fd[*protoconf.Path_Friend]("id"), }, }, }, @@ -220,13 +230,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"UseEffectType"}, Name: "UseEffectType", }, - MD: (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ItemConf_Item](), ColFields: []*LevelField{ { - FD: (&protoconf.UseEffect{}).ProtoReflect().Descriptor().Fields().ByName("type"), + FD: fd[*protoconf.UseEffect]("type"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ItemConf_Item{}).ProtoReflect().Descriptor().Fields().ByName("use_effect"), - (&protoconf.UseEffect{}).ProtoReflect().Descriptor().Fields().ByName("type"), + fd[*protoconf.ItemConf_Item]("use_effect"), + fd[*protoconf.UseEffect]("type"), }, }, }, @@ -239,13 +249,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { { name: "HeroConf", args: args{ - md: (&protoconf.HeroConf{}).ProtoReflect().Descriptor(), + md: md[*protoconf.HeroConf](), }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: (&protoconf.HeroConf{}).ProtoReflect().Descriptor().Fields().ByName("hero_map"), + FD: fd[*protoconf.HeroConf]("hero_map"), NextLevel: &LevelMessage{ - FD: (&protoconf.HeroConf_Hero{}).ProtoReflect().Descriptor().Fields().ByName("attr_map"), + FD: fd[*protoconf.HeroConf_Hero]("attr_map"), NextLevel: &LevelMessage{ Indexes: []*LevelIndex{ { @@ -253,12 +263,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { Cols: []string{"Title"}, Name: "", }, - MD: (&protoconf.HeroConf_Hero_Attr{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.HeroConf_Hero_Attr](), ColFields: []*LevelField{ { - FD: (&protoconf.HeroConf_Hero_Attr{}).ProtoReflect().Descriptor().Fields().ByName("title"), + FD: fd[*protoconf.HeroConf_Hero_Attr]("title"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.HeroConf_Hero_Attr{}).ProtoReflect().Descriptor().Fields().ByName("title"), + fd[*protoconf.HeroConf_Hero_Attr]("title"), }, }, }, @@ -272,44 +282,44 @@ func Test_ParseIndexDescriptor(t *testing.T) { { name: "ActivityConf", args: args{ - md: (&protoconf.ActivityConf{}).ProtoReflect().Descriptor(), + md: md[*protoconf.ActivityConf](), }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: (&protoconf.ActivityConf{}).ProtoReflect().Descriptor().Fields().ByName("activity_map"), + FD: fd[*protoconf.ActivityConf]("activity_map"), NextLevel: &LevelMessage{ - FD: (&protoconf.ActivityConf_Activity{}).ProtoReflect().Descriptor().Fields().ByName("chapter_map"), + FD: fd[*protoconf.ActivityConf_Activity]("chapter_map"), Indexes: []*LevelIndex{ { Index: &Index{ Cols: []string{"ActivityName"}, Name: "", }, - MD: (&protoconf.ActivityConf_Activity{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ActivityConf_Activity](), ColFields: []*LevelField{ { - FD: (&protoconf.ActivityConf_Activity{}).ProtoReflect().Descriptor().Fields().ByName("activity_name"), + FD: fd[*protoconf.ActivityConf_Activity]("activity_name"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ActivityConf_Activity{}).ProtoReflect().Descriptor().Fields().ByName("activity_name"), + fd[*protoconf.ActivityConf_Activity]("activity_name"), }, }, }, }, }, NextLevel: &LevelMessage{ - FD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("section_map"), + FD: fd[*protoconf.ActivityConf_Activity_Chapter]("section_map"), Indexes: []*LevelIndex{ { Index: &Index{ Cols: []string{"ChapterID"}, Name: "", }, - MD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ActivityConf_Activity_Chapter](), ColFields: []*LevelField{ { - FD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("chapter_id"), + FD: fd[*protoconf.ActivityConf_Activity_Chapter]("chapter_id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("chapter_id"), + fd[*protoconf.ActivityConf_Activity_Chapter]("chapter_id"), }, }, }, @@ -320,41 +330,41 @@ func Test_ParseIndexDescriptor(t *testing.T) { Keys: []string{"AwardID"}, Name: "NamedChapter", }, - MD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.ActivityConf_Activity_Chapter](), ColFields: []*LevelField{ { - FD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("chapter_name"), + FD: fd[*protoconf.ActivityConf_Activity_Chapter]("chapter_name"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("chapter_name"), + fd[*protoconf.ActivityConf_Activity_Chapter]("chapter_name"), }, }, }, KeyFields: []*LevelField{ { - FD: (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("award_id"), + FD: fd[*protoconf.ActivityConf_Activity_Chapter]("award_id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.ActivityConf_Activity_Chapter{}).ProtoReflect().Descriptor().Fields().ByName("award_id"), + fd[*protoconf.ActivityConf_Activity_Chapter]("award_id"), }, }, }, }, }, NextLevel: &LevelMessage{ - FD: (&protoconf.Section{}).ProtoReflect().Descriptor().Fields().ByName("section_item_list"), + FD: fd[*protoconf.Section]("section_item_list"), NextLevel: &LevelMessage{ - FD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("decompose_item_list"), + FD: fd[*protoconf.Section_SectionItem]("decompose_item_list"), Indexes: []*LevelIndex{ { Index: &Index{ Cols: []string{"SectionItemID"}, Name: "Award", }, - MD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.Section_SectionItem](), ColFields: []*LevelField{ { - FD: (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.Section_SectionItem]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.Section_SectionItem{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.Section_SectionItem]("id"), }, }, }, @@ -371,11 +381,11 @@ func Test_ParseIndexDescriptor(t *testing.T) { { name: "TaskConf", args: args{ - md: (&protoconf.TaskConf{}).ProtoReflect().Descriptor(), + md: md[*protoconf.TaskConf](), }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: (&protoconf.TaskConf{}).ProtoReflect().Descriptor().Fields().ByName("task_map"), + FD: fd[*protoconf.TaskConf]("task_map"), NextLevel: &LevelMessage{ Indexes: []*LevelIndex{ { @@ -384,26 +394,26 @@ func Test_ParseIndexDescriptor(t *testing.T) { Keys: []string{"Goal", "ID"}, Name: "", }, - MD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor(), + MD: md[*protoconf.TaskConf_Task](), ColFields: []*LevelField{ { - FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("activity_id"), + FD: fd[*protoconf.TaskConf_Task]("activity_id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("activity_id"), + fd[*protoconf.TaskConf_Task]("activity_id"), }, }, }, KeyFields: []*LevelField{ { - FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("goal"), + FD: fd[*protoconf.TaskConf_Task]("goal"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("goal"), + fd[*protoconf.TaskConf_Task]("goal"), }, }, { - FD: (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("id"), + FD: fd[*protoconf.TaskConf_Task]("id"), LeveledFDList: []protoreflect.FieldDescriptor{ - (&protoconf.TaskConf_Task{}).ProtoReflect().Descriptor().Fields().ByName("id"), + fd[*protoconf.TaskConf_Task]("id"), }, }, }, diff --git a/test/proto/test_conf.proto b/test/proto/test_conf.proto index 81d395cb..181bd32d 100644 --- a/test/proto/test_conf.proto +++ b/test/proto/test_conf.proto @@ -105,10 +105,7 @@ message TaskConf { message Task { int64 id = 1 [(tableau.field) = { name: "ID" }]; int64 activity_id = 2 [(tableau.field) = { name: "ActivityID" }]; - int64 goal = 3 [(tableau.field) = { - name: "Goal" - prop: { range: "0,~" } - }]; + int64 goal = 3 [(tableau.field) = { name: "Goal" }]; protoconf.Item reward = 4 [(tableau.field) = { name: "Reward" }]; } } \ No newline at end of file From 37d09b7de073c33af3e2da8998249b32f7db80b3 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Sat, 5 Jul 2025 14:45:09 +0800 Subject: [PATCH 3/3] fix: rename index test function --- internal/index/index_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/index/index_test.go b/internal/index/index_test.go index 639bb141..a65c8172 100644 --- a/internal/index/index_test.go +++ b/internal/index/index_test.go @@ -5,7 +5,7 @@ import ( "testing" ) -func Test_parseColsFrom(t *testing.T) { +func Test_parseIndex(t *testing.T) { tests := []struct { name string input string @@ -88,7 +88,7 @@ func Test_parseColsFrom(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseIndex(tt.input); !reflect.DeepEqual(got, tt.want) { - t.Errorf("parseColsFrom() = %v, want %v", got, tt.want) + t.Errorf("parseIndex() = %v, want %v", got, tt.want) } }) }