package database import ( "database/sql" "log" "time" "git.xeserv.us/xena/mercy/internal/common" "github.com/Xe/gorqlite" ) type Results struct { conn gorqlite.Connection insResult gorqlite.PreparedStatement getResultsForCustomer gorqlite.PreparedStatement } func NewResults(conn gorqlite.Connection) *Results { return &Results{ conn: conn, insResult: gorqlite.NewPreparedStatement("INSERT INTO results (timestamp, customer_id, check_id, run_id, result, error_msg) VALUES (%d, %s, %s, %s, %d, %s)"), getResultsForCustomer: gorqlite.NewPreparedStatement("SELECT * FROM results WHERE customer_id=%s"), } } func (r *Results) Migrate() error { ddl := []string{ `CREATE TABLE IF NOT EXISTS results (id INTEGER PRIMARY KEY, timestamp INTEGER, customer_id TEXT NOT NULL, check_id TEXT NOT NULL, run_id TEXT NOT NULL, result INTEGER NOT NULL, error_msg TEXT)`, } _, err := r.conn.Write(ddl) return err } func (r *Results) InsResult(cr common.CheckResult) error { _, err := r.conn.WriteOne(r.insResult.Bind(cr.Timestamp.Unix(), cr.Preamble.CustomerID, cr.Preamble.CheckID, cr.Preamble.RunID, cr.Result, cr.ErrData)) return err } func (r *Results) GetResultsForCustomer(cid string) ([]common.CheckResult, error) { var result []common.CheckResult res, err := r.conn.QueryOne(r.getResultsForCustomer.Bind(cid)) if err != nil { return nil, err } if res.NumRows() == 0 { return nil, sql.ErrNoRows } for res.Next() { var cr common.CheckResult var ts int64 var checkResult int64 err = res.Scan(&cr.Preamble.CheckID, &ts, &cr.Preamble.CustomerID, &cr.Preamble.CheckID, &cr.Preamble.RunID, &checkResult, &cr.ErrData) if err != nil { return nil, err } cr.Timestamp = time.Unix(ts, 0) cr.Result = common.Result(checkResult) result = append(result, cr) } return result, nil } type Checks struct { conn gorqlite.Connection insCheck gorqlite.PreparedStatement getCheck gorqlite.PreparedStatement getAllChecks gorqlite.PreparedStatement getChecksForCustomer gorqlite.PreparedStatement activeCheck gorqlite.PreparedStatement deactiveCheck gorqlite.PreparedStatement removeCheck gorqlite.PreparedStatement updateLastRes gorqlite.PreparedStatement } func NewChecks(conn gorqlite.Connection) *Checks { return &Checks{ conn: conn, insCheck: gorqlite.NewPreparedStatement("INSERT INTO checks (timestamp, customer_id, active, uri, report_webhook, last_result) VALUES (%d, %s, %d, %s, %s, 0)"), getCheck: gorqlite.NewPreparedStatement("SELECT * FROM checks WHERE id=%d"), getAllChecks: gorqlite.NewPreparedStatement("SELECT id, timestamp, customer_id, active, uri, report_webhook, last_result FROM checks WHERE active=1"), getChecksForCustomer: gorqlite.NewPreparedStatement("SELECT * FROM CHECKS WHERE customer_id=%s"), activeCheck: gorqlite.NewPreparedStatement("UPDATE checks SET active=1 WHERE id=%d"), deactiveCheck: gorqlite.NewPreparedStatement("UPDATE checks SET active=0 WHERE id=%d"), removeCheck: gorqlite.NewPreparedStatement("DELETE FROM checks WHERE id=%d"), updateLastRes: gorqlite.NewPreparedStatement("UPDATE checks SET last_result=%d WHERE id=%d"), } } func (c *Checks) Migrate() error { ddl := []string{ `CREATE TABLE IF NOT EXISTS checks (id INTEGER PRIMARY KEY, timestamp INTEGER, customer_id TEXT, active INTEGER, uri TEXT, report_webhook TEXT, last_result INTEGER)`, } _, err := c.conn.Write(ddl) return err } func (c *Checks) InsertCheck(ch *common.Check) error { var active int if ch.Active { active = 1 } res, err := c.conn.WriteOne(c.insCheck.Bind(ch.Timestamp.Unix(), ch.CustomerID, active, ch.URI, ch.ReportWebhook)) if err != nil { return err } ch.ID = res.LastInsertID return nil } func (c *Checks) GetAllChecks() ([]common.Check, error) { var result []common.Check q := c.getAllChecks.Bind() log.Println(q) res, err := c.conn.QueryOne(q) if err != nil { return nil, err } if res.Err != nil { return nil, err } if res.NumRows() == 0 { return nil, sql.ErrNoRows } for res.Next() { var ch common.Check var chid int64 var ts int64 var act int64 var lres int64 err = res.Scan(&chid, &ts, &ch.CustomerID, &act, &ch.URI, &ch.ReportWebhook, &lres) if err != nil { return nil, err } ch.ID = int64(chid) ch.Timestamp = time.Unix(int64(ts), 0) ch.Active = act == 1 ch.LastResult = common.Result(lres) result = append(result, ch) } return result, nil } func (c *Checks) GetCheck(cid int64) (*common.Check, error) { var ch common.Check res, err := c.conn.QueryOne(c.getCheck.Bind(cid)) if err != nil { return nil, err } if res.NumRows() == 0 { return nil, sql.ErrNoRows } if !res.Next() { return nil, sql.ErrNoRows } var ts int64 var act int64 var lres int64 err = res.Scan(&ch.ID, &ts, &ch.CustomerID, &act, &ch.URI, &ch.ReportWebhook, &lres) if err != nil { return nil, err } ch.Timestamp = time.Unix(ts, 0) ch.Active = act == 1 ch.LastResult = common.Result(lres) return &ch, nil } func (c *Checks) UpdateLastResult(cid int64, result common.Result) error { _, err := c.conn.WriteOne(c.updateLastRes.Bind(int64(result), cid)) return err }