forked from lmas/ss13.se
-
Notifications
You must be signed in to change notification settings - Fork 1
/
storage_sqlite.go
153 lines (129 loc) · 3.39 KB
/
storage_sqlite.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
package ss13_se
import (
"time"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
)
const sqliteScheme string = `
CREATE TABLE IF NOT EXISTS server_entry(
id TEXT UNIQUE,
title STRING,
site_url STRING,
game_url STRING,
time DATETIME,
players INTEGER
);
CREATE INDEX IF NOT EXISTS idx_server_entry ON server_entry(time, players, title);
CREATE TABLE IF NOT EXISTS server_history (
id INTEGER PRIMARY KEY,
time DATETIME,
server_id TEXT,
players INTEGER
);
CREATE INDEX IF NOT EXISTS idx_server_history ON server_history(time, server_id);
`
type StorageSqlite struct {
*sqlx.DB
Path string
}
func (store *StorageSqlite) Open() error {
db, err := sqlx.Connect("sqlite3", store.Path)
if err != nil {
return err
}
_, err = db.Exec(sqliteScheme)
if err != nil {
return err
}
store.DB = db
return nil
}
func (store *StorageSqlite) SaveServers(servers []ServerEntry) error {
tx, err := store.Begin()
if err != nil {
return err
}
q := `INSERT OR REPLACE INTO server_entry (id, title, site_url, game_url, time, players) VALUES(?, ?, ?, ?, ?, ?);`
for _, s := range servers {
_, err := tx.Exec(q, s.ID, s.Title, s.SiteURL, s.GameURL, s.Time, s.Players)
if err != nil {
tx.Rollback() // TODO: handle error?
return err
}
}
return tx.Commit()
}
func (store *StorageSqlite) GetServer(id string) (ServerEntry, error) {
var server ServerEntry
q := `SELECT * FROM server_entry WHERE id = ? LIMIT 1;`
err := store.Get(&server, q, id)
if err != nil {
return ServerEntry{}, err
}
return server, nil
}
func (store *StorageSqlite) GetServers() ([]ServerEntry, error) {
var servers []ServerEntry
q := `SELECT * FROM server_entry ORDER BY players DESC, id ASC;`
err := store.Select(&servers, q)
if err != nil {
return nil, err
}
return servers, nil
}
func (store *StorageSqlite) RemoveServers(servers []ServerEntry) error {
tx, err := store.Begin()
if err != nil {
return err
}
qHistory := `DELETE FROM server_history WHERE server_id = ?;`
qEntry := `DELETE FROM server_entry WHERE id = ?;`
for _, s := range servers {
_, err := tx.Exec(qHistory, s.ID)
if err != nil {
tx.Rollback() // TODO: handle error?
return err
}
_, err = tx.Exec(qEntry, s.ID)
if err != nil {
tx.Rollback() // TODO: handle error?
return err
}
}
return tx.Commit()
}
func (store *StorageSqlite) SaveServerHistory(points []ServerPoint) error {
tx, err := store.Begin()
if err != nil {
return err
}
q := `INSERT INTO server_history (time, server_id, players) VALUES(?, ?, ?);`
for _, p := range points {
_, err := tx.Exec(q, p.Time, p.ServerID, p.Players)
if err != nil {
tx.Rollback() // TODO: handle error?
return err
}
}
return tx.Commit()
}
func (store *StorageSqlite) GetServerHistory(days int) ([]ServerPoint, error) {
var points []ServerPoint
delta := time.Now().AddDate(0, 0, -days)
q := `SELECT time,server_id,players FROM server_history WHERE time > ? ORDER BY time DESC, server_id ASC;`
err := store.Select(&points, q, delta)
if err != nil {
return nil, err
}
return points, nil
}
func (store *StorageSqlite) GetSingleServerHistory(id string, days int) ([]ServerPoint, error) {
var points []ServerPoint
delta := time.Now().AddDate(0, 0, -days)
q := `SELECT time,server_id,players FROM server_history WHERE server_id = ? AND time > ? ORDER BY time DESC;`
err := store.Select(&points, q, id, delta)
if err != nil {
return nil, err
}
return points, nil
}