ss13_se/storage_sqlite.go
2017-07-15 18:08:17 +02:00

154 lines
3.4 KiB
Go

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
}