Documentation
¶
Index ¶
- Constants
- Variables
- func ClearFieldChanged(e *EntBase, fieldIndex int)
- func CreateEnt(e Ent, storage Storage) error
- func DeleteEnt(e Ent) error
- func EntString(e Ent) string
- func FieldsWithEmptyValue(e Ent) uint64
- func FindEntIdByIndex(s Storage, entTypeName string, x *EntIndex, nfields int, ...) (uint64, error)
- func FindEntIdByIndexKey(s Storage, entTypeName string, x *EntIndex, key []byte) (uint64, error)
- func FindEntIdsByIndex(s Storage, entTypeName string, x *EntIndex, nfields, limit int, ...) ([]uint64, error)
- func IsFieldChanged(e *EntBase, fieldIndex int) bool
- func JsonDecode(e Ent, data []byte) error
- func JsonDecodeEnt(e Ent, data []byte) (id, version uint64, err error)
- func JsonDecodeEntPartial(e Ent, data []byte, fields uint64) (version uint64, err error)
- func JsonEncode(e Ent, indent string) ([]byte, error)
- func JsonEncodeEnt(e Ent, id, version, fieldmap uint64, indent string) ([]byte, error)
- func JsonEncodeUnsaved(e Ent, indent string) ([]byte, error)
- func LoadEntById(e Ent, storage Storage, id uint64) error
- func LoadEntByIndex(s Storage, e Ent, x *EntIndex, nfields int, keyEncoder func(Encoder)) error
- func LoadEntByIndexKey(s Storage, e Ent, x *EntIndex, key []byte) error
- func ReloadEnt(e Ent) error
- func Repr(e Ent, fieldmap uint64, flags ReprFlags) ([]byte, 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) EntFields() Fields
- 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 Fields
- type Id
- type IdSet
- 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 ReprFlags
- type Storage
- type StorageIndexEdit
- type VersionConflictErr
Constants ¶
const (
EntIndexUnique = 1 << iota // a unique index entry points to exactly one ent
)
const ( // ReprOmitEmpty causes empty, non-numeric fields to be excluded ReprOmitEmpty = ReprFlags(1 << iota) )
Variables ¶
var ( ErrNoStorage = errors.New("no ent storage") ErrNotFound = errors.New("ent not found") ErrNotChanged = errors.New("ent not changed") 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 FieldsWithEmptyValue ¶ added in v0.2.0
FieldsWithEmptyValue returns a fieldmap of all non-numeric non-bool fields which has a zero value for its type.
func FindEntIdByIndex ¶
func FindEntIdByIndexKey ¶
func FindEntIdsByIndex ¶
func IsFieldChanged ¶
IsFieldChanged returns true if the field fieldIndex is marked as "having unsaved changes"
func JsonDecodeEnt ¶ added in v0.2.0
func JsonDecodeEntPartial ¶ added in v0.2.0
JsonDecodeEntPartial is a utility function for decoding a partial ent. It calls e.EntDecodePartial and thus is limited to fields that participate in indexes.
func JsonEncode ¶
JsonEncode encodes the ent as JSON
func JsonEncodeEnt ¶ added in v0.2.0
func JsonEncodeUnsaved ¶
JsonEncodeUnsaved encodes the ent as JSON, only including fields with unsaved changes
func LoadEntByIndex ¶
func Repr ¶ added in v0.2.0
Repr formats a human-readable representation of an ent. It only includes fields in fieldmap.
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 Bool() bool Int(bitsize int) int64 // advisory size Uint(bitsize int) uint64 // advisory size Float(bitsize int) float64 // advisory size 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 EntBase ¶
type EntBase struct {
// contains filtered or unexported fields
}
EntBase is the foundation for all ent types. Use it as the first embedded field in a struct to make the struct an ent.
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 Fields ¶ added in v0.2.0
type Fields struct { Names []string // names of fields, ordered by field index Fieldmap uint64 // a bitmap with all fields set }
Fields describes fields of an ent. Available via TYPE.EntFields()
type IdSet ¶ added in v0.2.0
type IdSet []uint64
IdSet is a list of integers which are treated as a set
func ParseIdSet ¶ added in v0.2.0
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 BareKeys bool // when true, don't wrap keys in "..." }
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
func (*JsonEncoder) Key ¶ added in v0.2.0
func (e *JsonEncoder) Key(k string)
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 string, x *EntIndex, key []byte, limit int) ([]uint64, error) LoadEntsByIndex(e Ent, x *EntIndex, key []byte, limit int) ([]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 ComputeIndexEdits ¶ added in v0.2.0
func ComputeIndexEdits( indexGet IndexGetter, nextEnt, prevEnt Ent, id, changedFields uint64, ) ([]StorageIndexEdit, error)
ComputeIndexEdits 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)
Note: StorageIndexEdits with IsCleanup=true always comes before a StorageIndexEdit for the same key that is not a cleanup. This makes it possible to perform patches using a single loop, e.g:
for _, ed := range indexEdits { key := indexKey(ed.Index.Name, ed.Key) if ed.IsCleanup { db.Delete(key) } else { db.Set(key, id) } }
indexGet may be nil in which case it is assumed that calling storage handles sets of ids. For example, ent/redis.EntStorage handles ids of non-unique indexes manually and thus provides nil for indexGet, while ent/mem.EntStorage does not handle id sets itself and instead provides a function, for reading its current state, as indexGet.
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