-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathfileType.go
132 lines (117 loc) · 2.63 KB
/
fileType.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
package db
import (
"bytes"
"encoding/gob"
"fmt"
"io"
"log"
"os"
"path/filepath"
"sync"
)
var lock sync.Mutex
var once sync.Once
var pathFromEnv string //This will be set through the build command, see Makefile
const (
fileName = "firewalld-rest.db"
defaultPath = "./"
)
//singleton reference
var fileTypeInstance *fileType
//fileType is the main struct for file database
type fileType struct {
path string
}
//GetFileTypeInstance returns the singleton instance of the filedb object
func GetFileTypeInstance() Instance {
once.Do(func() {
path := defaultPath + fileName
if pathFromEnv != "" {
pathFromEnv = parsePath(pathFromEnv)
pathFromEnv += fileName
path = pathFromEnv
}
fileTypeInstance = &fileType{path: path}
})
return fileTypeInstance
}
//Type of the db
func (fileType *fileType) Type() string {
return "fileType"
}
// Register interface with gob
func (fileType *fileType) Register(v interface{}) {
gob.Register(v)
}
// Save saves a representation of v to the file at path.
func (fileType *fileType) Save(v interface{}) error {
lock.Lock()
defer lock.Unlock()
f, err := os.Create(fileType.path)
if err != nil {
return err
}
defer f.Close()
r, err := marshal(v)
if err != nil {
return err
}
_, err = io.Copy(f, r)
return err
}
// Load loads the file at path into v.
func (fileType *fileType) Load(v interface{}) error {
fullPath, err := filepath.Abs(fileType.path)
if err != nil {
return fmt.Errorf("could not locate absolute path : %v", err)
}
if fileExists(fileType.path) {
lock.Lock()
defer lock.Unlock()
f, err := os.Open(fileType.path)
if err != nil {
return err
}
defer f.Close()
return unmarshal(f, v)
}
log.Printf("Db file not found, will be created here: %v\n", fullPath)
return nil
}
// marshal is a function that marshals the object into an
// io.Reader.
var marshal = func(v interface{}) (io.Reader, error) {
var buf bytes.Buffer
e := gob.NewEncoder(&buf)
err := e.Encode(v)
if err != nil {
return nil, err
}
return bytes.NewReader(buf.Bytes()), nil
}
// unmarshal is a function that unmarshals the data from the
// reader into the specified value.
var unmarshal = func(r io.Reader, v interface{}) error {
d := gob.NewDecoder(r)
err := d.Decode(v)
if err != nil {
return err
}
return nil
}
// fileExists checks if a file exists and is not a directory before we
// try using it to prevent further errors.
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
func parsePath(path string) string {
lastChar := path[len(path)-1:]
if lastChar != "/" {
path += "/"
}
return path
}