schema

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2024 License: Apache-2.0 Imports: 7 Imported by: 14

README

Logical State Schema Framework

The cosmossdk.io/schema base module is designed to provide a stable, zero-dependency base layer for specifying the logical representation of module state schemas and implementing state indexing. This is intended to be used primarily for indexing modules in external databases and providing a standard human-readable state representation for genesis import and export.

The schema defined in this library does not aim to be general purpose and cover all types of schemas, such as those used for defining transactions. For instance, this schema does not include many types of composite objects such as nested objects and arrays. Rather, the schema defined here aims to cover state schemas only which are implemented as key-value pairs and usually have direct mappings to relational database tables or objects in a document store.

Also, this schema does not cover physical state layout and byte-level encoding, but simply describes a common logical format.

HasModuleCodec Interface

Any module which supports logical decoding and/or encoding should implement the HasModuleCodec interface. This interface provides a way to get the codec for the module, which can be used to decode the module's state and/or apply logical updates.

State frameworks such as collections or orm should directly provide ModuleCodec implementations so that this functionality basically comes for free if a compatible framework is used. Modules that do not use one of these frameworks can choose to manually implement logical decoding and/or encoding.

Documentation

Index

Constants

View Source
const (
	// IntegerFormat is a regex that describes the format integer number strings must match. It specifies
	// that integers may have at most 100 digits.
	IntegerFormat = `^-?[0-9]{1,100}$`

	// DecimalFormat is a regex that describes the format decimal number strings must match. It specifies
	// that decimals may have at most 50 digits before and after the decimal point and may have an optional
	// exponent of up to 2 digits. These restrictions ensure that the decimal can be accurately represented
	// by a wide variety of implementations.
	DecimalFormat = `^-?[0-9]{1,50}(\.[0-9]{1,50})?([eE][-+]?[0-9]{1,2})?$`
)
View Source
const MAX_VALID_KIND = JSONKind

MAX_VALID_KIND is the maximum valid kind value.

View Source
const NameFormat = `^[a-zA-Z_][a-zA-Z0-9_]{0,63}$`

NameFormat is the regular expression that a name must match. A name must start with a letter or underscore and can only contain letters, numbers, and underscores. A name must be at least one character long and can be at most 64 characters long.

Variables

This section is empty.

Functions

func ValidateName

func ValidateName(name string) bool

ValidateName checks if the given name is a valid name conforming to NameFormat.

func ValidateObjectKey

func ValidateObjectKey(keyFields []Field, value interface{}, typeSet TypeSet) error

ValidateObjectKey validates that the value conforms to the set of fields as a Key in an StateObjectUpdate. See StateObjectUpdate.Key for documentation on the requirements of such keys.

func ValidateObjectValue

func ValidateObjectValue(valueFields []Field, value interface{}, typeSet TypeSet) error

ValidateObjectValue validates that the value conforms to the set of fields as a Value in an StateObjectUpdate. See StateObjectUpdate.Value for documentation on the requirements of such values.

Types

type APIDescriptor added in v0.4.0

type APIDescriptor struct {
	// Name is the versioned name of the API.
	Name string

	// Methods is the list of methods in the API.
	// It is a COMPATIBLE change to add new methods to an API.
	// If a newer client tries to call a method that an older server does not recognize it,
	// an error will simply be returned.
	Methods []MethodDescriptor
}

APIDescriptor is a public versioned descriptor of an API.

An APIDescriptor can be used as a native descriptor of an API's encoding. The native binary encoding of API requests and responses is to encode the input and output fields using value binary encoding. The native JSON encoding would be to encode the fields as a JSON object, canonically sorted by field name with no extra whitespace. Thus, APIDefinitions have deterministic binary and JSON encodings.

APIDefinitions have a strong definition of compatibility between different versions of the same API. It is an INCOMPATIBLE change to add new input fields to existing methods or to remove or modify existing input or output fields. Input fields also cannot reference any unsealed structs, directly or transitively, because these types allow adding new fields. Adding new input fields to a method introduces the possibility that a newer client will send an incomprehensible message to an older server. The only safe ways that input field schemas can be extended are by adding new values to EnumType's and new cases to OneOfType's. It is a COMPATIBLE change to add new methods to an API and to add new output fields to existing methods. Output fields can reference any sealed or unsealed StructType, directly or transitively.

Existing protobuf APIs could also be mapped into APIDefinitions, and used in the following ways: - to produce, user-friendly deterministic JSON - to produce a deterministic binary encoding - to check for compatibility in a way that is more appropriate to blockchain applications - to use any code generators designed to support this spec as an alternative to protobuf Also, a standardized way of serializing schema types as protobuf could be defined which maps to the original protobuf encoding, so that schemas can be used as an interop layer between different less expressive encoding systems.

Existing EVM contract APIs expressed in Solidity could be mapped into APIDefinitions, and a mapping of all schema values to ABI encoding could be defined which preserves the original ABI encoding.

In this way, we can define an interop layer between contracts in the EVM world, SDK modules accepting protobuf types, and any API using this schema system natively.

type EnumType added in v0.2.0

type EnumType struct {
	// Name is the name of the enum type.
	// It must conform to the NameFormat regular expression.
	// Its name must be unique between all enum types and object types in the module.
	// The same enum, however, can be used in multiple object types and fields as long as the
	// definition is identical each time.
	Name string `json:"name,omitempty"`

	// Values is a list of distinct, non-empty values that are part of the enum type.
	// Each value must conform to the NameFormat regular expression.
	Values []EnumValueDefinition `json:"values"`

	// NumericKind is the numeric kind used to represent the enum values numerically.
	// If it is left empty, Int32Kind is used by default.
	// Valid values are Uint8Kind, Int8Kind, Uint16Kind, Int16Kind, and Int32Kind.
	NumericKind Kind `json:"numeric_kind,omitempty"`
}

EnumType represents the definition of an enum type.

func (EnumType) GetNumericKind added in v0.2.0

func (e EnumType) GetNumericKind() Kind

GetNumericKind returns the numeric kind used to represent the enum values numerically. When EnumType.NumericKind is not set, the default value of Int32Kind is returned here.

func (EnumType) TypeName added in v0.2.0

func (e EnumType) TypeName() string

TypeName implements the Type interface.

func (EnumType) Validate added in v0.2.0

func (e EnumType) Validate(TypeSet) error

Validate validates the enum definition.

func (EnumType) ValidateValue added in v0.2.0

func (e EnumType) ValidateValue(value string) error

ValidateValue validates that the value is a valid enum value.

type EnumValueDefinition added in v0.2.0

type EnumValueDefinition struct {
	// Name is the name of the enum value.
	// It must conform to the NameFormat regular expression.
	// Its name must be unique between all values in the enum.
	Name string `json:"name"`

	// Value is the numeric value of the enum.
	// It must be unique between all values in the enum.
	Value int32 `json:"value"`
}

EnumValueDefinition represents a value in an enum type.

type Field

type Field struct {
	// Name is the name of the field. It must conform to the NameFormat regular expression.
	Name string `json:"name"`

	// Kind is the basic type of the field.
	Kind Kind `json:"kind"`

	// Nullable indicates whether null values are accepted for the field. Key fields CANNOT be nullable.
	Nullable bool `json:"nullable,omitempty"`

	// ReferencedType is the referenced type name when Kind is EnumKind, StructKind or OneOfKind.
	ReferencedType string `json:"referenced_type,omitempty"`

	// ElementKind is the element type when Kind is ListKind.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	ElementKind Kind `json:"element_kind,omitempty"`

	// Size specifies the size or max-size of a field.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// Its specific meaning may vary depending on the field kind.
	// For IntNKind and UintNKind fields, it specifies the bit width of the field.
	// For StringKind, BytesKind, AddressKind, and JSONKind, fields it specifies the maximum length rather than a fixed length.
	// If it is 0, such fields have no maximum length.
	// It is invalid to have a non-zero Size for other kinds.
	Size uint32 `json:"size,omitempty"`
}

Field represents a field in an object type.

func (Field) Validate

func (c Field) Validate(typeSet TypeSet) error

Validate validates the field.

func (Field) ValidateValue

func (c Field) ValidateValue(value interface{}, typeSet TypeSet) error

ValidateValue validates that the value conforms to the field's kind and nullability. Unlike Kind.ValidateValue, it also checks that the value conforms to the EnumType if the field is an EnumKind.

type HasModuleCodec

type HasModuleCodec interface {
	// ModuleCodec returns a ModuleCodec for the module.
	ModuleCodec() (ModuleCodec, error)
}

HasModuleCodec is an interface that modules can implement to provide a ModuleCodec. Usually these modules would also implement appmodule.AppModule, but that is not included to keep this package free of any dependencies.

type KVDecoder

type KVDecoder = func(KVPairUpdate) ([]StateObjectUpdate, error)

KVDecoder is a function that decodes a key-value pair into one or more StateObjectUpdate's. If the KV-pair doesn't represent object updates, the function should return nil as the first and no error. The error result should only be non-nil when the decoder expected to parse a valid update and was unable to. In the case of an error, the decoder may return a non-nil value for the first return value, which can indicate which parts of the update were decodable to aid debugging.

type KVPairUpdate

type KVPairUpdate = struct {
	// Key is the key of the key-value pair.
	Key []byte

	// Value is the value of the key-value pair. It should be ignored when Remove is true.
	Value []byte

	// Remove is a flag that indicates that the key-value pair was deleted. If it is false,
	// then it is assumed that this has been a set operation.
	Remove bool
}

KVPairUpdate represents a key-value pair set or delete.

type Kind

type Kind int

Kind represents the basic type of a field in an object. Each kind defines the following encodings:

- Go Encoding: the golang type which should be accepted by listeners and generated by decoders when providing entity updates. - JSON Encoding: the JSON encoding which should be used when encoding the field to JSON. - Key Binary Encoding: the encoding which should be used when encoding the field as a key in binary messages. Some encodings specify a terminal and non-terminal form depending on whether or not the field is the last field in the key. - Value Binary Encoding: the encoding which should be used when encoding the field as a value in binary messages.

When there is some non-determinism in an encoding, kinds should specify what values they accept and also what is the canonical, deterministic encoding which should be preferably emitted by serializers.

Binary encodings were chosen based on what is likely to be the most convenient default binary encoding for state management implementations. This encoding allows for sorted keys whenever it is possible for a kind and is deterministic. Modules that use the specified encoding natively will have a trivial decoder implementation because the encoding is already in the correct format after any initial prefix bytes are stripped.

const (
	// InvalidKind indicates that an invalid type.
	InvalidKind Kind = iota

	// StringKind is a string type.
	// Go Encoding: UTF-8 string with no null characters.
	// JSON Encoding: string
	// Key Binary Encoding:
	//   non-terminal: UTF-8 string with no null characters suffixed with a null character
	//   terminal: UTF-8 string with no null characters
	// Value Binary Encoding: the same value binary encoding as BytesKind.
	StringKind

	// BytesKind represents a byte array.
	// Go Encoding: []byte
	// JSON Encoding: base64 encoded string, canonical values should be encoded with standard encoding and padding.
	// Either standard or URL encoding with or without padding should be accepted.
	// Key Binary Encoding:
	//   non-terminal: length prefixed bytes where the width of the length prefix is 1, 2, 3 or 4 bytes depending on
	//     the field's MaxLength (defaulting to 4 bytes).
	//     Length prefixes should be big-endian encoded.
	//     Values larger than 2^32 bytes are not supported (likely key-value stores impose a lower limit).
	//   terminal: raw bytes with no length prefix
	// Value Binary Encoding: two 32-bit unsigned little-endian integers, the first one representing the offset of the
	//   value in the buffer and the second one representing the length of the value.
	BytesKind

	// Int8Kind represents an 8-bit signed integer.
	// Go Encoding: int8
	// JSON Encoding: number
	// Key Binary Encoding: 1-byte two's complement encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 1-byte two's complement encoding.
	Int8Kind

	// Uint8Kind represents an 8-bit unsigned integer.
	// Go Encoding: uint8
	// JSON Encoding: number
	// Key Binary Encoding: 1-byte unsigned encoding.
	// Value Binary Encoding: 1-byte unsigned encoding.
	Uint8Kind

	// Int16Kind represents a 16-bit signed integer.
	// Go Encoding: int16
	// JSON Encoding: number
	// Key Binary Encoding: 2-byte two's complement big-endian encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 2 byte two's complement little-endian encoding.
	Int16Kind

	// Uint16Kind represents a 16-bit unsigned integer.
	// Go Encoding: uint16
	// JSON Encoding: number
	// Key Binary Encoding: 2-byte unsigned big-endian encoding.
	// Value Binary Encoding: 2-byte unsigned little-endian encoding.
	Uint16Kind

	// Int32Kind represents a 32-bit signed integer.
	// Go Encoding: int32
	// JSON Encoding: number
	// Key Binary Encoding: 4-byte two's complement big-endian encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 4-byte two's complement little-endian encoding.
	Int32Kind

	// Uint32Kind represents a 32-bit unsigned integer.
	// Go Encoding: uint32
	// JSON Encoding: number
	// Key Binary Encoding: 4-byte unsigned big-endian encoding.
	// Value Binary Encoding: 4-byte unsigned little-endian encoding.
	Uint32Kind

	// Int64Kind represents a 64-bit signed integer.
	// Go Encoding: int64
	// JSON Encoding: base10 integer string which matches the IntegerFormat regex
	// The canonical encoding should include no leading zeros.
	// Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 8-byte two's complement little-endian encoding.
	Int64Kind

	// Uint64Kind represents a 64-bit unsigned integer.
	// Go Encoding: uint64
	// JSON Encoding: base10 integer string which matches the IntegerFormat regex
	// Canonically encoded values should include no leading zeros.
	// Key Binary Encoding: 8-byte unsigned big-endian encoding.
	// Value Binary Encoding: 8-byte unsigned little-endian encoding.
	Uint64Kind

	// IntegerKind represents an arbitrary precision integer number.
	// Support for expressing the maximum bit precision of values will be added in the future.
	// Go Encoding: string which matches the IntegerFormat regex (unstable, subject to change).
	// JSON Encoding: base10 integer string
	// Canonically encoded values should include no leading zeros.
	// Equality comparison with integers should be done using numerical equality rather
	// than string equality.
	IntegerKind

	// DecimalKind represents an arbitrary precision decimal or integer number.
	// Support for optionally limiting the precision may be added in the future.
	// Go Encoding: string which matches the DecimalFormat regex
	// JSON Encoding: base10 decimal string
	// Canonically encoded values should include no leading zeros or trailing zeros,
	// and exponential notation with a lowercase 'e' should be used for any numbers
	// with an absolute value less than or equal to 1e-6 or greater than or equal to 1e6.
	// Equality comparison with decimals should be done using numerical equality rather
	// than string equality.
	DecimalKind

	// BoolKind represents a boolean true or false value.
	// Go Encoding: bool
	// JSON Encoding: boolean
	// Key Binary Encoding: 1-byte encoding where 0 is false and 1 is true.
	// Value Binary Encoding: 1-byte encoding where 0 is false and 1 is true.
	BoolKind

	// TimeKind represents a nanosecond precision UNIX time value (with zero representing January 1, 1970 UTC).
	// Its valid range is +/- 2^63 (the range of a 64-bit signed integer).
	// Go Encoding: time.Time
	// JSON Encoding: Any value IS0 8601 time stamp should be accepted.
	// Canonical values should be encoded with UTC time zone Z, nanoseconds should
	// be encoded with no trailing zeros, and T time values should always be present
	// even at 00:00:00.
	// Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 8-byte two's complement little-endian encoding.
	TimeKind

	// DurationKind represents the elapsed time between two nanosecond precision time values.
	// Its valid range is +/- 2^63 (the range of a 64-bit signed integer).
	// Go Encoding: time.Duration
	// JSON Encoding: the number of seconds as a decimal string with no trailing zeros followed by
	// a lowercase 's' character to represent seconds.
	// Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting.
	// Value Binary Encoding: 8-byte two's complement little-endian encoding.
	DurationKind

	// Float32Kind represents an IEEE-754 32-bit floating point number.
	// Go Encoding: float32
	// JSON Encoding: number
	// Key Binary Encoding: 4-byte IEEE-754 encoding.
	// Value Binary Encoding: 4-byte IEEE-754 encoding.
	Float32Kind

	// Float64Kind represents an IEEE-754 64-bit floating point number.
	// Go Encoding: float64
	// JSON Encoding: number
	// Key Binary Encoding: 8-byte IEEE-754 encoding.
	// Value Binary Encoding: 8-byte IEEE-754 encoding.
	Float64Kind

	// AddressKind represents an account address which is represented by a variable length array of bytes.
	// Addresses usually have a human-readable rendering, such as bech32, and tooling should provide
	// a way for apps to define a string encoder for friendly user-facing display. Addresses have a maximum
	// supported length of 63 bytes.
	// Go Encoding: []byte
	// JSON Encoding: addresses should be encoded as strings using the human-readable address renderer
	// provided to the JSON encoder.
	// Key Binary Encoding:
	//   non-terminal: bytes prefixed with 1-byte length prefix
	//   terminal: raw bytes with no length prefix
	// Value Binary Encoding: bytes prefixed with 1-byte length prefix.
	AddressKind

	// EnumKind represents a value of an enum type.
	// Fields of this type are expected to set the EnumType field in the field definition to the enum
	// definition.
	// Go Encoding: string
	// JSON Encoding: string
	// Key Binary Encoding: the same binary encoding as the EnumType's numeric kind.
	// Value Binary Encoding: the same binary encoding as the EnumType's numeric kind.
	EnumKind

	// JSONKind represents arbitrary JSON data.
	// Go Encoding: json.RawMessage
	// JSON Encoding: any valid JSON value
	// Key Binary Encoding: string encoding
	// Value Binary Encoding: string encoding
	JSONKind

	// UIntNKind represents a signed integer type with a width in bits specified by the Size field in the
	// field definition.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific
	// types for these widths.
	// Go Encoding: []byte where len([]byte) == Size / 8, little-endian encoded.
	// JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros.
	// Key Binary Encoding: N / 8 bytes big-endian encoded
	// Value Binary Encoding: N / 8 bytes little-endian encoded
	UIntNKind

	// IntNKind represents an unsigned integer type with a width in bits specified by the Size field in the
	// field definition. N must be a multiple of 8.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific
	// types for these widths.
	// Go Encoding: []byte where len([]byte) == Size / 8, two's complement little-endian encoded.
	// JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros.
	// Key Binary Encoding: N / 8 bytes big-endian two's complement encoded with the first bit inverted for sorting.
	// Value Binary Encoding: N / 8 bytes little-endian two's complement encoded.
	IntNKind

	// StructKind represents a struct object.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// Go Encoding: an array of type []interface{} where each element is of the respective field's kind type.
	// JSON Encoding: an object where each key is the field name and the value is the field value.
	// Canonically, keys are in alphabetical order with no extra whitespace.
	// Key Binary Encoding: not valid as a key field.
	// Value Binary Encoding: 32-bit unsigned little-endian length prefix,
	// followed by the value binary encoding of each field in order.
	StructKind

	// OneOfKind represents a field that can be one of a set of types.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// Go Encoding: the anonymous struct { Case string; Value interface{} }, aliased as OneOfValue.
	// JSON Encoding: same as the case's struct encoding with "@type" set to the case name.
	// Key Binary Encoding: not valid as a key field.
	// Value Binary Encoding: the oneof's discriminant numeric value encoded as its discriminant kind
	// followed by the encoded value.
	OneOfKind

	// ListKind represents a list of elements.
	// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.
	// Go Encoding: an array of type []interface{} where each element is of the respective field's kind type.
	// JSON Encoding: an array of values where each element is the field value.
	// Canonically, there is no extra whitespace.
	// Key Binary Encoding: not valid as a key field.
	// Value Binary Encoding: 32-bit unsigned little-endian size prefix indicating the size of the encoded data in bytes,
	// followed by a 32-bit unsigned little-endian count of the number of elements in the list,
	// followed by each element encoded with value binary encoding.
	ListKind
)

func KindForGoValue

func KindForGoValue(value interface{}) Kind

KindForGoValue finds the simplest kind that can represent the given go value. It will not, however, return kinds such as IntegerKind, DecimalKind, AddressKind, or EnumKind which all can be represented as strings.

func (Kind) MarshalJSON added in v0.2.0

func (t Kind) MarshalJSON() ([]byte, error)

MarshalJSON marshals the kind to a JSON string and returns an error if the kind is invalid.

func (Kind) String

func (t Kind) String() string

String returns a string representation of the kind.

func (*Kind) UnmarshalJSON added in v0.2.0

func (t *Kind) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals the kind from a JSON string and returns an error if the kind is invalid.

func (Kind) ValidKeyKind added in v0.2.0

func (t Kind) ValidKeyKind() bool

ValidKeyKind returns true if the kind is a valid key kind. All kinds except Float32Kind, Float64Kind, and JSONKind are valid key kinds because they do not define a strict form of equality.

func (Kind) Validate

func (t Kind) Validate() error

Validate returns an errContains if the kind is invalid.

func (Kind) ValidateValue

func (t Kind) ValidateValue(value interface{}) error

ValidateValue returns an errContains if the value does not conform to the expected go type and format. It is more thorough, but slower, than Kind.ValidateValueType and validates that Integer, Decimal and JSON values are formatted correctly. It cannot validate enum values because Kind's do not have enum schemas.

func (Kind) ValidateValueType

func (t Kind) ValidateValueType(value interface{}) error

ValidateValueType returns an errContains if the value does not conform to the expected go type. Some fields may accept nil values, however, this method does not have any notion of nullability. This method only validates that the go type of the value is correct for the kind and does not validate string or json formats. Kind.ValidateValue does a more thorough validation of number and json string formatting.

type MapValueUpdates

type MapValueUpdates map[string]interface{}

MapValueUpdates is a map-based implementation of ValueUpdates which always iterates over keys in sorted order.

func (MapValueUpdates) Iterate

func (m MapValueUpdates) Iterate(fn func(col string, value interface{}) bool) error

Iterate implements the ValueUpdates interface.

type MethodDescriptor added in v0.4.0

type MethodDescriptor struct {
	// Name is the name of the method.
	Name string

	// InputFields is the list of input fields for the method.
	//
	// It is an INCOMPATIBLE change to add, remove or update input fields to a method.
	// The addition of new fields introduces the possibility that a newer client
	// will send an incomprehensible message to an older server.
	// InputFields can only reference sealed StructTypes, either directly and transitively.
	//
	// As a special case to represent protobuf service definitions, there can be a single
	// unnamed struct input field that code generators can choose to either reference
	// as a named struct or to expand inline as function arguments.
	InputFields []Field

	// OutputFields is the list of output fields for the method.
	//
	// It is a COMPATIBLE change to add new output fields to a method,
	// but existing output fields should not be removed or modified.
	// OutputFields can reference any sealed or unsealed StructType, directly or transitively.
	// If a newer client tries to call a method on an older server, the newer expected result output
	// fields will simply be populated with the default values for that field kind.
	//
	// As a special case to represent protobuf service definitions, there can be a single
	// unnamed struct output field.
	// In this case, adding new output fields is an INCOMPATIBLE change (because protobuf service definitions
	// don't allow this), but new fields can be added to the referenced struct if it is unsealed.
	OutputFields []Field

	// Volatility is the volatility of the method.
	Volatility Volatility
}

MethodDescriptor describes a method in the API.

type ModuleCodec

type ModuleCodec struct {
	// Schema is the schema for the module. It is required.
	Schema ModuleSchema

	// KVDecoder is a function that decodes a key-value pair into an StateObjectUpdate.
	// If it is nil, the module doesn't support state decoding directly.
	KVDecoder KVDecoder
}

ModuleCodec is a struct that contains the schema and a KVDecoder for a module.

type ModuleSchema

type ModuleSchema struct {
	// contains filtered or unexported fields
}

ModuleSchema represents the logical schema of a module for purposes of indexing and querying.

func CompileModuleSchema added in v0.2.0

func CompileModuleSchema(types ...Type) (ModuleSchema, error)

CompileModuleSchema compiles the types into a ModuleSchema and validates it. Any module schema returned without an error is guaranteed to be valid.

func MustCompileModuleSchema added in v0.2.0

func MustCompileModuleSchema(types ...Type) ModuleSchema

MustCompileModuleSchema constructs a new ModuleSchema and panics if it is invalid. This should only be used in test code or static initialization where it is safe to panic!

func (ModuleSchema) AllTypes added in v0.2.0

func (s ModuleSchema) AllTypes(f func(Type) bool)

AllTypes calls the provided function for each type in the module schema and stops if the function returns false. The types are iterated over in sorted order by name. This function is compatible with go 1.23 iterators.

func (ModuleSchema) EnumTypes added in v0.2.0

func (s ModuleSchema) EnumTypes(f func(EnumType) bool)

EnumTypes iterators over all the enum types in the schema in alphabetical order.

func (ModuleSchema) LookupEnumType added in v0.3.0

func (s ModuleSchema) LookupEnumType(name string) (t EnumType, found bool)

LookupEnumType is a convenience method that looks up an EnumType by name.

func (ModuleSchema) LookupStateObjectType added in v0.3.0

func (s ModuleSchema) LookupStateObjectType(name string) (t StateObjectType, found bool)

LookupObjectType is a convenience method that looks up an ObjectType by name.

func (ModuleSchema) LookupType added in v0.2.0

func (s ModuleSchema) LookupType(name string) (Type, bool)

LookupType looks up a type by name in the module schema.

func (ModuleSchema) MarshalJSON added in v0.2.0

func (s ModuleSchema) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for ModuleSchema. It marshals the module schema into a JSON object with the object types and enum types under the keys "object_types" and "enum_types" respectively.

func (ModuleSchema) StateObjectTypes added in v0.3.0

func (s ModuleSchema) StateObjectTypes(f func(StateObjectType) bool)

ObjectTypes iterators over all the object types in the schema in alphabetical order.

func (*ModuleSchema) UnmarshalJSON added in v0.2.0

func (s *ModuleSchema) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for ModuleSchema. See MarshalJSON for the JSON format.

func (ModuleSchema) Validate

func (s ModuleSchema) Validate() error

Validate validates the module schema.

func (ModuleSchema) ValidateObjectUpdate

func (s ModuleSchema) ValidateObjectUpdate(update StateObjectUpdate) error

ValidateObjectUpdate validates that the update conforms to the module schema.

type OneOfCase added in v0.4.0

type OneOfCase struct {
	// Name is the name of the case. It must conform to the NameFormat regular expression.
	Name string

	// Discriminant is the discriminant value for the case.
	Discriminant int32

	// Kind is the kind of the case. ListKind is not allowed.
	Kind Kind

	// Reference is the referenced type if Kind is EnumKind, StructKind, or OneOfKind.
	ReferencedType string
}

OneOfCase represents a case in a oneof type. It is represented by a struct type internally with a discriminant value.

type OneOfType added in v0.4.0

type OneOfType struct {
	// Name is the name of the oneof type. It must conform to the NameFormat regular expression.
	Name string

	// Cases is a list of cases in the oneof type.
	// It is a COMPATIBLE change to add new cases to a oneof type.
	// If a newer client tries to send a message with a case that an older server does not recognize,
	// the older server will simply reject it in a switch statement.
	// It is INCOMPATIBLE to remove existing cases from a oneof type.
	Cases []OneOfCase

	// DiscriminantKind is the kind of the discriminant field.
	// It must be Uint8Kind, Int8Kind, Uint16Kind, Int16Kind, or Int32Kind.
	DiscriminantKind Kind
}

OneOfType represents a oneof type. Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.

type OneOfValue added in v0.4.0

type OneOfValue = struct {
	// Case is the name of the case.
	Case string

	// Value is the value of the case.
	Value interface{}
}

OneOfValue is the golang runtime representation of a oneof value.

type ReferenceableType added in v0.4.0

type ReferenceableType interface {
	Type
	// contains filtered or unexported methods
}

ReferenceableType is a marker interface that all types that can be the target of Field.ReferencedType implement. Currently, this is only EnumType.

type StateObjectType added in v0.3.0

type StateObjectType struct {
	// Name is the name of the object type. It must be unique within the module schema amongst all object and enum
	// types and conform to the NameFormat regular expression.
	Name string `json:"name"`

	// KeyFields is a list of fields that make up the primary key of the object.
	// It can be empty, in which case, indexers should assume that this object is
	// a singleton and only has one value. Field names must be unique within the
	// object between both key and value fields.
	// Key fields CANNOT be nullable and Float32Kind, Float64Kind, JSONKind, StructKind,
	// OneOfKind, RepeatedKind, ListKind or ObjectKind
	// are NOT ALLOWED.
	// It is an INCOMPATIBLE change to add, remove or change fields in the key as this
	// changes the underlying primary key of the object.
	KeyFields []Field `json:"key_fields,omitempty"`

	// ValueFields is a list of fields that are not part of the primary key of the object.
	// It can be empty in the case where all fields are part of the primary key.
	// Field names must be unique within the object between both key and value fields.
	// ObjectKind fields are not allowed.
	// It is a COMPATIBLE change to add new value fields to an object type because
	// this does not affect the primary key of the object.
	// Existing value fields should not be removed or modified.
	ValueFields []Field `json:"value_fields,omitempty"`

	// RetainDeletions is a flag that indicates whether the indexer should retain
	// deleted rows in the database and flag them as deleted rather than actually
	// deleting the row. For many types of data in state, the data is deleted even
	// though it is still valid in order to save space. Indexers will want to have
	// the option of retaining such data and distinguishing from other "true" deletions.
	RetainDeletions bool `json:"retain_deletions,omitempty"`
}

StateObjectType describes an object type a module schema.

func (StateObjectType) TypeName added in v0.3.0

func (o StateObjectType) TypeName() string

TypeName implements the Type interface.

func (StateObjectType) Validate added in v0.3.0

func (o StateObjectType) Validate(typeSet TypeSet) error

Validate validates the object type.

func (StateObjectType) ValidateObjectUpdate added in v0.3.0

func (o StateObjectType) ValidateObjectUpdate(update StateObjectUpdate, typeSet TypeSet) error

ValidateObjectUpdate validates that the update conforms to the object type.

type StateObjectUpdate added in v0.3.0

type StateObjectUpdate struct {
	// TypeName is the name of the object type in the module's schema.
	TypeName string

	// Key returns the value of the primary key of the object and must conform to these constraints with respect
	// that the schema that is defined for the object:
	// - if key represents a single field, then the value must be valid for the first field in that
	// 	field list. For instance, if there is one field in the key of type String, then the value must be of
	//  type string
	// - if key represents multiple fields, then the value must be a slice of values where each value is valid
	//  for the corresponding field in the field list. For instance, if there are two fields in the key of
	//  type String, String, then the value must be a slice of two strings.
	// If the key has no fields, meaning that this is a singleton object, then this value is ignored and can be nil.
	Key interface{}

	// Value returns the non-primary key fields of the object and can either conform to the same constraints
	// as StateObjectUpdate.Key or it may be and instance of ValueUpdates. ValueUpdates can be used as a performance
	// optimization to avoid copying the values of the object into the update and/or to omit unchanged fields.
	// If this is a delete operation, then this value is ignored and can be nil.
	Value interface{}

	// Delete is a flag that indicates whether this update is a delete operation. If true, then the Value field
	// is ignored and can be nil.
	Delete bool
}

StateObjectUpdate represents an update operation on an object in a module's state.

type StructType added in v0.4.0

type StructType struct {
	// Name is the name of the struct type.
	Name string

	// Fields is the list of fields in the struct.
	// It is a COMPATIBLE change to add new fields to an unsealed struct,
	// but it is an INCOMPATIBLE change to add new fields to a sealed struct.
	//
	// A sealed struct cannot reference any unsealed structs directly or
	// transitively because these types allow adding new fields.
	Fields []Field

	// Sealed is true if it is an INCOMPATIBLE change to add new fields to the struct.
	// It is a COMPATIBLE change to change an unsealed struct to sealed, but it is
	// an INCOMPATIBLE change to change a sealed struct to unsealed.
	Sealed bool
}

StructType represents a struct type. Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added.

type Type added in v0.2.0

type Type interface {
	// TypeName returns the type's name.
	TypeName() string

	// Validate validates the type.
	Validate(TypeSet) error
	// contains filtered or unexported methods
}

Type is an interface that all types in the schema implement. Currently, these are StateObjectType and EnumType.

type TypeSet added in v0.2.0

type TypeSet interface {
	// LookupType looks up a type by name.
	LookupType(name string) (t Type, found bool)

	// LookupEnumType is a convenience method that looks up an EnumType by name.
	LookupEnumType(name string) (t EnumType, found bool)

	// LookupStateObjectType is a convenience method that looks up an StateObjectType by name.
	LookupStateObjectType(name string) (t StateObjectType, found bool)

	// AllTypes calls the given function for each type in the type set.
	// This function is compatible with go 1.23 iterators and can be used like this:
	// for t := range types.AllTypes {
	//     // do something with t
	// }
	AllTypes(f func(Type) bool)

	// EnumTypes calls the given function for each EnumType in the type set.
	// This function is compatible with go 1.23 iterators.
	EnumTypes(f func(EnumType) bool)

	// StateObjectTypes calls the given function for each StateObjectType in the type set.
	// This function is compatible with go 1.23 iterators.
	StateObjectTypes(f func(objectType StateObjectType) bool)
	// contains filtered or unexported methods
}

TypeSet represents something that has types and allows them to be looked up by name. Currently, the only implementation is ModuleSchema.

func EmptyTypeSet added in v0.2.0

func EmptyTypeSet() TypeSet

EmptyTypeSet is a schema that contains no types. It can be used in Validate methods when there is no schema needed or available.

type ValueUpdates

type ValueUpdates interface {
	// Iterate iterates over the fields and values in the object update. The function should return
	// true to continue iteration or false to stop iteration. Each field value should conform
	// to the requirements of that field's type in the schema. Iterate returns an error if
	// it was unable to decode the values properly (which could be the case in lazy evaluation).
	Iterate(func(col string, value interface{}) bool) error
}

ValueUpdates is an interface that represents the value fields of an object update. fields that were not updated may be excluded from the update. Consumers should be aware that implementations may not filter out fields that were unchanged. However, if a field is omitted from the update it should be considered unchanged.

type Volatility added in v0.4.0

type Volatility int

Volatility is the volatility of a method.

const (
	// PureVolatility indicates that the method can neither read nor write state.
	PureVolatility Volatility = iota
	// ReadonlyVolatility indicates that the method can read state but not write state.
	ReadonlyVolatility

	// VolatileVolatility indicates that the method can read and write state.
	VolatileVolatility
)

Directories

Path Synopsis
Package diff provides the CompareModuleSchemas function which compares module schemas and their types and generates a structured diff.
Package diff provides the CompareModuleSchemas function which compares module schemas and their types and generates a structured diff.
Package logutil defines the Logger interface expected by indexer implementations.
Package logutil defines the Logger interface expected by indexer implementations.
testing module
Package view defines interfaces for viewing the data stored in an indexer target or an app's original data store.
Package view defines interfaces for viewing the data stored in an indexer target or an app's original data store.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL