-
Notifications
You must be signed in to change notification settings - Fork 55
/
storage.go
102 lines (86 loc) · 2.56 KB
/
storage.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
91
92
93
94
95
96
97
98
99
100
101
102
package unleash
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/Unleash/unleash-client-go/v4/api"
)
// Storage is an interface that can be implemented in order to have control over how
// the repository of feature toggles is persisted.
type Storage interface {
// Init is called to initialize the storage implementation. The backupPath
// is used to specify the location the data should be stored and the appName
// can be used in naming.
Init(backupPath string, appName string)
// Reset is called after the repository has fetched the feature toggles from the server.
// If persist is true the implementation of this function should call Persist(). The data
// passed in here should be owned by the implementer of this interface.
Reset(data map[string]interface{}, persist bool) error
// Load is called to load the data from persistent storage and hold it in memory for fast
// querying.
Load() error
// Persist is called when the data in the storage implementation should be persisted to disk.
Persist() error
// Get returns the data for the specified feature toggle.
Get(string) (interface{}, bool)
// List returns a list of all feature toggles.
List() []interface{}
}
// DefaultStorage is a default Storage implementation.
type DefaultStorage struct {
appName string
path string
data map[string]interface{}
}
func (ds *DefaultStorage) Init(backupPath, appName string) {
ds.appName = appName
ds.path = filepath.Join(backupPath, fmt.Sprintf("unleash-repo-schema-v1-%s.json", appName))
ds.data = map[string]interface{}{}
ds.Load()
}
func (ds *DefaultStorage) Reset(data map[string]interface{}, persist bool) error {
ds.data = data
if persist {
return ds.Persist()
}
return nil
}
func (ds *DefaultStorage) Load() error {
if file, err := os.Open(ds.path); err != nil {
return err
} else {
dec := json.NewDecoder(file)
var featuresFromFile map[string]api.Feature
if err := dec.Decode(&featuresFromFile); err != nil {
return err
}
for key, value := range featuresFromFile {
ds.data[key] = value
}
}
return nil
}
func (ds *DefaultStorage) Persist() error {
if file, err := os.Create(ds.path); err != nil {
return err
} else {
defer file.Close()
enc := json.NewEncoder(file)
if err := enc.Encode(ds.data); err != nil {
return err
}
}
return nil
}
func (ds DefaultStorage) Get(key string) (interface{}, bool) {
val, ok := ds.data[key]
return val, ok
}
func (ds *DefaultStorage) List() []interface{} {
var features []interface{}
for _, val := range ds.data {
features = append(features, val)
}
return features
}