-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoperations.go
139 lines (116 loc) · 4.63 KB
/
operations.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package flatstorage
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/sirupsen/logrus"
)
// Delete removes a single resource from a collection
func (fs *FlatStorage) Delete(collection string, resource string) error {
if fs.Exists(collection, resource) {
defer fs.UnlockCollection(collection)
fs.LockCollection(collection)
logrus.WithField("collection", collection).WithField("resource", resource).Debug("Removing resource from collection")
return os.Remove(fs.resourcePath(collection, resource))
}
return nil
}
// DeleteAll removes an entire collection from the filesystem
func (fs *FlatStorage) DeleteAll(collection string) error {
if fs.CollectionExists(collection) {
defer fs.UnlockCollection(collection)
fs.LockCollection(collection)
logrus.WithField("collection", collection).Debug("Deleting entire collection")
return os.RemoveAll(fs.collectionPath(collection))
}
return nil
}
// Exists checks if a resource is present in a collection
func (fs *FlatStorage) Exists(collection string, resource string) bool {
return pathExists(fs.resourcePath(collection, resource))
}
// CollectionExists checks if a collection exists
func (fs *FlatStorage) CollectionExists(collection string) bool {
return pathExists(fs.collectionPath(collection))
}
// Read reads a single resource from a collection into an interface instance
func (fs *FlatStorage) Read(collection string, resource string, out interface{}) error {
if !fs.CollectionExists(collection) {
logrus.WithField("collection", collection).Debug("Tried to read resource from non-existent collection")
return collectionNotExistent(collection)
}
if !fs.Exists(collection, resource) {
logrus.WithField("collection", collection).WithField("resource", resource).Debug("Tried to read resource from non-existent collection")
return resourceNotExistent(collection, resource)
}
bytes, err := ioutil.ReadFile(fs.resourcePath(collection, resource))
if err != nil {
logrus.WithField("collection", collection).WithField("resource", resource).Error("Error while trying to read resource", err)
return err
}
err = json.Unmarshal(bytes, &out)
if err != nil {
logrus.WithField("collection", collection).WithField("resource", resource).Error("Error while trying to unmarshal resource", err)
}
return err
}
// ReadAll reads all resources from a collection into an interface array of resourceType
func (fs *FlatStorage) ReadAll(collection string, resourceType interface{}) ([]interface{}, error) {
resourceList := make([]interface{}, 0)
if !fs.CollectionExists(collection) {
return resourceList, collectionNotExistent(collection)
}
resources, err := ioutil.ReadDir(fs.collectionPath(collection))
if err != nil {
logrus.WithField("collection", collection).Error("Error while trying to list resources", err)
return resourceList, err
}
for _, resourceFile := range resources {
var clone = reflect.New(reflect.ValueOf(resourceType).Elem().Type()).Interface()
name := strings.TrimSuffix(resourceFile.Name(), filepath.Ext(resourceFile.Name()))
err := fs.Read(collection, name, &clone)
if err != nil {
return make([]interface{}, 0), err
}
resourceList = append(resourceList, clone)
}
return resourceList, nil
}
// Write writes a single object into a collection from an interface instance
func (fs *FlatStorage) Write(collection string, resource string, object interface{}) error {
if collection == "" {
logrus.Warn("Tried to save resource without collection identifier")
return fmt.Errorf("No collection specified for writing resource")
}
if resource == "" {
logrus.Warn("Tried to save resource without resource identifier")
return fmt.Errorf("No resource specified for writing resource")
}
defer fs.UnlockCollection(collection)
fs.LockCollection(collection)
resPath := fs.resourcePath(collection, resource)
resTempPath := resPath + ".fstemp"
if !fs.CollectionExists(collection) {
err := os.MkdirAll(fs.collectionPath(collection), 0755)
if err != nil {
logrus.WithField("collection", collection).Error("Could not create collection directory", err)
return err
}
}
// Outputs pretty, tab-indented json files
bytes, err := json.MarshalIndent(object, "", "\t")
if err != nil {
logrus.WithField("collection", collection).WithField("resource", resource).Error("Error while marshaling resource", err)
return err
}
if err := ioutil.WriteFile(resTempPath, bytes, 0644); err != nil {
logrus.WithField("collection", collection).WithField("resource", resource).Error("Error while writing resource to disk", err)
return err
}
// Ensure we dont write in the middle of a read access to the file
return os.Rename(resTempPath, resPath)
}