Skip to content

Commit f2a929a

Browse files
refactor: Abstracts historyStore
1 parent 2ac68f4 commit f2a929a

File tree

3 files changed

+105
-37
lines changed

3 files changed

+105
-37
lines changed

hisController.go

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ import (
88
"time"
99

1010
"github.com/google/uuid"
11-
"gorm.io/gorm"
12-
"gorm.io/gorm/clause"
1311
)
1412

1513
type hisController struct {
16-
db *gorm.DB
14+
store historyStore
1715
}
1816

1917
// GET /recs/:pointId/history?start=...&end=...
@@ -34,41 +32,38 @@ func (h hisController) getHis(w http.ResponseWriter, request *http.Request) {
3432
}
3533
params := request.Form
3634

37-
var sqlResult []his
38-
query := h.db.Where(&his{PointId: pointId})
3935
// TODO: Change start/end to ISO8601
36+
var start *time.Time
4037
if params["start"] != nil {
4138
startStr := params["start"][0]
42-
start, err := strconv.ParseInt(startStr, 0, 64)
39+
startUnix, err := strconv.ParseInt(startStr, 0, 64)
4340
if err != nil {
4441
log.Printf("Cannot parse time: %s", startStr)
4542
w.WriteHeader(http.StatusBadRequest)
4643
return
4744
}
48-
query.Where("ts >= ?", time.Unix(start, 0))
45+
startTime := time.Unix(startUnix, 0)
46+
start = &startTime
4947
}
48+
var end *time.Time
5049
if params["end"] != nil {
5150
endStr := params["end"][0]
52-
end, err := strconv.ParseInt(endStr, 0, 64)
51+
endUnix, err := strconv.ParseInt(endStr, 0, 64)
5352
if err != nil {
5453
log.Printf("Cannot parse time: %s", endStr)
5554
w.WriteHeader(http.StatusBadRequest)
5655
return
5756
}
58-
query.Where("ts < ?", time.Unix(end, 0))
57+
endTime := time.Unix(endUnix, 0)
58+
end = &endTime
5959
}
60-
err = query.Order("ts asc").Find(&sqlResult).Error
60+
httpResult, err := h.store.readHistory(pointId, start, end)
6161
if err != nil {
62-
log.Printf("SQL Error: %s", err)
62+
log.Printf("Storage Error: %s", err)
6363
w.WriteHeader(http.StatusInternalServerError)
6464
return
6565
}
6666

67-
httpResult := []apiHis{}
68-
for _, sqlRow := range sqlResult {
69-
httpResult = append(httpResult, apiHis(sqlRow))
70-
}
71-
7267
httpJson, err := json.Marshal(httpResult)
7368
if err != nil {
7469
log.Printf("Cannot encode response JSON")
@@ -98,23 +93,12 @@ func (h hisController) postHis(writer http.ResponseWriter, request *http.Request
9893
writer.WriteHeader(http.StatusBadRequest)
9994
return
10095
}
101-
102-
his := his{
103-
PointId: pointId,
104-
Ts: hisItem.Ts,
105-
Value: hisItem.Value,
106-
}
107-
108-
err = h.db.Clauses(clause.OnConflict{
109-
Columns: []clause.Column{{Name: "pointId"}, {Name: "ts"}},
110-
DoUpdates: clause.AssignmentColumns([]string{"value"}),
111-
}).Create(&his).Error
96+
err = h.store.writeHistory(pointId, hisItem)
11297
if err != nil {
113-
log.Printf("SQL Error: %s", err)
98+
log.Printf("Storage Error: %s", err)
11499
writer.WriteHeader(http.StatusInternalServerError)
115100
return
116101
}
117-
118102
writer.WriteHeader(http.StatusOK)
119103
}
120104

@@ -136,30 +120,32 @@ func (h hisController) deleteHis(writer http.ResponseWriter, request *http.Reque
136120
}
137121
params := request.Form
138122

139-
var sqlResult []his
140-
query := h.db.Where(&his{PointId: pointId})
141123
// TODO: Change start/end to ISO8601
124+
var start *time.Time
142125
if params["start"] != nil {
143126
startStr := params["start"][0]
144-
start, err := strconv.ParseInt(startStr, 0, 64)
127+
startUnix, err := strconv.ParseInt(startStr, 0, 64)
145128
if err != nil {
146129
log.Printf("Cannot parse time: %s", startStr)
147130
writer.WriteHeader(http.StatusBadRequest)
148131
return
149132
}
150-
query.Where("ts >= ?", time.Unix(start, 0))
133+
startTime := time.Unix(startUnix, 0)
134+
start = &startTime
151135
}
136+
var end *time.Time
152137
if params["end"] != nil {
153138
endStr := params["end"][0]
154-
end, err := strconv.ParseInt(endStr, 0, 64)
139+
endUnix, err := strconv.ParseInt(endStr, 0, 64)
155140
if err != nil {
156141
log.Printf("Cannot parse time: %s", endStr)
157142
writer.WriteHeader(http.StatusBadRequest)
158143
return
159144
}
160-
query.Where("ts < ?", time.Unix(end, 0))
145+
endTime := time.Unix(endUnix, 0)
146+
end = &endTime
161147
}
162-
err = query.Delete(&sqlResult).Error
148+
err = h.store.deleteHistory(pointId, start, end)
163149
if err != nil {
164150
log.Printf("SQL Error: %s", err)
165151
writer.WriteHeader(http.StatusInternalServerError)

historyStore.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package main
2+
3+
import (
4+
"time"
5+
6+
"github.com/google/uuid"
7+
"gorm.io/gorm"
8+
"gorm.io/gorm/clause"
9+
)
10+
11+
// historyStore is able to store point historical values
12+
type historyStore interface {
13+
readHistory(uuid.UUID, *time.Time, *time.Time) ([]apiHisItem, error)
14+
writeHistory(uuid.UUID, apiHisItem) error
15+
deleteHistory(uuid.UUID, *time.Time, *time.Time) error
16+
}
17+
18+
// gormHistoryStore stores point historical values in a GORM database.
19+
type gormHistoryStore struct {
20+
db *gorm.DB
21+
}
22+
23+
func newGormHistoryStore(db *gorm.DB) gormHistoryStore {
24+
return gormHistoryStore{db: db}
25+
}
26+
27+
func (s gormHistoryStore) readHistory(
28+
pointId uuid.UUID,
29+
start *time.Time,
30+
end *time.Time,
31+
) ([]apiHisItem, error) {
32+
result := []apiHisItem{}
33+
34+
var sqlResult []his
35+
query := s.db.Where(&his{PointId: pointId})
36+
if start != nil {
37+
query.Where("ts >= ?", start)
38+
}
39+
if end != nil {
40+
query.Where("ts < ?", end)
41+
}
42+
err := query.Order("ts asc").Find(&sqlResult).Error
43+
if err != nil {
44+
return result, err
45+
}
46+
for _, sqlRow := range sqlResult {
47+
result = append(result, apiHisItem{Ts: sqlRow.Ts, Value: sqlRow.Value})
48+
}
49+
return result, nil
50+
}
51+
52+
func (s gormHistoryStore) writeHistory(
53+
pointId uuid.UUID,
54+
hisItem apiHisItem,
55+
) error {
56+
his := his{
57+
PointId: pointId,
58+
Ts: hisItem.Ts,
59+
Value: hisItem.Value,
60+
}
61+
62+
return s.db.Clauses(clause.OnConflict{
63+
Columns: []clause.Column{{Name: "pointId"}, {Name: "ts"}},
64+
DoUpdates: clause.AssignmentColumns([]string{"value"}),
65+
}).Create(&his).Error
66+
}
67+
68+
func (s gormHistoryStore) deleteHistory(
69+
pointId uuid.UUID,
70+
start *time.Time,
71+
end *time.Time,
72+
) error {
73+
var sqlResult []his
74+
query := s.db.Where(&his{PointId: pointId})
75+
if start != nil {
76+
query.Where("ts >= ?", start)
77+
}
78+
if end != nil {
79+
query.Where("ts < ?", end)
80+
}
81+
return query.Delete(&sqlResult).Error
82+
}

server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func NewServer(serverConfig ServerConfig) (*http.ServeMux, error) {
3939

4040
tokenAuth := http.NewServeMux()
4141

42-
hisController := hisController{db: serverConfig.db}
42+
hisController := hisController{store: newGormHistoryStore(serverConfig.db)}
4343
tokenAuth.HandleFunc("GET /his/{pointId}", hisController.getHis) // Deprecated
4444
tokenAuth.HandleFunc("POST /his/{pointId}", hisController.postHis) // Deprecated
4545
tokenAuth.HandleFunc("DELETE /his/{pointId}", hisController.deleteHis) // Deprecated

0 commit comments

Comments
 (0)