Documentation
¶
Index ¶
- Constants
- Variables
- func ClearFieldChanged(e *EntBase, fieldIndex int)
- func CreateEnt(e Ent, storage Storage) error
- func DeleteEnt(e Ent) error
- func FindEntIdByIndex(s Storage, entTypeName, indexName string, keyEncoder func(Encoder)) (uint64, error)
- func FindEntIdByIndexKey(s Storage, entTypeName, indexName string, key []byte) (uint64, error)
- func FindEntIdsByIndex(s Storage, entTypeName, indexName string, nfields int, ...) ([]uint64, error)
- func IsFieldChanged(e *EntBase, fieldIndex int) bool
- func JsonDecode(e Ent, data []byte) error
- func JsonEncode(e Ent) ([]byte, error)
- func JsonEncodeUnsaved(e Ent) ([]byte, error)
- func LoadEntById(e Ent, storage Storage, id uint64) error
- func LoadEntByIndex(s Storage, e Ent, indexName string, keyEncoder func(Encoder)) error
- func LoadEntByIndexKey(s Storage, e Ent, indexName string, key []byte) error
- func ReloadEnt(e Ent) error
- func SaveEnt(e Ent) error
- func SetEntBaseFieldsAfterLoad(e Ent, s Storage, id, version uint64)
- func SetFieldChanged(e *EntBase, fieldIndex int)
- type Buffer
- type Decoder
- type Encoder
- type Ent
- type EntBase
- func (e *EntBase) EntDecode(c Decoder) (id, version uint64)
- func (e *EntBase) EntEncode(Encoder, uint64)
- func (e *EntBase) EntIndexes() []EntIndex
- func (e *EntBase) EntIsFieldChanged(fieldIndex int) bool
- func (e *EntBase) EntTypeName() string
- func (e *EntBase) HasUnsavedChanges() bool
- func (e *EntBase) Id() uint64
- func (e *EntBase) Version() uint64
- type EntIndex
- type EntIndexFlag
- type EntType
- type Id
- type IndexGetter
- type IndexKeyEncoder
- func (c *IndexKeyEncoder) BeginDict(length int)
- func (c *IndexKeyEncoder) BeginEnt(version uint64)
- func (c *IndexKeyEncoder) BeginList(length int)
- func (c *IndexKeyEncoder) Blob(v []byte)
- func (c *IndexKeyEncoder) Bool(v bool)
- func (c *IndexKeyEncoder) EncodeKey(e Ent, fieldmap uint64) ([]byte, error)
- func (c *IndexKeyEncoder) EndDict()
- func (c *IndexKeyEncoder) EndEnt()
- func (c *IndexKeyEncoder) EndList()
- func (c *IndexKeyEncoder) Err() error
- func (c *IndexKeyEncoder) Float(v float64, bitsize int)
- func (c *IndexKeyEncoder) Int(v int64, bitsize int)
- func (c *IndexKeyEncoder) Key(k string)
- func (c *IndexKeyEncoder) Reset(nfields int)
- func (c *IndexKeyEncoder) Str(v string)
- func (c *IndexKeyEncoder) Uint(v uint64, bitsize int)
- type JsonDecoder
- type JsonEncoder
- type JsonError
- type MemoryStorage
- func (s *MemoryStorage) CreateEnt(e Ent, fieldmap uint64) (id uint64, err error)
- func (s *MemoryStorage) DeleteEnt(e Ent) error
- func (s *MemoryStorage) FindEntIdsByIndex(entTypeName, indexName string, key []byte) ([]uint64, error)
- func (s *MemoryStorage) LoadEntById(e Ent, id uint64) (version uint64, err error)
- func (s *MemoryStorage) LoadEntsByIndex(e Ent, indexName string, key []byte) ([]Ent, error)
- func (s *MemoryStorage) SaveEnt(e Ent, fieldmap uint64) (nextVersion uint64, err error)
- type Storage
- type StorageIndexEdit
- type VersionConflictErr
Constants ¶
const (
EntIndexUnique = 1 << iota // a unique index entry points to exactly one ent
)
Variables ¶
var ( ErrNoStorage = errors.New("no ent storage") ErrNotFound = errors.New("ent not found") ErrVersionConflict = errors.New("version conflict") ErrDuplicateEnt = errors.New("duplicate ent") )
var ( FieldNameVersion = "_ver" FieldNameId = "_id" )
Functions ¶
func ClearFieldChanged ¶
ClearFieldChanged marks the field fieldIndex as not having and unsaved changes
func FindEntIdByIndex ¶
func FindEntIdByIndexKey ¶
func FindEntIdsByIndex ¶
func IsFieldChanged ¶
IsFieldChanged returns true if the field fieldIndex is marked as "having unsaved changes"
func JsonEncodeUnsaved ¶
JsonEncodeUnsaved encodes the ent as JSON, only including fields with unsaved changes
func LoadEntByIndex ¶
func LoadEntByIndexKey ¶
func SetEntBaseFieldsAfterLoad ¶
SetEntBaseFieldsAfterLoad sets values of EntBase fields. This function is meant to be used by Storage implementation, called after a new ent has been loaded or created.
func SetFieldChanged ¶
SetFieldChanged marks the field fieldIndex as "having unsaved changes"
Types ¶
type Buffer ¶
type Buffer []byte
Buffer is an extension to the byte array with functions for efficiently growing it, useful for constructing variably-sized byte arrays.
func NewBuffer ¶
NewBuffer creates a buffer with some preallocated space. Note that you do not need to use this function. Simply using a default-initialized Buffer works just as well as it will be allocated on first grow() call.
func (Buffer) DenseBytes ¶
DenseBytes returns the receiver if the density (cap divided by len) is less than densityThreshold. Otherwise a perfectly dense copy is returned.
This is useful if you plan to keep a lot of buffers unmodified for a long period of time, where memory consumption might be a concern.
To always make a copy, provide a densityThreshold of 1.0 or lower.
func (*Buffer) Grow ¶
Grow returns the index where bytes should be written and whether it succeeded.
func (*Buffer) Reset ¶
func (b *Buffer) Reset()
Reset truncates the buffer's length to zero, allowing it to be reused.
func (*Buffer) Write ¶
Write appends data to the buffer, returning the offset to the start of the appended data
func (*Buffer) WriteString ¶
type Decoder ¶
type Decoder interface { Err() error // returns the error state of the decoder // Key reads & returns the next key. Returns "" in case there are no more fields. Key() string ListHeader() int // decode a list header. Returns known size or -1 if unknown DictHeader() int // decode a dict header. Returns known size or -1 if unknown // More reports whether there is another element in the current list or dict being decoded. // Only used when ListHeader and DictHeader returns -1. More() bool Str() string // decode a string field Blob() []byte // decode a byte array field Int(bitsize int) int64 // advisory size Uint(bitsize int) uint64 // advisory size Float(bitsize int) float64 // advisory size Bool() bool Discard() // read and discard any value }
Decoder is the interface for ent field decoders. ent.JsonDecoder is an example of an implementation.
type Encoder ¶
type Encoder interface { Err() error // returns the error state of the encoder BeginEnt(version uint64) // start encoding an ent EndEnt() // finalize encoding of an ent BeginList(length int) // start encoding a list of length EndList() // end encoding a list BeginDict(length int) // start encoding a dictionary with length entries EndDict() // end encoding of a dict Key(k string) // encode key for a field (value call should follow) Str(v string) // encode a string value Blob(v []byte) // encode a raw-bytes value Int(v int64, bitsize int) // advisory size Uint(v uint64, bitsize int) // advisory size Float(v float64, bitsize int) // advisory size Bool(v bool) // encode a boolean value }
Encoder is the interface for ent field encoders. ent.JsonEncoder is an example of an implementation.
type Ent ¶
type Ent interface { Id() uint64 Version() uint64 HasUnsavedChanges() bool EntTypeName() string EntNew() Ent EntEncode(c Encoder, fieldmap uint64) EntDecode(c Decoder) (id, version uint64) EntDecodeIndexed(c Decoder, fields uint64) (version uint64) EntIndexes() []EntIndex // contains filtered or unexported methods }
type EntBase ¶
type EntBase struct {
// contains filtered or unexported fields
}
func (*EntBase) EntIndexes ¶
func (*EntBase) EntIsFieldChanged ¶
func (*EntBase) EntTypeName ¶
these are just stubs; actual implementations generated by entgen
func (*EntBase) HasUnsavedChanges ¶
type EntIndex ¶
type EntIndex struct { Name string Fields uint64 // bitmap of field indices which this index depends on Flags EntIndexFlag }
EntIndex describes a secondary index and are usually generated by entgen
type EntType ¶
func EntTypeByName ¶
type IndexGetter ¶
IndexGetter is used to look up an entry in an index
type IndexKeyEncoder ¶
type IndexKeyEncoder struct {
// contains filtered or unexported fields
}
IndexKeyEncoder is an implementation of the Encoder interface, used to encode index keys
func (*IndexKeyEncoder) BeginDict ¶
func (c *IndexKeyEncoder) BeginDict(length int)
func (*IndexKeyEncoder) BeginEnt ¶
func (c *IndexKeyEncoder) BeginEnt(version uint64)
func (*IndexKeyEncoder) BeginList ¶
func (c *IndexKeyEncoder) BeginList(length int)
func (*IndexKeyEncoder) Blob ¶
func (c *IndexKeyEncoder) Blob(v []byte)
func (*IndexKeyEncoder) Bool ¶
func (c *IndexKeyEncoder) Bool(v bool)
func (*IndexKeyEncoder) EncodeKey ¶
func (c *IndexKeyEncoder) EncodeKey(e Ent, fieldmap uint64) ([]byte, error)
func (*IndexKeyEncoder) EndDict ¶
func (c *IndexKeyEncoder) EndDict()
func (*IndexKeyEncoder) EndEnt ¶
func (c *IndexKeyEncoder) EndEnt()
func (*IndexKeyEncoder) EndList ¶
func (c *IndexKeyEncoder) EndList()
func (*IndexKeyEncoder) Err ¶
func (c *IndexKeyEncoder) Err() error
func (*IndexKeyEncoder) Float ¶
func (c *IndexKeyEncoder) Float(v float64, bitsize int)
func (*IndexKeyEncoder) Int ¶
func (c *IndexKeyEncoder) Int(v int64, bitsize int)
func (*IndexKeyEncoder) Key ¶
func (c *IndexKeyEncoder) Key(k string)
func (*IndexKeyEncoder) Reset ¶
func (c *IndexKeyEncoder) Reset(nfields int)
func (*IndexKeyEncoder) Str ¶
func (c *IndexKeyEncoder) Str(v string)
func (*IndexKeyEncoder) Uint ¶
func (c *IndexKeyEncoder) Uint(v uint64, bitsize int)
type JsonDecoder ¶
type JsonDecoder struct {
json.Reader
}
JsonDecoder is an implementation of the Decoder interface
func NewJsonDecoder ¶
func NewJsonDecoder(data []byte) *JsonDecoder
func (*JsonDecoder) DictHeader ¶
func (c *JsonDecoder) DictHeader() int
func (*JsonDecoder) ListHeader ¶
func (c *JsonDecoder) ListHeader() int
type JsonEncoder ¶
type JsonEncoder struct {
json.Builder // Note: set Builder.Indent to enable pretty-printing
}
JsonEncoder is an implementation of the Encoder interface
func (*JsonEncoder) BeginDict ¶
func (c *JsonEncoder) BeginDict(length int)
func (*JsonEncoder) BeginEnt ¶
func (c *JsonEncoder) BeginEnt(version uint64)
func (*JsonEncoder) BeginList ¶
func (c *JsonEncoder) BeginList(length int)
func (*JsonEncoder) EndDict ¶
func (c *JsonEncoder) EndDict()
func (*JsonEncoder) EndEnt ¶
func (c *JsonEncoder) EndEnt()
func (*JsonEncoder) EndList ¶
func (c *JsonEncoder) EndList()
func (*JsonEncoder) Err ¶
func (c *JsonEncoder) Err() error
type MemoryStorage ¶
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage is a generic, goroutine-safe storage implementation which maintains ent data in memory, suitable for tests.
func NewMemoryStorage ¶
func NewMemoryStorage() *MemoryStorage
func (*MemoryStorage) CreateEnt ¶
func (s *MemoryStorage) CreateEnt(e Ent, fieldmap uint64) (id uint64, err error)
func (*MemoryStorage) DeleteEnt ¶
func (s *MemoryStorage) DeleteEnt(e Ent) error
func (*MemoryStorage) FindEntIdsByIndex ¶
func (s *MemoryStorage) FindEntIdsByIndex( entTypeName, indexName string, key []byte, ) ([]uint64, error)
func (*MemoryStorage) LoadEntById ¶
func (s *MemoryStorage) LoadEntById(e Ent, id uint64) (version uint64, err error)
func (*MemoryStorage) LoadEntsByIndex ¶
type Storage ¶
type Storage interface { CreateEnt(e Ent, fieldmap uint64) (id uint64, err error) SaveEnt(e Ent, fieldmap uint64) (version uint64, err error) LoadEntById(e Ent, id uint64) (version uint64, err error) FindEntIdsByIndex(entTypeName, indexName string, key []byte) (ids []uint64, err error) LoadEntsByIndex(e Ent, indexName string, key []byte) ([]Ent, error) DeleteEnt(e Ent) error }
Storage is the interface for persistent storage of ents
type StorageIndexEdit ¶
type StorageIndexEdit struct { Index *EntIndex Key string Value []uint64 // IsCleanup is true when the edit represents removing an id for an index entry. // A Storage implementation can choose to perform these edits independently from or outside of // the logical transaction of modifying an ent. IsCleanup bool }
StorageIndexEdit represents a modification to an index
func CalcStorageIndexEdits ¶
func CalcStorageIndexEdits( indexGet IndexGetter, nextEnt, prevEnt Ent, id, changedFields uint64, ) ([]StorageIndexEdit, error)
CalcStorageIndexEdits calculates changes to secondary indexes.
When a new ent is created, prevEnt should be nil. When an ent is deleted, nextEnt should be nil. When an ent is modified, both nextEnt and prevEnt should be provided.
When a new ent is modified or deleted, prevEnt should be the "current" version of the ent. In these cases prevEnt's field values are used to determine what index entries needs to be cleaned up.
prevEnt only needs to loaded fields which indices are the union of all the prevEnt.EntIndexes() Fields values. Example:
var fieldsToLoad uint64 for _, x := range nextEnt.EntIndexes() { fieldsToLoad |= x.Fields } DecodePartialEnt(prevEnt, fieldsToLoad)
type VersionConflictErr ¶
type VersionConflictErr struct { Underlying error // always ErrVersionConflict ExpectedVersion uint64 ActualVersion uint64 }
VersionConflictErr is returned when a Save call fails because the ent has changed by someone else since it was loaded.
func NewVersionConflictErr ¶
func NewVersionConflictErr(expectedVersion, actualVersion uint64) *VersionConflictErr
func (*VersionConflictErr) Error ¶
func (e *VersionConflictErr) Error() string
func (*VersionConflictErr) Unwrap ¶
func (e *VersionConflictErr) Unwrap() error