From 62496d4ac38121053597d9dce2ed2c790abd5b39 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 31 Jan 2023 04:44:11 -0500 Subject: [PATCH] feat(orm): support orm appconfig module (#14824) --- orm/go.mod | 4 +- orm/go.sum | 8 +- orm/internal/testpb/bank.pb.go | 131 +++++++++++++----- orm/internal/testpb/bank.proto | 15 ++ orm/internal/testpb/bank_query.pb.go | 6 +- orm/internal/testpb/bank_query.proto | 15 +- orm/internal/testpb/test_schema.pb.go | 3 +- orm/internal/testpb/test_schema_query.pb.go | 12 +- orm/internal/testpb/test_schema_query.proto | 63 ++++----- orm/model/ormdb/file.go | 4 + orm/model/ormdb/module.go | 20 +-- orm/model/ormdb/module_test.go | 114 ++++++++++----- orm/model/ormtable/build.go | 2 +- orm/orm.go | 69 +++++++++ orm/types/ormerrors/errors.go | 1 + proto/cosmos/orm/module/v1alpha1/module.proto | 4 +- 16 files changed, 331 insertions(+), 140 deletions(-) create mode 100644 orm/orm.go diff --git a/orm/go.mod b/orm/go.mod index 96d95cbb6e..a9fd13124e 100644 --- a/orm/go.mod +++ b/orm/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( cosmossdk.io/api v0.2.6 cosmossdk.io/core v0.5.1 + cosmossdk.io/depinject v1.0.0-alpha.3 cosmossdk.io/errors v1.0.0-beta.7 github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 github.com/cosmos/cosmos-proto v1.0.0-beta.1 @@ -57,6 +58,7 @@ require ( golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/orm/go.sum b/orm/go.sum index cc22649e98..2493b28414 100644 --- a/orm/go.sum +++ b/orm/go.sum @@ -3,6 +3,8 @@ cosmossdk.io/api v0.2.6 h1:AoNwaLLapcLsphhMK6+o0kZl+D6MMUaHVqSdwinASGU= cosmossdk.io/api v0.2.6/go.mod h1:u/d+GAxil0nWpl1XnQL8nkziQDIWuBDhv8VnDm/s6dI= cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -204,7 +206,6 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -503,7 +504,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= @@ -515,6 +515,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -527,3 +529,5 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/orm/internal/testpb/bank.pb.go b/orm/internal/testpb/bank.pb.go index 83ef85f5c8..83c50055fd 100644 --- a/orm/internal/testpb/bank.pb.go +++ b/orm/internal/testpb/bank.pb.go @@ -1,13 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.27.1 // protoc (unknown) // source: testpb/bank.proto package testpb import ( + _ "cosmossdk.io/api/cosmos/app/v1alpha1" _ "cosmossdk.io/api/cosmos/orm/v1" + _ "cosmossdk.io/api/cosmos/orm/v1alpha1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -21,6 +23,45 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Module is a test module for demonstrating how to use the ORM with appconfig. +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_testpb_bank_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_testpb_bank_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_testpb_bank_proto_rawDescGZIP(), []int{0} +} + type Balance struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -34,7 +75,7 @@ type Balance struct { func (x *Balance) Reset() { *x = Balance{} if protoimpl.UnsafeEnabled { - mi := &file_testpb_bank_proto_msgTypes[0] + mi := &file_testpb_bank_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -47,7 +88,7 @@ func (x *Balance) String() string { func (*Balance) ProtoMessage() {} func (x *Balance) ProtoReflect() protoreflect.Message { - mi := &file_testpb_bank_proto_msgTypes[0] + mi := &file_testpb_bank_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -60,7 +101,7 @@ func (x *Balance) ProtoReflect() protoreflect.Message { // Deprecated: Use Balance.ProtoReflect.Descriptor instead. func (*Balance) Descriptor() ([]byte, []int) { - return file_testpb_bank_proto_rawDescGZIP(), []int{0} + return file_testpb_bank_proto_rawDescGZIP(), []int{1} } func (x *Balance) GetAddress() string { @@ -96,7 +137,7 @@ type Supply struct { func (x *Supply) Reset() { *x = Supply{} if protoimpl.UnsafeEnabled { - mi := &file_testpb_bank_proto_msgTypes[1] + mi := &file_testpb_bank_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -109,7 +150,7 @@ func (x *Supply) String() string { func (*Supply) ProtoMessage() {} func (x *Supply) ProtoReflect() protoreflect.Message { - mi := &file_testpb_bank_proto_msgTypes[1] + mi := &file_testpb_bank_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -122,7 +163,7 @@ func (x *Supply) ProtoReflect() protoreflect.Message { // Deprecated: Use Supply.ProtoReflect.Descriptor instead. func (*Supply) Descriptor() ([]byte, []int) { - return file_testpb_bank_proto_rawDescGZIP(), []int{1} + return file_testpb_bank_proto_rawDescGZIP(), []int{2} } func (x *Supply) GetDenom() string { @@ -145,28 +186,37 @@ var file_testpb_bank_proto_rawDesc = []byte{ 0x0a, 0x11, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x6d, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x77, 0x0a, 0x07, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, - 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, - 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x24, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x1e, 0x0a, - 0x0f, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2c, 0x64, 0x65, 0x6e, 0x6f, 0x6d, - 0x12, 0x09, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x10, 0x01, 0x18, 0x01, 0x22, 0x49, 0x0a, - 0x06, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x11, 0xf2, 0x9e, 0xd3, 0x8e, 0x03, 0x0b, 0x0a, 0x07, 0x0a, - 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x42, 0x81, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x09, 0x42, 0x61, 0x6e, 0x6b, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, - 0x64, 0x6b, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, - 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x54, - 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xe2, 0x02, - 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, 0x6d, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, + 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x3a, 0x46, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x23, 0x0a, 0x21, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6f, 0x72, + 0x6d, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x6f, 0x72, 0x6d, 0x64, 0x62, 0x82, 0x9f, 0xd3, + 0x8e, 0x03, 0x17, 0x0a, 0x15, 0x08, 0x01, 0x12, 0x11, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, + 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x77, 0x0a, 0x07, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x24, 0xf2, + 0x9e, 0xd3, 0x8e, 0x03, 0x1e, 0x0a, 0x0f, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x2c, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x09, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x10, + 0x01, 0x18, 0x01, 0x22, 0x49, 0x0a, 0x06, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, + 0x6e, 0x6f, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x11, 0xf2, 0x9e, 0xd3, + 0x8e, 0x03, 0x0b, 0x0a, 0x07, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x42, 0x81, + 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x09, 0x42, + 0x61, 0x6e, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, + 0x58, 0x58, 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, + 0x73, 0x74, 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -181,10 +231,11 @@ func file_testpb_bank_proto_rawDescGZIP() []byte { return file_testpb_bank_proto_rawDescData } -var file_testpb_bank_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_testpb_bank_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_testpb_bank_proto_goTypes = []interface{}{ - (*Balance)(nil), // 0: testpb.Balance - (*Supply)(nil), // 1: testpb.Supply + (*Module)(nil), // 0: testpb.Module + (*Balance)(nil), // 1: testpb.Balance + (*Supply)(nil), // 2: testpb.Supply } var file_testpb_bank_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -201,7 +252,7 @@ func file_testpb_bank_proto_init() { } if !protoimpl.UnsafeEnabled { file_testpb_bank_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Balance); i { + switch v := v.(*Module); i { case 0: return &v.state case 1: @@ -213,6 +264,18 @@ func file_testpb_bank_proto_init() { } } file_testpb_bank_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Balance); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_testpb_bank_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Supply); i { case 0: return &v.state @@ -231,7 +294,7 @@ func file_testpb_bank_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_testpb_bank_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/orm/internal/testpb/bank.proto b/orm/internal/testpb/bank.proto index 1a41a8387f..57c28cac9e 100644 --- a/orm/internal/testpb/bank.proto +++ b/orm/internal/testpb/bank.proto @@ -3,9 +3,24 @@ syntax = "proto3"; package testpb; import "cosmos/orm/v1/orm.proto"; +import "cosmos/orm/v1alpha1/schema.proto"; +import "cosmos/app/v1alpha1/module.proto"; // This is a simulated bank schema used for testing. +// Module is a test module for demonstrating how to use the ORM with appconfig. +message Module { + option (cosmos.app.v1alpha1.module) = { + go_import: "github.com/cosmos/orm/model/ormdb" + }; + option (cosmos.orm.v1alpha1.module_schema) = { + schema_file: { + id: 1 + proto_file_name: "testpb/bank.proto" + } + }; +} + message Balance { option (cosmos.orm.v1.table) = { id: 1; diff --git a/orm/internal/testpb/bank_query.pb.go b/orm/internal/testpb/bank_query.pb.go index 487235337c..f0a2e21f02 100644 --- a/orm/internal/testpb/bank_query.pb.go +++ b/orm/internal/testpb/bank_query.pb.go @@ -2,7 +2,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.27.1 // protoc (unknown) // source: testpb/bank_query.proto @@ -139,7 +139,6 @@ type ListBalanceRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListBalanceRequest_PrefixQuery // *ListBalanceRequest_RangeQuery_ Query isListBalanceRequest_Query `protobuf_oneof:"query"` @@ -390,7 +389,6 @@ type ListSupplyRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListSupplyRequest_PrefixQuery // *ListSupplyRequest_RangeQuery_ Query isListSupplyRequest_Query `protobuf_oneof:"query"` @@ -543,7 +541,6 @@ type ListBalanceRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListBalanceRequest_IndexKey_AddressDenom_ // *ListBalanceRequest_IndexKey_Denom_ Key isListBalanceRequest_IndexKey_Key `protobuf_oneof:"key"` @@ -798,7 +795,6 @@ type ListSupplyRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListSupplyRequest_IndexKey_Denom_ Key isListSupplyRequest_IndexKey_Key `protobuf_oneof:"key"` } diff --git a/orm/internal/testpb/bank_query.proto b/orm/internal/testpb/bank_query.proto index 6335d52eaf..a204777bd4 100644 --- a/orm/internal/testpb/bank_query.proto +++ b/orm/internal/testpb/bank_query.proto @@ -42,7 +42,7 @@ message ListBalanceRequest { // denom specifies the value of the Denom index key to use in the query. Denom denom = 2; } - + message AddressDenom { // address is the value of the address field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. @@ -51,14 +51,14 @@ message ListBalanceRequest { // It can be omitted to query for all valid values of that field in this segment of the index. optional string denom = 2; } - + message Denom { // denom is the value of the denom field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional string denom = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -68,7 +68,7 @@ message ListBalanceRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -110,14 +110,14 @@ message ListSupplyRequest { // denom specifies the value of the Denom index key to use in the query. Denom denom = 1; } - + message Denom { // denom is the value of the denom field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional string denom = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -127,7 +127,7 @@ message ListSupplyRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -147,3 +147,4 @@ message ListSupplyResponse { // pagination is the pagination response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } + diff --git a/orm/internal/testpb/test_schema.pb.go b/orm/internal/testpb/test_schema.pb.go index 8dc30bfc36..4f98d3208c 100644 --- a/orm/internal/testpb/test_schema.pb.go +++ b/orm/internal/testpb/test_schema.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.27.1 // protoc (unknown) // source: testpb/test_schema.proto @@ -105,7 +105,6 @@ type ExampleTable struct { Map map[string]uint32 `protobuf:"bytes,18,rep,name=map,proto3" json:"map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` Msg *ExampleTable_ExampleMessage `protobuf:"bytes,19,opt,name=msg,proto3" json:"msg,omitempty"` // Types that are assignable to Sum: - // // *ExampleTable_Oneof Sum isExampleTable_Sum `protobuf_oneof:"sum"` } diff --git a/orm/internal/testpb/test_schema_query.pb.go b/orm/internal/testpb/test_schema_query.pb.go index 484624eb64..b72ddd3449 100644 --- a/orm/internal/testpb/test_schema_query.pb.go +++ b/orm/internal/testpb/test_schema_query.pb.go @@ -2,7 +2,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.27.1 // protoc (unknown) // source: testpb/test_schema_query.proto @@ -253,7 +253,6 @@ type ListExampleTableRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListExampleTableRequest_PrefixQuery // *ListExampleTableRequest_RangeQuery_ Query isListExampleTableRequest_Query `protobuf_oneof:"query"` @@ -600,7 +599,6 @@ type ListExampleAutoIncrementTableRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListExampleAutoIncrementTableRequest_PrefixQuery // *ListExampleAutoIncrementTableRequest_RangeQuery_ Query isListExampleAutoIncrementTableRequest_Query `protobuf_oneof:"query"` @@ -940,7 +938,6 @@ type ListExampleTimestampRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListExampleTimestampRequest_PrefixQuery // *ListExampleTimestampRequest_RangeQuery_ Query isListExampleTimestampRequest_Query `protobuf_oneof:"query"` @@ -1287,7 +1284,6 @@ type ListSimpleExampleRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListSimpleExampleRequest_PrefixQuery // *ListSimpleExampleRequest_RangeQuery_ Query isListSimpleExampleRequest_Query `protobuf_oneof:"query"` @@ -1538,7 +1534,6 @@ type ListExampleAutoIncFieldNameRequest struct { // query specifies the type of query - either a prefix or range query. // // Types that are assignable to Query: - // // *ListExampleAutoIncFieldNameRequest_PrefixQuery // *ListExampleAutoIncFieldNameRequest_RangeQuery_ Query isListExampleAutoIncFieldNameRequest_Query `protobuf_oneof:"query"` @@ -1691,7 +1686,6 @@ type ListExampleTableRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListExampleTableRequest_IndexKey_U_32I_64Str // *ListExampleTableRequest_IndexKey_U_64Str // *ListExampleTableRequest_IndexKey_StrU_32 @@ -2114,7 +2108,6 @@ type ListExampleAutoIncrementTableRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListExampleAutoIncrementTableRequest_IndexKey_Id_ // *ListExampleAutoIncrementTableRequest_IndexKey_X_ Key isListExampleAutoIncrementTableRequest_IndexKey_Key `protobuf_oneof:"key"` @@ -2361,7 +2354,6 @@ type ListExampleTimestampRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListExampleTimestampRequest_IndexKey_Id_ // *ListExampleTimestampRequest_IndexKey_Ts_ Key isListExampleTimestampRequest_IndexKey_Key `protobuf_oneof:"key"` @@ -2606,7 +2598,6 @@ type ListSimpleExampleRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListSimpleExampleRequest_IndexKey_Name_ // *ListSimpleExampleRequest_IndexKey_Unique_ Key isListSimpleExampleRequest_IndexKey_Key `protobuf_oneof:"key"` @@ -2851,7 +2842,6 @@ type ListExampleAutoIncFieldNameRequest_IndexKey struct { // key specifies the index key value. // // Types that are assignable to Key: - // // *ListExampleAutoIncFieldNameRequest_IndexKey_Foo_ Key isListExampleAutoIncFieldNameRequest_IndexKey_Key `protobuf_oneof:"key"` } diff --git a/orm/internal/testpb/test_schema_query.proto b/orm/internal/testpb/test_schema_query.proto index c6f79a59f7..8371c3e1fa 100644 --- a/orm/internal/testpb/test_schema_query.proto +++ b/orm/internal/testpb/test_schema_query.proto @@ -15,17 +15,13 @@ service TestSchemaQueryService { // ListExampleTable queries the ExampleTable table using prefix and range queries against defined indexes. rpc ListExampleTable(ListExampleTableRequest) returns (ListExampleTableResponse) {} // Get queries the ExampleAutoIncrementTable table by its primary key. - rpc GetExampleAutoIncrementTable(GetExampleAutoIncrementTableRequest) returns (GetExampleAutoIncrementTableResponse) { - } + rpc GetExampleAutoIncrementTable(GetExampleAutoIncrementTableRequest) returns (GetExampleAutoIncrementTableResponse) {} // GetExampleAutoIncrementTableByX queries the ExampleAutoIncrementTable table by its X index - rpc GetExampleAutoIncrementTableByX(GetExampleAutoIncrementTableByXRequest) - returns (GetExampleAutoIncrementTableByXResponse) {} - // ListExampleAutoIncrementTable queries the ExampleAutoIncrementTable table using prefix and range queries against - // defined indexes. - rpc ListExampleAutoIncrementTable(ListExampleAutoIncrementTableRequest) - returns (ListExampleAutoIncrementTableResponse) {} + rpc GetExampleAutoIncrementTableByX(GetExampleAutoIncrementTableByXRequest) returns (GetExampleAutoIncrementTableByXResponse) {} + // ListExampleAutoIncrementTable queries the ExampleAutoIncrementTable table using prefix and range queries against defined indexes. + rpc ListExampleAutoIncrementTable(ListExampleAutoIncrementTableRequest) returns (ListExampleAutoIncrementTableResponse) {} // GetExampleSingleton queries the ExampleSingleton singleton. - rpc GetExampleSingleton(GetExampleSingletonRequest) returns (GetExampleSingletonResponse) {} + rpc GetExampleSingleton (GetExampleSingletonRequest) returns (GetExampleSingletonResponse) {} // Get queries the ExampleTimestamp table by its primary key. rpc GetExampleTimestamp(GetExampleTimestampRequest) returns (GetExampleTimestampResponse) {} // ListExampleTimestamp queries the ExampleTimestamp table using prefix and range queries against defined indexes. @@ -38,8 +34,7 @@ service TestSchemaQueryService { rpc ListSimpleExample(ListSimpleExampleRequest) returns (ListSimpleExampleResponse) {} // Get queries the ExampleAutoIncFieldName table by its primary key. rpc GetExampleAutoIncFieldName(GetExampleAutoIncFieldNameRequest) returns (GetExampleAutoIncFieldNameResponse) {} - // ListExampleAutoIncFieldName queries the ExampleAutoIncFieldName table using prefix and range queries against - // defined indexes. + // ListExampleAutoIncFieldName queries the ExampleAutoIncFieldName table using prefix and range queries against defined indexes. rpc ListExampleAutoIncFieldName(ListExampleAutoIncFieldNameRequest) returns (ListExampleAutoIncFieldNameResponse) {} } @@ -85,7 +80,7 @@ message ListExampleTableRequest { // bz_str specifies the value of the BzStr index key to use in the query. BzStr bz_str = 4; } - + message U32I64Str { // u32 is the value of the u32 field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. @@ -97,7 +92,7 @@ message ListExampleTableRequest { // It can be omitted to query for all valid values of that field in this segment of the index. optional string str = 3; } - + message U64Str { // u64 is the value of the u64 field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. @@ -106,7 +101,7 @@ message ListExampleTableRequest { // It can be omitted to query for all valid values of that field in this segment of the index. optional string str = 2; } - + message StrU32 { // str is the value of the str field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. @@ -115,7 +110,7 @@ message ListExampleTableRequest { // It can be omitted to query for all valid values of that field in this segment of the index. optional uint32 u32 = 2; } - + message BzStr { // bz is the value of the bz field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. @@ -125,7 +120,7 @@ message ListExampleTableRequest { optional string str = 2; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -135,7 +130,7 @@ message ListExampleTableRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -189,20 +184,20 @@ message ListExampleAutoIncrementTableRequest { // x specifies the value of the X index key to use in the query. X x = 2; } - + message Id { // id is the value of the id field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional uint64 id = 1; } - + message X { // x is the value of the x field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional string x = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -212,7 +207,7 @@ message ListExampleAutoIncrementTableRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -234,7 +229,8 @@ message ListExampleAutoIncrementTableResponse { } // GetExampleSingletonRequest is the TestSchemaQuery/GetExampleSingletonRequest request type. -message GetExampleSingletonRequest {} +message GetExampleSingletonRequest { +} // GetExampleSingletonResponse is the TestSchemaQuery/GetExampleSingletonResponse request type. message GetExampleSingletonResponse { @@ -264,20 +260,20 @@ message ListExampleTimestampRequest { // ts specifies the value of the Ts index key to use in the query. Ts ts = 2; } - + message Id { // id is the value of the id field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional uint64 id = 1; } - + message Ts { // ts is the value of the ts field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional google.protobuf.Timestamp ts = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -287,7 +283,7 @@ message ListExampleTimestampRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -341,20 +337,20 @@ message ListSimpleExampleRequest { // unique specifies the value of the Unique index key to use in the query. Unique unique = 2; } - + message Name { // name is the value of the name field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional string name = 1; } - + message Unique { // unique is the value of the unique field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional string unique = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -364,7 +360,7 @@ message ListSimpleExampleRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -406,14 +402,14 @@ message ListExampleAutoIncFieldNameRequest { // foo specifies the value of the Foo index key to use in the query. Foo foo = 1; } - + message Foo { // foo is the value of the foo field in the index. // It can be omitted to query for all valid values of that field in this segment of the index. optional uint64 foo = 1; } } - + // query specifies the type of query - either a prefix or range query. oneof query { // prefix_query specifies the index key value to use for the prefix query. @@ -423,7 +419,7 @@ message ListExampleAutoIncFieldNameRequest { } // pagination specifies optional pagination parameters. cosmos.base.query.v1beta1.PageRequest pagination = 3; - + // RangeQuery specifies the from/to index keys for a range query. message RangeQuery { // from is the index key to use for the start of the range query. @@ -443,3 +439,4 @@ message ListExampleAutoIncFieldNameResponse { // pagination is the pagination response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } + diff --git a/orm/model/ormdb/file.go b/orm/model/ormdb/file.go index 3dcf1e4814..37c01bcb1f 100644 --- a/orm/model/ormdb/file.go +++ b/orm/model/ormdb/file.go @@ -3,6 +3,7 @@ package ormdb import ( "bytes" "encoding/binary" + "errors" "math" "google.golang.org/protobuf/reflect/protoregistry" @@ -67,6 +68,9 @@ func newFileDescriptorDB(fileDescriptor protoreflect.FileDescriptor, options fil JSONValidator: options.JSONValidator, BackendResolver: options.BackendResolver, }) + if errors.Is(err, ormerrors.NoTableDescriptor) { + continue + } if err != nil { return nil, err } diff --git a/orm/model/ormdb/module.go b/orm/model/ormdb/module.go index 5879f1b55c..0c2f71e114 100644 --- a/orm/model/ormdb/module.go +++ b/orm/model/ormdb/module.go @@ -98,16 +98,16 @@ func NewModuleDB(schema *ormv1alpha1.ModuleSchemaDescriptor, options ModuleDBOpt switch entry.StorageType { case ormv1alpha1.StorageType_STORAGE_TYPE_DEFAULT_UNSPECIFIED: service := options.KVStoreService - if service == nil { - return nil, fmt.Errorf("missing KVStoreService") - } - - backendResolver = func(ctx context.Context) (ormtable.ReadBackend, error) { - kvStore := service.OpenKVStore(ctx) - return ormtable.NewBackend(ormtable.BackendOptions{ - CommitmentStore: kvStore, - IndexStore: kvStore, - }), nil + if service != nil { + // for testing purposes, the ORM allows KVStoreService to be omitted + // and a default test backend can be used + backendResolver = func(ctx context.Context) (ormtable.ReadBackend, error) { + kvStore := service.OpenKVStore(ctx) + return ormtable.NewBackend(ormtable.BackendOptions{ + CommitmentStore: kvStore, + IndexStore: kvStore, + }), nil + } } case ormv1alpha1.StorageType_STORAGE_TYPE_MEMORY: service := options.MemoryStoreService diff --git a/orm/model/ormdb/module_test.go b/orm/model/ormdb/module_test.go index c558de88aa..9a27bf29ee 100644 --- a/orm/model/ormdb/module_test.go +++ b/orm/model/ormdb/module_test.go @@ -8,10 +8,16 @@ import ( "strings" "testing" + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + ormmodulev1alpha1 "cosmossdk.io/api/cosmos/orm/module/v1alpha1" ormv1alpha1 "cosmossdk.io/api/cosmos/orm/v1alpha1" + "cosmossdk.io/core/appconfig" + "cosmossdk.io/core/appmodule" "cosmossdk.io/core/store" dbm "github.com/cosmos/cosmos-db" + "cosmossdk.io/depinject" + "github.com/golang/mock/gomock" "github.com/cosmos/cosmos-sdk/orm/testing/ormmocks" @@ -19,6 +25,7 @@ import ( "gotest.tools/v3/assert" "gotest.tools/v3/golden" + _ "github.com/cosmos/cosmos-sdk/orm" // required for ORM module registration "github.com/cosmos/cosmos-sdk/orm/internal/testkv" "github.com/cosmos/cosmos-sdk/orm/internal/testpb" "github.com/cosmos/cosmos-sdk/orm/model/ormdb" @@ -31,6 +38,13 @@ import ( // These tests use a simulated bank keeper. Addresses and balances use // string and uint64 types respectively for simplicity. +func init() { + // this registers the test module with the module registry + appmodule.Register(&testpb.Module{}, + appmodule.Provide(NewKeeper), + ) +} + var TestBankSchema = &ormv1alpha1.ModuleSchemaDescriptor{ SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ { @@ -192,36 +206,7 @@ func TestModuleDB(t *testing.T) { k, err := NewKeeper(db) assert.NilError(t, err) - // mint coins - denom := "foo" - acct1 := "bob" - err = k.Mint(ctx, acct1, denom, 100) - assert.NilError(t, err) - bal, err := k.Balance(ctx, acct1, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(100), bal) - supply, err := k.Supply(ctx, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(100), supply) - - // send coins - acct2 := "sally" - err = k.Send(ctx, acct1, acct2, denom, 30) - bal, err = k.Balance(ctx, acct1, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(70), bal) - bal, err = k.Balance(ctx, acct2, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(30), bal) - - // burn coins - err = k.Burn(ctx, acct2, denom, 3) - bal, err = k.Balance(ctx, acct2, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(27), bal) - supply, err = k.Supply(ctx, denom) - assert.NilError(t, err) - assert.Equal(t, uint64(97), supply) + runSimpleBankTests(t, k, ctx) // check debug output golden.Assert(t, debugBuf.String(), "bank_scenario.golden") @@ -277,6 +262,39 @@ func TestModuleDB(t *testing.T) { testkv.AssertBackendsEqual(t, backend, backend2) } +func runSimpleBankTests(t *testing.T, k Keeper, ctx context.Context) { + // mint coins + denom := "foo" + acct1 := "bob" + err := k.Mint(ctx, acct1, denom, 100) + assert.NilError(t, err) + bal, err := k.Balance(ctx, acct1, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(100), bal) + supply, err := k.Supply(ctx, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(100), supply) + + // send coins + acct2 := "sally" + err = k.Send(ctx, acct1, acct2, denom, 30) + bal, err = k.Balance(ctx, acct1, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(70), bal) + bal, err = k.Balance(ctx, acct2, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(30), bal) + + // burn coins + err = k.Burn(ctx, acct2, denom, 3) + bal, err = k.Balance(ctx, acct2, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(27), bal) + supply, err = k.Supply(ctx, denom) + assert.NilError(t, err) + assert.Equal(t, uint64(97), supply) +} + func TestHooks(t *testing.T) { ctrl := gomock.NewController(t) db, err := ormdb.NewModuleDB(TestBankSchema, ormdb.ModuleDBOptions{}) @@ -344,13 +362,25 @@ type testStoreService struct { db dbm.DB } +func (t testStoreService) OpenKVStore(context.Context) store.KVStore { + return t.db +} + func (t testStoreService) OpenMemoryStore(context.Context) store.KVStore { return t.db } func TestGetBackendResolver(t *testing.T) { - _, err := ormdb.NewModuleDB(TestBankSchema, ormdb.ModuleDBOptions{}) - assert.ErrorContains(t, err, "missing KVStoreService") + _, err := ormdb.NewModuleDB(&ormv1alpha1.ModuleSchemaDescriptor{ + SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ + { + Id: 1, + ProtoFileName: testpb.File_testpb_bank_proto.Path(), + StorageType: ormv1alpha1.StorageType_STORAGE_TYPE_MEMORY, + }, + }, + }, ormdb.ModuleDBOptions{}) + assert.ErrorContains(t, err, "missing MemoryStoreService") _, err = ormdb.NewModuleDB(&ormv1alpha1.ModuleSchemaDescriptor{ SchemaFile: []*ormv1alpha1.ModuleSchemaDescriptor_FileEntry{ @@ -365,3 +395,23 @@ func TestGetBackendResolver(t *testing.T) { }) assert.NilError(t, err) } + +func ProvideTestRuntime() store.KVStoreService { + return testStoreService{db: dbm.NewMemDB()} +} + +func TestAppConfigModule(t *testing.T) { + appCfg := appconfig.Compose(&appv1alpha1.Config{ + Modules: []*appv1alpha1.ModuleConfig{ + {Name: "bank", Config: appconfig.WrapAny(&testpb.Module{})}, + {Name: "orm", Config: appconfig.WrapAny(&ormmodulev1alpha1.Module{})}, + }, + }) + var k Keeper + err := depinject.Inject(depinject.Configs( + appCfg, depinject.Provide(ProvideTestRuntime), + ), &k) + assert.NilError(t, err) + + runSimpleBankTests(t, k, context.Background()) +} diff --git a/orm/model/ormtable/build.go b/orm/model/ormtable/build.go index 072e340a52..4b9dae4f8a 100644 --- a/orm/model/ormtable/build.go +++ b/orm/model/ormtable/build.go @@ -132,7 +132,7 @@ func Build(options Options) (Table, error) { return &singleton{table}, nil default: - return nil, ormerrors.InvalidTableDefinition.Wrapf("missing table descriptor for %s", messageDescriptor.FullName()) + return nil, ormerrors.NoTableDescriptor.Wrapf("missing table descriptor for %s", messageDescriptor.FullName()) } tableId := tableDesc.Id diff --git a/orm/orm.go b/orm/orm.go new file mode 100644 index 0000000000..558a061c74 --- /dev/null +++ b/orm/orm.go @@ -0,0 +1,69 @@ +package orm + +import ( + "fmt" + + appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1" + modulev1alpha1 "cosmossdk.io/api/cosmos/orm/module/v1alpha1" + ormv1alpha1 "cosmossdk.io/api/cosmos/orm/v1alpha1" + "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/store" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoregistry" + + "cosmossdk.io/depinject" + + "github.com/cosmos/cosmos-sdk/orm/model/ormdb" + "github.com/cosmos/cosmos-sdk/orm/model/ormtable" +) + +func init() { + appmodule.Register(&modulev1alpha1.Module{}, + appmodule.Provide(ProvideModuleDB), + ) +} + +// ModuleDBInputs are the inputs to ProvideModuleDB. NOTE: this is intended to be used by depinject. +type ModuleDBInputs struct { + depinject.In + + AppConfig *appv1alpha1.Config + KVStoreService store.KVStoreService + MemoryStoreService store.MemoryStoreService `optional:"true"` + TransientStoreService store.TransientStoreService `optional:"true"` + TypeResolver ormtable.TypeResolver `optional:"true"` + FileResolver protodesc.Resolver `optional:"true"` +} + +// ProvideModuleDB provides an ORM ModuleDB scoped to a module. NOTE: this is intended to be used by depinject. +func ProvideModuleDB(moduleKey depinject.ModuleKey, inputs ModuleDBInputs) (ormdb.ModuleDB, error) { + for _, module := range inputs.AppConfig.Modules { + if module.Name == moduleKey.Name() { + typeResolver := inputs.TypeResolver + if typeResolver == nil { + typeResolver = protoregistry.GlobalTypes + } + + modTyp, err := typeResolver.FindMessageByURL(module.Config.TypeUrl) + if err != nil { + return nil, err + } + + modSchema := proto.GetExtension(modTyp.Descriptor().Options(), ormv1alpha1.E_ModuleSchema).(*ormv1alpha1.ModuleSchemaDescriptor) + if modSchema == nil { + return nil, fmt.Errorf("no schema for module %s", moduleKey.Name()) + } + + return ormdb.NewModuleDB(modSchema, ormdb.ModuleDBOptions{ + TypeResolver: inputs.TypeResolver, + FileResolver: inputs.FileResolver, + KVStoreService: inputs.KVStoreService, + MemoryStoreService: inputs.MemoryStoreService, + TransientStoreService: inputs.TransientStoreService, + }) + } + } + + return nil, fmt.Errorf("unable to find config for module %s", moduleKey.Name()) +} diff --git a/orm/types/ormerrors/errors.go b/orm/types/ormerrors/errors.go index d62d1f0ba2..ef4dac26e0 100644 --- a/orm/types/ormerrors/errors.go +++ b/orm/types/ormerrors/errors.go @@ -43,4 +43,5 @@ var ( ReadOnly = errors.New(codespace, 30, "database is read-only") AlreadyExists = errors.RegisterWithGRPCCode(codespace, 31, codes.AlreadyExists, "already exists") ConstraintViolation = errors.RegisterWithGRPCCode(codespace, 32, codes.FailedPrecondition, "failed precondition") + NoTableDescriptor = errors.New(codespace, 33, "no table descriptor found") ) diff --git a/proto/cosmos/orm/module/v1alpha1/module.proto b/proto/cosmos/orm/module/v1alpha1/module.proto index cb7bbbeeaf..d8e7fa1f48 100644 --- a/proto/cosmos/orm/module/v1alpha1/module.proto +++ b/proto/cosmos/orm/module/v1alpha1/module.proto @@ -5,8 +5,8 @@ package cosmos.orm.module.v1alpha1; import "cosmos/app/v1alpha1/module.proto"; // Module defines the ORM module which adds providers to the app container for -// module-scoped DB's. In the future it may provide gRPC services for interacting -// with ORM data. +// ORM ModuleDB's and in the future will automatically register query +// services for modules that use the ORM. message Module { option (cosmos.app.v1alpha1.module) = { go_import: "github.com/cosmos/cosmos-sdk/orm"