Skip to content

Commit

Permalink
feat(collections): add NewSchemaBuilderFromAccessor function (cosmos#…
Browse files Browse the repository at this point in the history
…15271)

Co-authored-by: testinginprod <[email protected]>
  • Loading branch information
testinginprod and testinginprod authored Mar 6, 2023
1 parent 183dde8 commit 3b40a62
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
2 changes: 0 additions & 2 deletions collections/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.20
require (
cosmossdk.io/core v0.6.0
github.com/cosmos/cosmos-db v1.0.0-rc.1
github.com/hashicorp/go-multierror v1.1.1 // TODO: remove with go 1.20 release
github.com/stretchr/testify v1.8.2
pgregory.net/rapid v0.5.5
)
Expand All @@ -28,7 +27,6 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
Expand Down
5 changes: 0 additions & 5 deletions collections/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,6 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
Expand Down
33 changes: 22 additions & 11 deletions collections/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,34 @@ import (
"cosmossdk.io/core/appmodule"

"cosmossdk.io/core/store"

"github.com/hashicorp/go-multierror"
)

// SchemaBuilder is used for building schemas. The Build method should always
// be called after all collections have been initialized. Initializing new
// collections with the builder after initialization will result in panics.
type SchemaBuilder struct {
schema *Schema
err *multierror.Error
err error
}

// NewSchemaBuilder creates a new schema builder from the provided store key.
// Callers should always call the SchemaBuilder.Build method when they are
// done adding collections to the schema.
func NewSchemaBuilder(service store.KVStoreService) *SchemaBuilder {
// NewSchemaBuilderFromAccessor creates a new schema builder from the provided store accessor function.
func NewSchemaBuilderFromAccessor(accessorFunc func(ctx context.Context) store.KVStore) *SchemaBuilder {
return &SchemaBuilder{
schema: &Schema{
storeAccessor: service.OpenKVStore,
storeAccessor: accessorFunc,
collectionsByName: map[string]collection{},
collectionsByPrefix: map[string]collection{},
},
}
}

// NewSchemaBuilder creates a new schema builder from the provided store key.
// Callers should always call the SchemaBuilder.Build method when they are
// done adding collections to the schema.
func NewSchemaBuilder(service store.KVStoreService) *SchemaBuilder {
return NewSchemaBuilderFromAccessor(service.OpenKVStore)
}

// Build should be called after all collections that are part of the schema
// have been initialized in order to get a reference to the Schema. It is
// important to check the returned error for any initialization errors.
Expand Down Expand Up @@ -86,24 +89,32 @@ func (s *SchemaBuilder) addCollection(collection collection) {
name := collection.getName()

if _, ok := s.schema.collectionsByPrefix[string(prefix)]; ok {
s.err = multierror.Append(s.err, fmt.Errorf("prefix %v already taken within schema", prefix))
s.appendError(fmt.Errorf("prefix %v already taken within schema", prefix))
return
}

if _, ok := s.schema.collectionsByName[name]; ok {
s.err = multierror.Append(s.err, fmt.Errorf("name %s already taken within schema", name))
s.appendError(fmt.Errorf("name %s already taken within schema", name))
return
}

if !nameRegex.MatchString(name) {
s.err = multierror.Append(s.err, fmt.Errorf("name must match regex %s, got %s", NameRegex, name))
s.appendError(fmt.Errorf("name must match regex %s, got %s", NameRegex, name))
return
}

s.schema.collectionsByPrefix[string(prefix)] = collection
s.schema.collectionsByName[name] = collection
}

func (s *SchemaBuilder) appendError(err error) {
if s.err == nil {
s.err = err
return
}
s.err = fmt.Errorf("%w\n%w", s.err, err)
}

// NameRegex is the regular expression that all valid collection names must match.
const NameRegex = "[A-Za-z][A-Za-z0-9_]*"

Expand Down

0 comments on commit 3b40a62

Please sign in to comment.