154 lines
3.4 KiB
Go
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
|
|
}
|