mukan-sdk/x/group/internal/orm/primary_key.go
Mukan Erkin Törük abb1ff956e
Some checks are pending
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
refactor: complete sovereign stack cleanup — all github.com upstream refs purged
2026-05-11 03:46:06 +03:00

164 lines
6.4 KiB
Go

package orm
import (
"github.com/cosmos/gogoproto/proto"
storetypes "cosmossdk.io/store/types"
"git.cw.tr/mukan-network/mukan-sdk/codec"
)
var (
_ Indexable = &PrimaryKeyTable{}
_ TableExportable = &PrimaryKeyTable{}
)
// PrimaryKeyTable provides simpler object style orm methods without passing database RowIDs.
// Entries are persisted and loaded with a reference to their unique primary key.
type PrimaryKeyTable struct {
*table
}
// NewPrimaryKeyTable creates a new PrimaryKeyTable.
func NewPrimaryKeyTable(prefixData [2]byte, model PrimaryKeyed, cdc codec.Codec) (*PrimaryKeyTable, error) {
table, err := newTable(prefixData, model, cdc)
if err != nil {
return nil, err
}
return &PrimaryKeyTable{
table: table,
}, nil
}
// PrimaryKeyed defines an object type that is aware of its immutable primary key.
type PrimaryKeyed interface {
// PrimaryKeyFields returns the fields of the object that will make up
// the primary key. The PrimaryKey function will encode and concatenate
// the fields to build the primary key.
//
// PrimaryKey parts can be []byte, string, and uint64 types. []byte is
// encoded with a length prefix, strings are null-terminated, and
// uint64 are encoded using 8 byte big endian.
//
// IMPORTANT: []byte parts are encoded with a single byte length prefix,
// so cannot be longer than 255 bytes.
PrimaryKeyFields() []any
proto.Message
}
// PrimaryKey returns the immutable and serialized primary key of this object.
// The primary key has to be unique within it's domain so that not two with same
// value can exist in the same table. This means PrimaryKeyFields() has to
// return a unique value for each object.
func PrimaryKey(obj PrimaryKeyed) []byte {
fields := obj.PrimaryKeyFields()
key, err := buildKeyFromParts(fields)
if err != nil {
panic(err)
}
return key
}
// Create persists the given object under their primary key. It checks if the
// key already exists and may return an `ErrUniqueConstraint`.
//
// Create iterates through the registered callbacks that may add secondary
// index keys.
func (a PrimaryKeyTable) Create(store storetypes.KVStore, obj PrimaryKeyed) error {
rowID := PrimaryKey(obj)
return a.table.Create(store, rowID, obj)
}
// Update updates the given object under the primary key. It expects the key to
// exists already and fails with an `ErrNotFound` otherwise. Any caller must
// therefore make sure that this contract is fulfilled. Parameters must not be
// nil.
//
// Update iterates through the registered callbacks that may add or remove
// secondary index keys.
func (a PrimaryKeyTable) Update(store storetypes.KVStore, newValue PrimaryKeyed) error {
return a.table.Update(store, PrimaryKey(newValue), newValue)
}
// Set persists the given object under the rowID key. It does not check if the
// key already exists and overwrites the value if it does.
//
// Set iterates through the registered callbacks that may add secondary index
// keys.
func (a PrimaryKeyTable) Set(store storetypes.KVStore, newValue PrimaryKeyed) error {
return a.table.Set(store, PrimaryKey(newValue), newValue)
}
// Delete removes the object. It expects the primary key to exists already and
// fails with a `ErrNotFound` otherwise. Any caller must therefore make sure
// that this contract is fulfilled.
//
// Delete iterates through the registered callbacks that remove secondary index
// keys.
func (a PrimaryKeyTable) Delete(store storetypes.KVStore, obj PrimaryKeyed) error {
return a.table.Delete(store, PrimaryKey(obj))
}
// Has checks if a key exists. Always returns false on nil or empty key.
func (a PrimaryKeyTable) Has(store storetypes.KVStore, primaryKey RowID) bool {
return a.table.Has(store, primaryKey)
}
// Contains returns true when an object with same type and primary key is persisted in this table.
func (a PrimaryKeyTable) Contains(store storetypes.KVStore, obj PrimaryKeyed) bool {
if err := assertCorrectType(a.model, obj); err != nil {
return false
}
return a.table.Has(store, PrimaryKey(obj))
}
// GetOne loads the object persisted for the given primary Key into the dest parameter.
// If none exists `ErrNotFound` is returned instead. Parameters must not be nil.
func (a PrimaryKeyTable) GetOne(store storetypes.KVStore, primKey RowID, dest proto.Message) error {
return a.table.GetOne(store, primKey, dest)
}
// PrefixScan returns an Iterator over a domain of keys in ascending order. End is exclusive.
// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned.
// Iterator must be closed by caller.
// To iterate over entire domain, use PrefixScan(nil, nil)
//
// WARNING: The use of a PrefixScan can be very expensive in terms of Gas. Please make sure you do not expose
// this as an endpoint to the public without further limits.
// Example:
//
// it, err := idx.PrefixScan(ctx, start, end)
// if err !=nil {
// return err
// }
// const defaultLimit = 20
// it = LimitIterator(it, defaultLimit)
//
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
func (a PrimaryKeyTable) PrefixScan(store storetypes.KVStore, start, end []byte) (Iterator, error) {
return a.table.PrefixScan(store, start, end)
}
// ReversePrefixScan returns an Iterator over a domain of keys in descending order. End is exclusive.
// Start is an MultiKeyIndex key or prefix. It must be less than end, or the Iterator is invalid and error is returned.
// Iterator must be closed by caller.
// To iterate over entire domain, use PrefixScan(nil, nil)
//
// WARNING: The use of a ReversePrefixScan can be very expensive in terms of Gas. Please make sure you do not expose
// this as an endpoint to the public without further limits. See `LimitIterator`
//
// CONTRACT: No writes may happen within a domain while an iterator exists over it.
func (a PrimaryKeyTable) ReversePrefixScan(store storetypes.KVStore, start, end []byte) (Iterator, error) {
return a.table.ReversePrefixScan(store, start, end)
}
// Export stores all the values in the table in the passed ModelSlicePtr.
func (a PrimaryKeyTable) Export(store storetypes.KVStore, dest ModelSlicePtr) (uint64, error) {
return a.table.Export(store, dest)
}
// Import clears the table and initializes it from the given data interface{}.
// data should be a slice of structs that implement PrimaryKeyed.
func (a PrimaryKeyTable) Import(store storetypes.KVStore, data any, seqValue uint64) error {
return a.table.Import(store, data, seqValue)
}