2015-07-21 22:56:27 +00:00
|
|
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2015-11-13 09:14:19 +00:00
|
|
|
"fmt"
|
2015-07-21 22:56:27 +00:00
|
|
|
"log"
|
|
|
|
|
|
|
|
"github.com/cznic/ql"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
ql.RegisterDriver()
|
|
|
|
register("ql", qlSetup, qlCompile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func qlSetup(db *sql.DB) (err error) {
|
|
|
|
tx, err := db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err == nil {
|
|
|
|
err = tx.Commit()
|
|
|
|
} else {
|
|
|
|
tx.Rollback()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS Devices (
|
|
|
|
DeviceID STRING NOT NULL,
|
|
|
|
Seen TIME NOT NULL
|
|
|
|
)`)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err = tx.Exec(`CREATE INDEX IF NOT EXISTS DevicesDeviceIDIndex ON Devices (DeviceID)`); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS Addresses (
|
|
|
|
DeviceID STRING NOT NULL,
|
|
|
|
Seen TIME NOT NULL,
|
|
|
|
Address STRING NOT NULL,
|
|
|
|
)`)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err = tx.Exec(`CREATE INDEX IF NOT EXISTS AddressesDeviceIDAddressIndex ON Addresses (DeviceID, Address)`); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = tx.Exec(`CREATE TABLE IF NOT EXISTS Relays (
|
|
|
|
DeviceID STRING NOT NULL,
|
|
|
|
Seen TIME NOT NULL,
|
|
|
|
Address STRING NOT NULL,
|
|
|
|
Latency INT NOT NULL,
|
|
|
|
)`)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = tx.Exec(`CREATE INDEX IF NOT EXISTS RelaysDeviceIDAddressIndex ON Relays (DeviceID, Address)`)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func qlCompile(db *sql.DB) (map[string]*sql.Stmt, error) {
|
|
|
|
stmts := map[string]string{
|
|
|
|
"cleanAddress": `DELETE FROM Addresses WHERE Seen < now() - duration("2h")`,
|
|
|
|
"cleanRelay": `DELETE FROM Relays WHERE Seen < now() - duration("2h")`,
|
2015-11-13 09:14:19 +00:00
|
|
|
"cleanDevice": fmt.Sprintf(`DELETE FROM Devices WHERE Seen < now() - duration("%dh")`, maxDeviceAge/3600),
|
2015-07-21 22:56:27 +00:00
|
|
|
"countAddress": "SELECT count(*) FROM Addresses",
|
|
|
|
"countDevice": "SELECT count(*) FROM Devices",
|
|
|
|
"countRelay": "SELECT count(*) FROM Relays",
|
|
|
|
"insertAddress": "INSERT INTO Addresses (DeviceID, Seen, Address) VALUES ($1, now(), $2)",
|
|
|
|
"insertRelay": "INSERT INTO Relays (DeviceID, Seen, Address, Latency) VALUES ($1, now(), $2, $3)",
|
|
|
|
"insertDevice": "INSERT INTO Devices (DeviceID, Seen) VALUES ($1, now())",
|
|
|
|
"selectAddress": `SELECT Address from Addresses WHERE DeviceID==$1 AND Seen > now() - duration("1h") LIMIT 16`,
|
|
|
|
"selectRelay": `SELECT Address, Latency from Relays WHERE DeviceID==$1 AND Seen > now() - duration("1h") LIMIT 16`,
|
2015-11-13 09:14:19 +00:00
|
|
|
"selectDevice": "SELECT Seen FROM Devices WHERE DeviceID==$1",
|
2015-09-13 09:44:33 +00:00
|
|
|
"updateAddress": "UPDATE Addresses Seen=now() WHERE DeviceID==$1 AND Address==$2",
|
2015-07-21 22:56:27 +00:00
|
|
|
"updateDevice": "UPDATE Devices Seen=now() WHERE DeviceID==$1",
|
|
|
|
"deleteRelay": "DELETE FROM Relays WHERE DeviceID==$1",
|
|
|
|
}
|
|
|
|
|
|
|
|
res := make(map[string]*sql.Stmt, len(stmts))
|
|
|
|
for key, stmt := range stmts {
|
|
|
|
prep, err := db.Prepare(stmt)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Failed to compile", stmt)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
res[key] = prep
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
}
|