Documentation ¶
Overview ¶
Package ormtable defines the interfaces and implementations of tables and indexes.
Index ¶
- func DefaultJSONValidator(message proto.Message) error
- func WrapContextDefault(backend ReadBackend) context.Context
- type Backend
- type BackendOptions
- type Hooks
- type Index
- type Iterator
- type Options
- type PaginationRequest
- type PaginationResponse
- type ReadBackend
- type ReadBackendOptions
- type Table
- type TypeResolver
- type UniqueIndex
- type View
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultJSONValidator ¶
DefaultJSONValidator is the default validator used when calling Table.ValidateJSON(). It will call methods with the signature `ValidateBasic() error` and/or `Validate() error` to validate the message.
func WrapContextDefault ¶
func WrapContextDefault(backend ReadBackend) context.Context
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").
Types ¶
type Backend ¶
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 }
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 BackendOptions ¶
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 }
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 Hooks ¶
type Hooks interface { // OnInsert is called before the message is inserted. // If error is not nil the operation will fail. OnInsert(proto.Message) error // OnUpdate is called before the existing message is updated with the new one. // If error is not nil the operation will fail. OnUpdate(existing, new proto.Message) error // OnDelete is called before the message is deleted. // If error is not nil the operation will fail. OnDelete(proto.Message) error }
Hooks defines an interface for a table hooks which can intercept insert, update and delete operations. Table.Save and Table.Delete methods will do a type assertion on kvstore.IndexCommitmentStore and if the Hooks interface is defined call the appropriate hooks.
type Index ¶
type Index interface { // Iterator returns an iterator for this index with the provided list options. Iterator(ctx context.Context, options ...ormlist.Option) (Iterator, error) // MessageType returns the protobuf message type of the index. MessageType() protoreflect.MessageType // Fields returns the canonical field names of the index. Fields() string // contains filtered or unexported methods }
Index defines an index on a table. Index instances are stateless, with all state existing only in the store passed to index methods.
type Iterator ¶
type Iterator interface { // Next advances the iterator and returns true if a valid entry is found. // Next must be called before starting iteration. Next() bool // Keys returns the current index key and primary key values that the // iterator points to. Keys() (indexKey, primaryKey []protoreflect.Value, err error) // UnmarshalMessage unmarshals the entry the iterator currently points to // the provided proto.Message. UnmarshalMessage(proto.Message) error // GetMessage retrieves the proto.Message that the iterator currently points // to. GetMessage() (proto.Message, error) // Cursor returns the cursor referencing the current iteration position // and can be used to restart iteration right after this position. Cursor() ormlist.CursorT // Close closes the iterator and must always be called when done using // the iterator. The defer keyword should generally be used for this. Close() // contains filtered or unexported methods }
Iterator defines the interface for iterating over indexes.
type Options ¶
type Options struct { // Prefix is an optional prefix used to build the table's prefix. Prefix []byte // MessageType is the protobuf message type of the table. MessageType protoreflect.MessageType // TableDescriptor is an optional table descriptor to be explicitly used // with the table. Generally this should be nil and the table descriptor // should be pulled from the table message option. TableDescriptor // cannot be used together with SingletonDescriptor. TableDescriptor *ormv1alpha1.TableDescriptor // SingletonDescriptor is an optional singleton descriptor to be explicitly used. // Generally this should be nil and the table descriptor // should be pulled from the singleton message option. SingletonDescriptor // cannot be used together with TableDescriptor. SingletonDescriptor *ormv1alpha1.SingletonDescriptor // TypeResolver is an optional type resolver to be used when unmarshaling // protobuf messages. TypeResolver TypeResolver // JSONValidator is an optional validator that can be used for validating // messaging when using ValidateJSON. If it is nil, DefaultJSONValidator // will be used JSONValidator func(proto.Message) error // GetBackend is an optional function which retrieves a Backend from the context. // If it is nil, the default behavior will be to attempt to retrieve a // backend using the method that WrapContextDefault uses. This method // can be used to imlement things like "store keys" which would allow a // table to only be used with a specific backend and to hide direct // access to the backend other than through the table interface. GetBackend func(context.Context) (Backend, error) // GetReadBackend is an optional function which retrieves a ReadBackend from the context. // If it is nil, the default behavior will be to attempt to retrieve a // backend using the method that WrapContextDefault uses. GetReadBackend func(context.Context) (ReadBackend, error) }
Options are options for building a Table.
type PaginationRequest ¶
type PaginationRequest struct { *queryv1beta1.PageRequest // Filter is an optional filter function that can be used to filter // the results in the underlying iterator and should return true to include // an item in the result. Filter func(message proto.Message) bool }
PaginationRequest is a request to the Paginate function and extends the options in query.PageRequest.
type PaginationResponse ¶
type PaginationResponse struct { *queryv1beta1.PageResponse // HaveMore indicates whether there are more pages. HaveMore bool // Cursors returns a cursor for each item and can be used to implement // GraphQL connection edges. Cursors []ormlist.CursorT }
PaginationResponse is a response from the Paginate function and extends the options in query.PageResponse.
type ReadBackend ¶
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 // contains filtered or unexported methods }
ReadBackend defines the type used for read-only ORM operations.
func NewReadBackend ¶
func NewReadBackend(options ReadBackendOptions) ReadBackend
NewReadBackend creates a new ReadBackend.
type ReadBackendOptions ¶
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 }
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 Table ¶
type Table interface { View ormkv.EntryCodec // Save saves the provided entry in the store either inserting it or // updating it if needed. // // If store implement the Hooks interface, the appropriate OnInsert or // OnUpdate hook method will be called. // // Save attempts to be atomic with respect to the underlying store, // meaning that either the full save operation is written or the store is // left unchanged, unless there is an error with the underlying store. Save(context context.Context, message proto.Message) error // Insert inserts the provided entry in the store and fails if there is // an unique key violation. See Save for more details on behavior. Insert(ctx context.Context, message proto.Message) error // Update updates the provided entry in the store and fails if an entry // with a matching primary key does not exist. See Save for more details // on behavior. Update(ctx context.Context, message proto.Message) error // Delete deletes the entry with the with primary key fields set on message // if one exists. Other fields besides the primary key fields will not // be used for retrieval. // // If store implement the Hooks interface, the OnDelete hook method will // be called. // // Delete attempts to be atomic with respect to the underlying store, // meaning that either the full save operation is written or the store is // left unchanged, unless there is an error with the underlying store. Delete(ctx context.Context, message proto.Message) error // DefaultJSON returns default JSON that can be used as a template for // genesis files. // // For regular tables this an empty JSON array, but for singletons an // empty instance of the singleton is marshaled. DefaultJSON() json.RawMessage // ValidateJSON validates JSON streamed from the reader. ValidateJSON(io.Reader) error // ImportJSON imports JSON into the store, streaming one entry at a time. // Each table should be import from a separate JSON file to enable proper // streaming. // // Regular tables should be stored as an array of objects with each object // corresponding to a single record in the table. // // Auto-incrementing tables // can optionally have the last sequence value as the first element in the // array. If the last sequence value is provided, then each value of the // primary key in the file must be <= this last sequence value or omitted // entirely. If no last sequence value is provided, no entries should // contain the primary key as this will be auto-assigned. // // Singletons should define a single object and not an array. // // ImportJSON is not atomic with respect to the underlying store, meaning // that in the case of an error, some records may already have been // imported. It is assumed that ImportJSON is called in the context of some // larger transaction isolation. ImportJSON(context.Context, io.Reader) error // ExportJSON exports JSON in the format accepted by ImportJSON. // Auto-incrementing tables will export the last sequence number as the // first element in the JSON array. ExportJSON(context.Context, io.Writer) error // ID is the ID of this table within the schema of its FileDescriptor. ID() uint32 }
Table is an abstract interface around a concrete table. Table instances are stateless, with all state existing only in the store passed to table and index methods.
type TypeResolver ¶
type TypeResolver interface { protoregistry.MessageTypeResolver protoregistry.ExtensionTypeResolver }
TypeResolver is an interface that can be used for the protoreflect.UnmarshalOptions.Resolver option.
type UniqueIndex ¶
type UniqueIndex interface { Index // Has returns true if the key values are present in the store for this index. Has(context context.Context, keyValues ...interface{}) (found bool, err error) // Get retrieves the message if one exists for the provided key values. Get(context context.Context, message proto.Message, keyValues ...interface{}) (found bool, err error) // DeleteByKey deletes the message if one exists in for the provided key values. DeleteByKey(context context.Context, keyValues ...interface{}) error }
UniqueIndex defines an unique index on a table.
type View ¶
type View interface { Index // Has returns true if there is an entity in the table with the same // primary key as message. Other fields besides the primary key fields will not // be used for retrieval. Has(ctx context.Context, message proto.Message) (found bool, err error) // Get retrieves the message if one exists for the primary key fields // set on the message. Other fields besides the primary key fields will not // be used for retrieval. Get(ctx context.Context, message proto.Message) (found bool, err error) // GetIndex returns the index referenced by the provided fields if // one exists or nil. Note that some concrete indexes can be retrieved by // multiple lists of fields. GetIndex(fields string) Index // GetUniqueIndex returns the unique index referenced by the provided fields if // one exists or nil. Note that some concrete indexes can be retrieved by // multiple lists of fields. GetUniqueIndex(fields string) UniqueIndex // Indexes returns all the concrete indexes for the table. Indexes() []Index }
View defines a read-only table.
It exists as a separate interacted to support future scenarios where tables may be "supported" virtually to provide compatibility between systems, for instance to enable backwards compatibility when a major migration needs to be performed.