-
Notifications
You must be signed in to change notification settings - Fork 4
/
database.go
157 lines (130 loc) · 2.92 KB
/
database.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
import (
"errors"
"github.com/dustin/seriesly/timelib"
"github.com/vimrus/tickdb/storage"
"log"
"os"
"path/filepath"
"strings"
)
var (
ErrDBNotFound = errors.New("Database not found")
ErrDBExists = errors.New("Database exists")
ErrDBCreate = errors.New("Create database failed")
ErrKeyNotFound = errors.New("Key not found")
)
type indexConns map[string]*storage.DB
var dbConns = make(map[string]indexConns)
type PostData struct {
Time string `json:"time"`
Index string `json:"index"`
Value map[string]float64 `json:"value"`
}
func dbcreate(path string) error {
if _, err := os.Stat(path); err == nil {
return ErrDBExists
}
if err := os.Mkdir(path, 0666); err != nil {
return ErrDBCreate
}
return nil
}
func dbopen(path string) error {
if _, err := os.Stat(path); err != nil {
return ErrDBNotFound
}
return nil
}
func dbconn(path, index string) (*storage.DB, error) {
if _, ok := dbConns[path]; !ok {
if err := dbopen(path); err != nil {
return nil, err
}
idx, err := storage.Open(path + "/" + index)
dbConns[path] = make(map[string]*storage.DB)
dbConns[path][index] = idx
return idx, err
}
if idx, ok := dbConns[path][index]; !ok {
var err error
idx, err = storage.Open(path + "/" + index)
dbConns[path][index] = idx
return idx, err
}
return dbConns[path][index], nil
}
func dbstore(path string, k int64, data []PostData) error {
for _, row := range data {
storage, dbErr := dbconn(path, row.Index)
if dbErr != nil {
return dbErr
}
t, err := timelib.ParseTime(row.Time)
if err != nil {
return err
}
err = storage.Put(t.UnixNano(), row.Value)
if err != nil {
return nil
}
}
return nil
}
func dbget(path string, index string, ts int64) (interface{}, error) {
db, dbErr := dbconn(path, index)
if dbErr != nil {
return nil, dbErr
}
point, err := db.Get(ts)
if err != nil {
return nil, err
}
return point.Value, nil
}
func dbquery(path string, query Query) (interface{}, error) {
db, dbErr := dbconn(path, query.Index)
if dbErr != nil {
return nil, dbErr
}
return execQuery(db, query)
}
func dbdelete(path string) error {
return os.Remove(path)
}
func dblist(root string) []string {
list := []string{}
filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
if err == nil {
if info.IsDir() && p != root {
list = append(list, dbBase(p))
}
} else {
log.Printf("Error on %#v: %v", p, err)
}
return nil
})
return list
}
func dbBase(path string) string {
left := 0
right := len(path)
if strings.HasPrefix(path, *dbRoot) {
left = len(*dbRoot)
if path[left] == '/' {
left++
}
}
return path[left:right]
}
func indexdelete(path, index string) error {
return os.Remove(path + "/" + index)
}
func pointremove(path, index string, from, to int64) error {
storage, dbErr := dbconn(path, index)
if dbErr != nil {
return dbErr
}
storage.Delete(from, to)
return nil
}