Skip to content

Commit 13b3dd9

Browse files
authored
Memory datastore (#111)
1 parent fee4ca3 commit 13b3dd9

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

pkg/datastore/memory.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package datastore
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log/slog"
7+
"sync"
8+
"time"
9+
10+
v1 "github.com/metal-stack/masterdata-api/api/v1"
11+
)
12+
13+
type memoryDatastore[E Entity] struct {
14+
lock sync.RWMutex
15+
entities map[string]E
16+
entity string
17+
log *slog.Logger
18+
}
19+
20+
func NewMemory[E Entity](log *slog.Logger, e E) Storage[E] {
21+
entity := e.JSONField()
22+
return &memoryDatastore[E]{
23+
lock: sync.RWMutex{},
24+
entities: make(map[string]E),
25+
entity: entity,
26+
log: log,
27+
}
28+
}
29+
30+
// Create implements Storage.
31+
func (m *memoryDatastore[E]) Create(ctx context.Context, ve E) error {
32+
m.log.Debug("create", "entity", m.entity, "value", ve)
33+
meta := ve.GetMeta()
34+
if meta == nil {
35+
return fmt.Errorf("create of type:%s failed, meta is nil", m.entity)
36+
}
37+
38+
id := ve.GetMeta().Id
39+
m.lock.Lock()
40+
defer m.lock.Unlock()
41+
42+
_, ok := m.entities[id]
43+
if ok {
44+
return NewDuplicateKeyError(fmt.Sprintf("an entity of type:%s with the id:%s already exists", m.entity, id))
45+
}
46+
m.entities[id] = ve
47+
return nil
48+
}
49+
50+
// Delete implements Storage.
51+
func (m *memoryDatastore[E]) Delete(ctx context.Context, id string) error {
52+
m.log.Debug("delete", "entity", m.entity, "id", id)
53+
54+
m.lock.Lock()
55+
defer m.lock.Unlock()
56+
57+
_, ok := m.entities[id]
58+
if !ok {
59+
return NewNotFoundError(fmt.Sprintf("not found: delete of %s with id %s", m.entity, id))
60+
}
61+
delete(m.entities, id)
62+
63+
return nil
64+
}
65+
66+
// DeleteAll implements Storage.
67+
func (m *memoryDatastore[E]) DeleteAll(ctx context.Context, ids ...string) error {
68+
m.entities = make(map[string]E)
69+
return nil
70+
}
71+
72+
// Find implements Storage.
73+
func (m *memoryDatastore[E]) Find(ctx context.Context, filter map[string]any, paging *v1.Paging) ([]E, *uint64, error) {
74+
m.log.Debug("find", "entity", m.entity, "filter", filter)
75+
76+
m.lock.Lock()
77+
defer m.lock.Unlock()
78+
79+
var result []E
80+
for _, e := range m.entities {
81+
// FIXME implement filtering
82+
result = append(result, e)
83+
}
84+
85+
return result, nil, nil
86+
}
87+
88+
// Get implements Storage.
89+
func (m *memoryDatastore[E]) Get(ctx context.Context, id string) (E, error) {
90+
m.log.Debug("get", "entity", m.entity, "id", id)
91+
var zero E
92+
m.lock.Lock()
93+
defer m.lock.Unlock()
94+
95+
e, ok := m.entities[id]
96+
if !ok {
97+
return zero, NewNotFoundError(fmt.Sprintf("not found: delete of %s with id %s", m.entity, id))
98+
}
99+
100+
return e, nil
101+
}
102+
103+
// GetHistory implements Storage.
104+
func (m *memoryDatastore[E]) GetHistory(ctx context.Context, id string, at time.Time, ve E) error {
105+
panic("unimplemented")
106+
}
107+
108+
// GetHistoryCreated implements Storage.
109+
func (m *memoryDatastore[E]) GetHistoryCreated(ctx context.Context, id string, ve E) error {
110+
panic("unimplemented")
111+
}
112+
113+
// Update implements Storage.
114+
func (m *memoryDatastore[E]) Update(ctx context.Context, ve E) error {
115+
m.log.Debug("update", "entity", m.entity)
116+
meta := ve.GetMeta()
117+
if meta == nil {
118+
return fmt.Errorf("update of type:%s failed, meta is nil", m.entity)
119+
}
120+
id := ve.GetMeta().Id
121+
m.lock.Lock()
122+
defer m.lock.Unlock()
123+
124+
_, ok := m.entities[id]
125+
if !ok {
126+
return NewNotFoundError(fmt.Sprintf("not found: delete of %s with id %s", m.entity, id))
127+
}
128+
129+
m.entities[id] = ve
130+
return nil
131+
}

0 commit comments

Comments
 (0)