ql.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
  2. package main
  3. import (
  4. "database/sql"
  5. "fmt"
  6. "log"
  7. "github.com/cznic/ql"
  8. )
  9. func init() {
  10. ql.RegisterDriver()
  11. register("ql", qlSetup, qlCompile)
  12. }
  13. func qlSetup(db *sql.DB) (err error) {
  14. tx, err := db.Begin()
  15. if err != nil {
  16. return
  17. }
  18. defer func() {
  19. if err == nil {
  20. err = tx.Commit()
  21. } else {
  22. tx.Rollback()
  23. }
  24. }()
  25. _, err = tx.Exec(`CREATE TABLE IF NOT EXISTS Devices (
  26. DeviceID STRING NOT NULL,
  27. Seen TIME NOT NULL
  28. )`)
  29. if err != nil {
  30. return
  31. }
  32. if _, err = tx.Exec(`CREATE INDEX IF NOT EXISTS DevicesDeviceIDIndex ON Devices (DeviceID)`); err != nil {
  33. return
  34. }
  35. _, err = tx.Exec(`CREATE TABLE IF NOT EXISTS Addresses (
  36. DeviceID STRING NOT NULL,
  37. Seen TIME NOT NULL,
  38. Address STRING NOT NULL,
  39. )`)
  40. if err != nil {
  41. return
  42. }
  43. _, err = tx.Exec(`CREATE INDEX IF NOT EXISTS AddressesDeviceIDAddressIndex ON Addresses (DeviceID, Address)`)
  44. return
  45. }
  46. func qlCompile(db *sql.DB) (map[string]*sql.Stmt, error) {
  47. stmts := map[string]string{
  48. "cleanAddress": `DELETE FROM Addresses WHERE Seen < now() - duration("2h")`,
  49. "cleanDevice": fmt.Sprintf(`DELETE FROM Devices WHERE Seen < now() - duration("%dh")`, maxDeviceAge/3600),
  50. "countAddress": "SELECT count(*) FROM Addresses",
  51. "countDevice": "SELECT count(*) FROM Devices",
  52. "insertAddress": "INSERT INTO Addresses (DeviceID, Seen, Address) VALUES ($1, now(), $2)",
  53. "insertDevice": "INSERT INTO Devices (DeviceID, Seen) VALUES ($1, now())",
  54. "selectAddress": `SELECT Address from Addresses WHERE DeviceID==$1 AND Seen > now() - duration("1h") LIMIT 16`,
  55. "selectDevice": "SELECT Seen FROM Devices WHERE DeviceID==$1",
  56. "updateAddress": "UPDATE Addresses Seen=now() WHERE DeviceID==$1 AND Address==$2",
  57. "updateDevice": "UPDATE Devices Seen=now() WHERE DeviceID==$1",
  58. }
  59. res := make(map[string]*sql.Stmt, len(stmts))
  60. for key, stmt := range stmts {
  61. prep, err := db.Prepare(stmt)
  62. if err != nil {
  63. log.Println("Failed to compile", stmt)
  64. return nil, err
  65. }
  66. res[key] = prep
  67. }
  68. return res, nil
  69. }