-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.go
140 lines (116 loc) · 2.81 KB
/
db.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
140
// db.go
//
// captures all db interactions
//
package main
import (
"errors"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/tidwall/buntdb"
"github.com/tidwall/gjson"
)
var buntDB *buntdb.DB
//
// opens the database on the file system
// and loads all curriculm json resources
//
func initialiseDB() {
// Open the data.db file. It will be created if it doesn't exist.
var dbErr error
buntDB, dbErr = buntdb.Open("./db/data.db")
if dbErr != nil {
log.Fatal("error opening database: ", dbErr)
}
log.Println("database opened.")
// walk the directory of json files & commit them to db
root := "./nsw"
err := filepath.Walk(root, visitAndCommit)
log.Printf("filepath.Walk() for %s complete returned error %v\n", root, err)
}
//
// compacts and closes the db
//
func closeDB() {
err := buntDB.Shrink()
if err != nil {
log.Println("error compacting database: ", err)
}
err = buntDB.Close()
if err != nil {
log.Println("error closing database: ", err)
}
log.Println("...database closed")
}
//
// called for each file the curriculum directory walker encounters
// if a .json file is found, content committed to db.
//
func visitAndCommit(path string, fi os.FileInfo, err error) error {
//
// make sure we only list .json files
//
if fi.Mode().IsRegular() && strings.HasSuffix(path, ".json") {
commitErr := commitJSON(path)
if commitErr != nil {
return commitErr
}
// log.Println("successfully committed: ", path)
}
return nil
}
//
// reads the content of a json file and commits it to the
// local db with a key derived from the file path.
//
func commitJSON(path string) error {
// read the file
jsonFile, err := os.Open(path)
if err != nil {
return err
}
// retrieve bytes into json string
jsonBytes, err := ioutil.ReadAll(jsonFile)
if err != nil {
return err
}
jsonString := gjson.ParseBytes(jsonBytes).Raw
if !gjson.Valid(jsonString) {
log.Println("could not read valid json from file: ", path)
}
// create the key for the json data string
keyName := strings.Replace(strings.TrimSuffix(path, ".json"), string(os.PathSeparator), "-", -1)
// log.Println("derived key:\t", keyName)
// commit to the db
txErr := buntDB.Update(func(tx *buntdb.Tx) error {
_, _, err := tx.Set(keyName, jsonString, nil)
return err
})
return txErr
}
//
// for the given key returns a map[string]interface{} rendering
// of the relevant json in the db
//
func getJSONMap(key string) (map[string]interface{}, error) {
var result gjson.Result
err := buntDB.View(func(tx *buntdb.Tx) error {
val, err := tx.Get(key)
if err != nil {
return err
}
result = gjson.Parse(val)
return nil
})
if err != nil {
return nil, err
}
jsonMap, ok := result.Value().(map[string]interface{})
if !ok {
return nil, errors.New("value from db is not a json object")
}
return jsonMap, nil
}