Newer
Older
type storableConstraint interface {
ID() uuid.UUID
Name() string
// GenericStore provides a in-memory implementation for multiple stores.
type GenericStore[T storableConstraint] struct {
Store map[uuid.UUID]T
nameLookupTable map[string]uuid.UUID
// NewGenericStore returns a specific in-memory store for a type T.
func NewGenericStore[T storableConstraint]() GenericStore[T] {
return GenericStore[T]{
Store: make(map[uuid.UUID]T),
nameLookupTable: make(map[string]uuid.UUID),
}
func (t *GenericStore[T]) Add(item T) error {
_, ok := t.Store[item.ID()]
if ok {
return errors.New("item not found")
t.Store[item.ID()] = item
t.nameLookupTable[item.Name()] = item.ID()
func (t *GenericStore[T]) Update(item T) error {
_, ok := t.Store[item.ID()]
if ok {
return nil
t.Store[item.ID()] = item
t.nameLookupTable[item.Name()] = item.ID()
return nil
func (t *GenericStore[T]) Delete(item T) error {
delete(t.Store, item.ID())
func (t *GenericStore[T]) Get(query Query) (T, error) {
// First search for direct hit on UUID.
item, ok := t.Store[query.ID]
if !ok {
// Second search for name
id, ok := t.nameLookupTable[query.Name]
if !ok {
return *new(T), errors.New("item not found")
}
item, ok := t.Store[id]
if !ok {
return *new(T), errors.New("item not found")
}
return item, nil
}
return item, nil
}
func (t *GenericStore[T]) GetAll() ([]T, error) {
var allItems []T
for _, item := range t.Store {
allItems = append(allItems, item)