-
Notifications
You must be signed in to change notification settings - Fork 11
/
namespaced.go
90 lines (72 loc) · 2.39 KB
/
namespaced.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package bolt
import (
"context"
"fmt"
"go.etcd.io/bbolt"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
)
var _ inmem.BackingStore = (*NamespacedBackingStore)(nil)
// NamespacedBackingStore implements inmem.BackingStore for a given namespace.
type NamespacedBackingStore struct {
store *BackingStore
namespace resource.Namespace
}
// Put implements inmem.BackingStore.
func (store *NamespacedBackingStore) Put(_ context.Context, resourceType resource.Type, res resource.Resource) error {
marshaled, err := store.store.marshaler.MarshalResource(res)
if err != nil {
return err
}
return store.store.db.Update(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists([]byte(store.namespace))
if err != nil {
return err
}
typeBucket, err := bucket.CreateBucketIfNotExists([]byte(resourceType))
if err != nil {
return err
}
return typeBucket.Put([]byte(res.Metadata().ID()), marshaled)
})
}
// Destroy implements inmem.BackingStore.
func (store *NamespacedBackingStore) Destroy(_ context.Context, resourceType resource.Type, ptr resource.Pointer) error {
return store.store.db.Update(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists([]byte(store.namespace))
if err != nil {
return err
}
typeBucket, err := bucket.CreateBucketIfNotExists([]byte(resourceType))
if err != nil {
return err
}
return typeBucket.Delete([]byte(ptr.ID()))
})
}
// Load implements inmem.BackingStore.
func (store *NamespacedBackingStore) Load(_ context.Context, handler inmem.LoadHandler) error {
return store.store.db.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket([]byte(store.namespace))
if bucket == nil {
return nil
}
return bucket.ForEach(func(typeKey, val []byte) error {
if val != nil {
return fmt.Errorf("expected only buckets, got value for key %v", string(typeKey))
}
typeBucket := bucket.Bucket(typeKey)
resourceType := resource.Type(typeKey)
return typeBucket.ForEach(func(_, marshaled []byte) error {
res, err := store.store.marshaler.UnmarshalResource(marshaled)
if err != nil {
return err
}
return handler(resourceType, res)
})
})
})
}