cosmos-sdk/orm/model/ormtable/backend.go

157 lines
4.2 KiB
Go

package ormtable
import (
"context"
"github.com/cosmos/cosmos-sdk/orm/types/kv"
)
// ReadBackend defines the type used for read-only ORM operations.
type ReadBackend interface {
// CommitmentStoreReader returns the reader for the commitment store.
CommitmentStoreReader() kv.ReadonlyStore
// IndexStoreReader returns the reader for the index store.
IndexStoreReader() kv.ReadonlyStore
private()
}
// Backend defines the type used for read-write ORM operations.
// Unlike ReadBackend, write access to the underlying kv-store
// is hidden so that this can be fully encapsulated by the ORM.
type Backend interface {
ReadBackend
// CommitmentStore returns the merklized commitment store.
CommitmentStore() kv.Store
// IndexStore returns the index store if a separate one exists,
// otherwise it the commitment store.
IndexStore() kv.Store
// Hooks returns a Hooks instance or nil.
Hooks() Hooks
}
// ReadBackendOptions defines options for creating a ReadBackend.
// Read context can optionally define two stores - a commitment store
// that is backed by a merkle tree and an index store that isn't.
// If the index store is not defined, the commitment store will be
// used for all operations.
type ReadBackendOptions struct {
// CommitmentStoreReader is a reader for the commitment store.
CommitmentStoreReader kv.ReadonlyStore
// IndexStoreReader is an optional reader for the index store.
// If it is nil the CommitmentStoreReader will be used.
IndexStoreReader kv.ReadonlyStore
}
type readBackend struct {
commitmentReader kv.ReadonlyStore
indexReader kv.ReadonlyStore
}
func (r readBackend) CommitmentStoreReader() kv.ReadonlyStore {
return r.commitmentReader
}
func (r readBackend) IndexStoreReader() kv.ReadonlyStore {
return r.indexReader
}
func (readBackend) private() {}
// NewReadBackend creates a new ReadBackend.
func NewReadBackend(options ReadBackendOptions) ReadBackend {
indexReader := options.IndexStoreReader
if indexReader == nil {
indexReader = options.CommitmentStoreReader
}
return &readBackend{
commitmentReader: options.CommitmentStoreReader,
indexReader: indexReader,
}
}
type backend struct {
commitmentStore kv.Store
indexStore kv.Store
hooks Hooks
}
func (backend) private() {}
func (c backend) CommitmentStoreReader() kv.ReadonlyStore {
return c.commitmentStore
}
func (c backend) IndexStoreReader() kv.ReadonlyStore {
return c.indexStore
}
func (c backend) CommitmentStore() kv.Store {
return c.commitmentStore
}
func (c backend) IndexStore() kv.Store {
return c.indexStore
}
func (c backend) Hooks() Hooks {
return c.hooks
}
// BackendOptions defines options for creating a Backend.
// Context can optionally define two stores - a commitment store
// that is backed by a merkle tree and an index store that isn't.
// If the index store is not defined, the commitment store will be
// used for all operations.
type BackendOptions struct {
// CommitmentStore is the commitment store.
CommitmentStore kv.Store
// IndexStore is the optional index store.
// If it is nil the CommitmentStore will be used.
IndexStore kv.Store
// Hooks are optional hooks into ORM insert, update and delete operations.
Hooks Hooks
}
// NewBackend creates a new Backend.
func NewBackend(options BackendOptions) Backend {
indexStore := options.IndexStore
if indexStore == nil {
indexStore = options.CommitmentStore
}
return &backend{
commitmentStore: options.CommitmentStore,
indexStore: indexStore,
hooks: options.Hooks,
}
}
// WrapContextDefault performs the default wrapping of a backend in a context.
// This should be used primarily for testing purposes and production code
// should use some other framework specific wrapping (for instance using
// "store keys").
func WrapContextDefault(backend ReadBackend) context.Context {
return context.WithValue(context.Background(), defaultContextKey, backend)
}
type contextKeyType string
var defaultContextKey = contextKeyType("backend")
func getBackendDefault(ctx context.Context) (Backend, error) {
return ctx.Value(defaultContextKey).(Backend), nil
}
func getReadBackendDefault(ctx context.Context) (ReadBackend, error) {
return ctx.Value(defaultContextKey).(ReadBackend), nil
}