ormtable

package
v1.0.0-alpha.5 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2022 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package ormtable defines the interfaces and implementations of tables and indexes.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultJSONValidator

func DefaultJSONValidator(message proto.Message) error

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.

func NewBackend

func NewBackend(options BackendOptions) Backend

NewBackend creates a new Backend.

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.

func Paginate

func Paginate(
	index Index,
	ctx context.Context,
	request *PaginationRequest,
	onItem func(proto.Message),
	options ...ormlist.Option,
) (*PaginationResponse, error)

Paginate retrieves a "page" of data from the provided index and context.

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 Schema

type Schema interface {
	ormkv.EntryCodec

	// GetTable returns the table for the provided message type or nil.
	GetTable(message proto.Message) Table
}

Schema is an interface for things that contain tables and can encode and decode kv-store pairs.

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

	Schema
}

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.

func Build

func Build(options Options) (Table, error)

Build builds a Table instance from the provided Options.

type TypeResolver

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

	// GetIndexByID returns the index with the provided ID or nil.
	GetIndexByID(id uint32) Index

	// PrimaryKey returns the primary key unique index.
	PrimaryKey() UniqueIndex
}

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.

Jump to

Keyboard shortcuts

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