orm

package
v0.21.1 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2019 License: Apache-2.0 Imports: 13 Imported by: 23

Documentation

Overview

Package orm provides an easy to use db wrapper

Break state space into prefixed sections called Buckets. * Each bucket contains only one type of object. * It has a primary index (which may be composite), and may possess secondary indexes. * It may possess one or more secondary indexes (1:1 or 1:N) * Easy queries for one and iteration.

For inspiration, look at [storm](https://github.com/asdine/storm) built on top of [bolt kvstore](https://github.com/boltdb/bolt#using-buckets). * Do not use so much reflection magic. Better do stuff compile-time static, even if it is a bit of boilerplate. * Consider general usability flow from that project

Index

Constants

View Source
const (
	// SeqID is a constant to use to get a default ID sequence
	SeqID = "id"
)

Variables

View Source
var (
	ErrInvalidLengthCodec = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowCodec   = fmt.Errorf("proto: integer overflow")
)
View Source
var ErrInvalidIndex = errors.Register(100, "invalid index")

ErrInvalidIndex is returned when an index specified is invalid

Functions

func MarshalVersionedID added in v0.21.0

func MarshalVersionedID(key VersionedIDRef) []byte

MarshalVersionedID is used to guarantee determinism while serializing a VersionedIDRef. It comes with the option to omit empty version should you want to do a prefix query.

func RegisterQuery

func RegisterQuery(qr weave.QueryRouter)

RegisterQuery will register a root query (literal keys) under "/"

Types

type Bucket

type Bucket interface {
	weave.QueryHandler

	DBKey(key []byte) []byte
	Delete(db weave.KVStore, key []byte) error
	Get(db weave.ReadOnlyKVStore, key []byte) (Object, error)
	GetIndexed(db weave.ReadOnlyKVStore, name string, key []byte) ([]Object, error)
	GetIndexedLike(db weave.ReadOnlyKVStore, name string, pattern Object) ([]Object, error)
	Parse(key, value []byte) (Object, error)
	Register(name string, r weave.QueryRouter)
	Save(db weave.KVStore, model Object) error
	Sequence(name string) Sequence
	WithIndex(name string, indexer Indexer, unique bool) Bucket
	WithMultiKeyIndex(name string, indexer MultiKeyIndexer, unique bool) Bucket
}

func NewBucket

func NewBucket(name string, proto Cloneable) Bucket

NewBucket creates a bucket to store data

type Cloneable

type Cloneable interface {
	Clone() Object
}

Cloneable will create a new object that can be loaded into

type CloneableData

type CloneableData interface {
	x.Validater
	weave.Persistent
	Copy() CloneableData
}

CloneableData is an intelligent Value that can be embedded in a simple object to handle much of the details.

type Counter

type Counter struct {
	Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
}

Counter could be used for sequence, but mainly just for test

func NewCounter

func NewCounter(count int64) *Counter

NewCounter returns an initialized counter

func (*Counter) Copy

func (c *Counter) Copy() CloneableData

Copy produces another counter with the same data

func (*Counter) Descriptor

func (*Counter) Descriptor() ([]byte, []int)

func (*Counter) GetCount

func (m *Counter) GetCount() int64

func (*Counter) Marshal

func (m *Counter) Marshal() (dAtA []byte, err error)

func (*Counter) MarshalTo

func (m *Counter) MarshalTo(dAtA []byte) (int, error)

func (*Counter) ProtoMessage

func (*Counter) ProtoMessage()

func (*Counter) Reset

func (m *Counter) Reset()

func (*Counter) Size

func (m *Counter) Size() (n int)

func (*Counter) String

func (m *Counter) String() string

func (*Counter) Unmarshal

func (m *Counter) Unmarshal(dAtA []byte) error

func (*Counter) Validate

func (c *Counter) Validate() error

Validate returns error on negative numbers

func (*Counter) XXX_DiscardUnknown added in v0.12.0

func (m *Counter) XXX_DiscardUnknown()

func (*Counter) XXX_Marshal added in v0.12.0

func (m *Counter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Counter) XXX_Merge added in v0.12.0

func (m *Counter) XXX_Merge(src proto.Message)

func (*Counter) XXX_Size added in v0.12.0

func (m *Counter) XXX_Size() int

func (*Counter) XXX_Unmarshal added in v0.12.0

func (m *Counter) XXX_Unmarshal(b []byte) error

type IDGenBucket added in v0.15.0

type IDGenBucket struct {
	Bucket
	// contains filtered or unexported fields
}

func WithIDGenerator added in v0.15.0

func WithIDGenerator(b Bucket, gen IDGenerator) IDGenBucket

WithIDGenerator creates a bucket with uses the given id generator on top of the given bucket implementation.

func WithSeqIDGenerator added in v0.15.0

func WithSeqIDGenerator(b Bucket, seqName string) IDGenBucket

WithSeqIDGenerator adds a Sequence for primary ID key generation on top fo the given bucket implementation

func (IDGenBucket) Create added in v0.15.0

func (b IDGenBucket) Create(db weave.KVStore, data CloneableData) (Object, error)

Create saves the given data in a persistent bucket with a new generated ID key.

type IDGenerator added in v0.15.0

type IDGenerator interface {
	// NextVal returns a new unique ID key
	NextVal(db weave.KVStore, obj CloneableData) ([]byte, error)
}

IDGenerator defines an interface for custom id generators

type IDGeneratorFunc added in v0.15.0

type IDGeneratorFunc func(db weave.KVStore, obj CloneableData) ([]byte, error)

IDGeneratorFunc provides IDGenerator interface support.

func (IDGeneratorFunc) NextVal added in v0.15.0

func (i IDGeneratorFunc) NextVal(db weave.KVStore, obj CloneableData) ([]byte, error)

NextVal returns a new unique ID key

type Index

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

Index represents a secondary index on some data. It is indexed by an arbitrary key returned by Indexer. The value is one primary key (unique), Or an array of primary keys (!unique).

func NewIndex

func NewIndex(name string, indexer Indexer, unique bool,
	refKey func([]byte) []byte) Index

NewIndex constructs an index with single key Indexer. Indexer calculates the index for an object unique enforces a unique constraint on the index refKey calculates the absolute dbkey for a ref

func NewMultiKeyIndex added in v0.8.0

func NewMultiKeyIndex(name string, indexer MultiKeyIndexer, unique bool,
	refKey func([]byte) []byte) Index

NewMultiKeyIndex constructs an index with multi key indexer. Indexer calculates the index for an object unique enforces a unique constraint on the index refKey calculates the absolute dbkey for a ref

func (Index) GetAt

func (i Index) GetAt(db weave.ReadOnlyKVStore, index []byte) ([][]byte, error)

GetAt returns a list of all pk at that index (may be empty), or an error

func (Index) GetLike

func (i Index) GetLike(db weave.ReadOnlyKVStore, pattern Object) ([][]byte, error)

GetLike calculates the index for the given pattern, and returns a list of all pk that match (may be nil when empty), or an error

func (Index) GetPrefix

func (i Index) GetPrefix(db weave.ReadOnlyKVStore, prefix []byte) ([][]byte, error)

GetPrefix returns all references that have an index that begins with a given prefix

func (Index) IndexKey

func (i Index) IndexKey(key []byte) []byte

IndexKey is the full key we store in the db, including prefix We copy into a new array rather than use append, as we don't want consecutive calls to overwrite the same byte array.

func (Index) Query

func (i Index) Query(db weave.ReadOnlyKVStore, mod string,
	data []byte) ([]weave.Model, error)

Query handles queries from the QueryRouter

func (Index) Update

func (i Index) Update(db weave.KVStore, prev Object, save Object) error

Update handles updating the reference to the object in the secondary index.

prev == nil means insert save == nil means delete both == nil is error if both != nil and prev.Key() != save.Key() this is an error

Otherwise, it will check indexer(prev) and indexer(save) and make sure the key is now stored in the right location

type Indexer

type Indexer func(Object) ([]byte, error)

Indexer calculates the secondary index key for a given object

type Keyed

type Keyed interface {
	Key() []byte
	SetKey([]byte)
}

Keyed is anything that can identify itself

type Model added in v0.16.0

type Model interface {
	weave.Persistent
	Validate() error
	Copy() CloneableData
}

Model is implemented by any entity that can be stored using ModelBucket.

This is the same interface as CloneableData. Using the right type names provides an easier to read API.

type ModelBucket added in v0.16.0

type ModelBucket interface {
	// One query the database for a single model instance. Lookup is done
	// by the primary index key. Result is loaded into given destination
	// model.
	// This method returns ErrNotFound if the entity does not exist in the
	// database.
	// If given model type cannot be used to contain stored entity, ErrType
	// is returned.
	One(db weave.ReadOnlyKVStore, key []byte, dest Model) error

	// ByIndex returns all objects that secondary index with given name and
	// given key. Main index is always unique but secondary indexes can
	// return more than one value for the same key.
	// All matching entities are appended to given destination slice. If no
	// result was found, no error is returned and destination slice is not
	// modified.
	ByIndex(db weave.ReadOnlyKVStore, indexName string, key []byte, dest ModelSlicePtr) (keys [][]byte, err error)

	// Put saves given model in the database. Before inserting into
	// database, model is validated using its Validate method.
	// If the key is nil or zero length then a sequence generator is used
	// to create a unique key value.
	// Using a key that already exists in the database cause the value to
	// be overwritten.
	Put(db weave.KVStore, key []byte, m Model) ([]byte, error)

	// Delete removes an entity with given primary key from the database.
	// It returns ErrNotFound if an entity with given key does not exist.
	Delete(db weave.KVStore, key []byte) error

	// Has returns nil if an entity with given primary key value exists. It
	// returns ErrNotFound if no entity can be found.
	// Has is a cheap operation that that does not read the data and only
	// checks the existence of it.
	Has(db weave.KVStore, key []byte) error

	// Register registers this buckets content to be accessible via query
	// requests under the given name.
	Register(name string, r weave.QueryRouter)
}

ModelBucket is implemented by buckets that operates on Models rather than Objects.

func NewModelBucket added in v0.16.0

func NewModelBucket(name string, m Model, opts ...ModelBucketOption) ModelBucket

NewModelBucket returns a ModelBucket instance. This implementation relies on a bucket instance. Final implementation should operate directly on the KVStore instead.

type ModelBucketOption added in v0.16.0

type ModelBucketOption func(mb *modelBucket)

ModelBucketOption is implemented by any function that can configure ModelBucket during creation.

func WithIDSequence added in v0.19.0

func WithIDSequence(s Sequence) ModelBucketOption

WithIDSequence configures the bucket to use the given sequence instance for generating ID.

func WithIndex added in v0.16.0

func WithIndex(name string, indexer Indexer, unique bool) ModelBucketOption

WithIndex configures the bucket to build an index with given name. All entities stored in the bucket are indexed using value returned by the indexer function. If an index is unique, there can be only one entity referenced per index value.

type ModelSlicePtr added in v0.16.0

type ModelSlicePtr interface{}

ModelSlicePtr represents a pointer to a slice of models. Think of it as *[]Model Because of Go type system, using []Model would not work for us. Instead we use a placeholder type and the validation is done during the runtime.

type MultiKeyIndexer added in v0.8.0

type MultiKeyIndexer func(Object) ([][]byte, error)

MultiKeyIndexer calculates the secondary index keys for a given object

type MultiRef

type MultiRef struct {
	Refs [][]byte `protobuf:"bytes,1,rep,name=refs,proto3" json:"refs,omitempty"`
}

MultiRef contains a list of references to pks

func NewMultiRef

func NewMultiRef(refs ...[]byte) (*MultiRef, error)

NewMultiRef creates a MultiRef with any number of initial references

func (*MultiRef) Add

func (m *MultiRef) Add(ref []byte) error

Add inserts this reference in the multiref, sorted by order. Returns an error if already there

func (*MultiRef) Copy

func (m *MultiRef) Copy() CloneableData

Copy does a shallow copy of the slice of refs and creates a new MultiRef

func (*MultiRef) Descriptor

func (*MultiRef) Descriptor() ([]byte, []int)

func (*MultiRef) GetRefs

func (m *MultiRef) GetRefs() [][]byte

func (*MultiRef) Marshal

func (m *MultiRef) Marshal() (dAtA []byte, err error)

func (*MultiRef) MarshalTo

func (m *MultiRef) MarshalTo(dAtA []byte) (int, error)

func (*MultiRef) ProtoMessage

func (*MultiRef) ProtoMessage()

func (*MultiRef) Remove

func (m *MultiRef) Remove(ref []byte) error

Remove removes this reference from the multiref. Returns an error if already there

func (*MultiRef) Reset

func (m *MultiRef) Reset()

func (*MultiRef) Size

func (m *MultiRef) Size() (n int)

func (*MultiRef) Sort

func (m *MultiRef) Sort()

Sort will make sure everything is in order

func (*MultiRef) String

func (m *MultiRef) String() string

func (*MultiRef) Unmarshal

func (m *MultiRef) Unmarshal(dAtA []byte) error

func (*MultiRef) Validate

func (m *MultiRef) Validate() error

Validate just returns an error if empty

func (*MultiRef) XXX_DiscardUnknown added in v0.12.0

func (m *MultiRef) XXX_DiscardUnknown()

func (*MultiRef) XXX_Marshal added in v0.12.0

func (m *MultiRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*MultiRef) XXX_Merge added in v0.12.0

func (m *MultiRef) XXX_Merge(src proto.Message)

func (*MultiRef) XXX_Size added in v0.12.0

func (m *MultiRef) XXX_Size() int

func (*MultiRef) XXX_Unmarshal added in v0.12.0

func (m *MultiRef) XXX_Unmarshal(b []byte) error

type Object

type Object interface {
	Keyed
	Cloneable
	// Validate returns error if the object is not in a valid
	// state to save to the db (eg. field missing, out of range, ...)
	x.Validater
	Value() weave.Persistent
}

Object is what is stored in the bucket Key is joined with the prefix to set the full key Value is the data stored

this can be light wrapper around a protobuf-defined type

type Reader added in v0.8.0

type Reader interface {
	Get(db weave.ReadOnlyKVStore, key []byte) (Object, error)
}

Reader defines an interface that allows reading objects from the db

type Sequence

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

Sequence maintains a counter, and generates a series of keys. Each key is greater than the last, both NextInt() as well as bytes.Compare() on NextVal().

func NewSequence

func NewSequence(bucket, name string) Sequence

NewSequence returns a sequence counter. Sequence is using following pattern to construct a key:

_s.<bucket>:<name>

func (*Sequence) NextInt

func (s *Sequence) NextInt(db weave.KVStore) (int64, error)

NextInt increments the sequence and returns its state as int.

func (*Sequence) NextVal

func (s *Sequence) NextVal(db weave.KVStore) ([]byte, error)

NextVal increments the sequence and returns its state as 8 bytes.

type SimpleObj

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

SimpleObj wraps a key and a value together It can be used as a template for type-safe objects

func NewSimpleObj

func NewSimpleObj(key []byte, value CloneableData) *SimpleObj

NewSimpleObj will combine a key and value into an object

func (*SimpleObj) Clone

func (o *SimpleObj) Clone() Object

Clone will make a copy of this object

func (SimpleObj) Key

func (o SimpleObj) Key() []byte

Key returns the key to store the object under

func (*SimpleObj) SetKey

func (o *SimpleObj) SetKey(key []byte)

SetKey may be used to update a simple obj key

func (SimpleObj) Validate

func (o SimpleObj) Validate() error

Validate makes sure the fields aren't empty. And delegates to the value validator if present

func (SimpleObj) Value

func (o SimpleObj) Value() weave.Persistent

Value gets the value stored in the object

type VersionedIDRef added in v0.15.0

type VersionedIDRef struct {
	// Unique identifier
	ID []byte `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"`
	// Document version, starting with 1.
	Version uint32 `protobuf:"varint,5,opt,name=version,proto3" json:"version,omitempty"`
}

VersionedID is the combination of document ID and version number.

func UnmarshalVersionedID added in v0.21.0

func UnmarshalVersionedID(b []byte) (VersionedIDRef, error)

UnmarshalVersionedID is used to deserialize a VersionedIDRef from a deterministic format. It expects version to be stored in the last 4 bytes of the passed slice.

func (VersionedIDRef) Copy added in v0.15.0

func (m VersionedIDRef) Copy() CloneableData

func (*VersionedIDRef) Descriptor added in v0.15.0

func (*VersionedIDRef) Descriptor() ([]byte, []int)

func (*VersionedIDRef) GetID added in v0.15.0

func (m *VersionedIDRef) GetID() []byte

func (*VersionedIDRef) GetVersion added in v0.15.0

func (m *VersionedIDRef) GetVersion() uint32

func (*VersionedIDRef) Marshal added in v0.15.0

func (m *VersionedIDRef) Marshal() (dAtA []byte, err error)

func (*VersionedIDRef) MarshalTo added in v0.15.0

func (m *VersionedIDRef) MarshalTo(dAtA []byte) (int, error)

func (VersionedIDRef) NextVersion added in v0.15.0

func (m VersionedIDRef) NextVersion() (VersionedIDRef, error)

NextVersion returns a new VersionedIDRef with the same ID as current but version +1.

func (*VersionedIDRef) ProtoMessage added in v0.15.0

func (*VersionedIDRef) ProtoMessage()

func (*VersionedIDRef) Reset added in v0.15.0

func (m *VersionedIDRef) Reset()

func (*VersionedIDRef) SetVersion added in v0.15.0

func (m *VersionedIDRef) SetVersion(v uint32)

func (*VersionedIDRef) Size added in v0.15.0

func (m *VersionedIDRef) Size() (n int)

func (*VersionedIDRef) String added in v0.15.0

func (m *VersionedIDRef) String() string

func (*VersionedIDRef) Unmarshal added in v0.15.0

func (m *VersionedIDRef) Unmarshal(dAtA []byte) error

func (VersionedIDRef) Validate added in v0.15.0

func (m VersionedIDRef) Validate() error

func (*VersionedIDRef) XXX_DiscardUnknown added in v0.15.0

func (m *VersionedIDRef) XXX_DiscardUnknown()

func (*VersionedIDRef) XXX_Marshal added in v0.15.0

func (m *VersionedIDRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*VersionedIDRef) XXX_Merge added in v0.15.0

func (m *VersionedIDRef) XXX_Merge(src proto.Message)

func (*VersionedIDRef) XXX_Size added in v0.15.0

func (m *VersionedIDRef) XXX_Size() int

func (*VersionedIDRef) XXX_Unmarshal added in v0.15.0

func (m *VersionedIDRef) XXX_Unmarshal(b []byte) error

type VersioningBucket added in v0.15.0

type VersioningBucket struct {
	IDGenBucket
}

func WithVersioning added in v0.15.0

func WithVersioning(b IDGenBucket) VersioningBucket

WithVersioning add versioning functionality to the underlying bucket. This means objects can not be overwritten anymore via Save function which must not be used with this type. Instead Create and Update methods are provided to support a history of object versions.

func (VersioningBucket) Create added in v0.15.0

func (b VersioningBucket) Create(db weave.KVStore, data versionedData) (*VersionedIDRef, error)

Create stores the given data. It assigns an ID and initial version number to the object instance and returns the VersionedIDRef which won't be nil on success.

func (VersioningBucket) CreateWithID added in v0.19.0

func (b VersioningBucket) CreateWithID(db weave.KVStore, id []byte, data versionedData) (*VersionedIDRef, error)

CreateWithID stores the given data. It accepts an ID and assigns an initial version number to the object instance and returns the VersionedIDRef which won't be nil on success. This method is designed to be used for scenarios where an ID is needed to generate data within the entity before saving it.

func (VersioningBucket) Delete added in v0.15.0

func (b VersioningBucket) Delete(db weave.KVStore, id []byte) (*VersionedIDRef, error)

Delete stores a tombstone value for the new highest version. It will return this key on success. A version for the given ID must exists or ErrNotFound is returned. When already deleted Err

func (VersioningBucket) Exists added in v0.15.0

func (b VersioningBucket) Exists(db weave.KVStore, idRef VersionedIDRef) (bool, error)

Exists returns if an object is persisted for that given VersionedIDRef. If it points to the tombstone as deletion marker, ErrDeleted is returned.

func (VersioningBucket) Get added in v0.15.0

func (b VersioningBucket) Get(db weave.ReadOnlyKVStore, key []byte) (Object, error)

Get works with a marshalled VersionedIDRef key. Direct usage should be avoided in favour of GetVersion or GetLatestVersion. Unlike the classic Get function it returns:

  • ErrNotFound when not found
  • ErrDeleted when deleted

Object won't be nil in success case

func (VersioningBucket) GetLatestVersion added in v0.15.0

func (b VersioningBucket) GetLatestVersion(db weave.ReadOnlyKVStore, id []byte) (*VersionedIDRef, Object, error)

GetLatestVersion finds the latest version for the given id and returns the VersionedIDRef and loaded object. Unlike the classic Get function it returns:

  • ErrNotFound when not found
  • ErrDeleted when deleted

Object won't be nil in success case

func (VersioningBucket) GetVersion added in v0.15.0

func (VersioningBucket) Save deprecated added in v0.15.0

func (b VersioningBucket) Save(db weave.KVStore, model Object) error

Deprecated: Save will always return an error. Use Create or Update instead.

func (VersioningBucket) Update added in v0.15.0

func (b VersioningBucket) Update(db weave.KVStore, id []byte, data versionedData) (*VersionedIDRef, error)

Update persists the given data object with a new derived version key in the storage. The VersionedIDRef returned won't be nil on success and contains the new version number. The currentKey must be the latest one in usage or an ErrDuplicate is returned.

Jump to

Keyboard shortcuts

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