smon/datapoint.go

113 lines
2.4 KiB
Go
Raw Normal View History

2024-04-29 08:36:13 +02:00
package main
import (
// External
we "git.gibonuddevalla.se/go/wrappederror"
// Standard
"database/sql"
"time"
)
type DatapointType string
const (
INT DatapointType = "INT"
STRING = "STRING"
DATETIME = "DATETIME"
)
type Datapoint struct {
ID int
Name string
SectionID int `db:"section_id"`
Datatype DatapointType
LastValue time.Time `db:"last_value"`
DatapointValueJSON []byte `db:"datapoint_value_json"`
LastDatapointValue DatapointValue
}
type DatapointValue struct {
ID int
DatapointID int `db:"datapoint_id"`
Ts time.Time
ValueInt sql.NullInt64 `db:"value_int"`
ValueString sql.NullString `db:"value_string"`
ValueDateTime sql.NullTime `db:"value_datetime"`
}
func (dp DatapointValue) Value() any {
if dp.ValueInt.Valid {
return dp.ValueInt.Int64
}
if dp.ValueString.Valid {
return dp.ValueString.String
}
if dp.ValueDateTime.Valid {
return dp.ValueDateTime.Time
}
return nil
}
func DatapointAdd[T any](name string, value T) (err error) {
row := service.Db.Conn.QueryRow(`SELECT id, datatype FROM datapoint WHERE name=$1`, name)
var dpID int
var dpType DatapointType
err = row.Scan(&dpID, &dpType)
if err != nil {
err = we.Wrap(err).WithData(struct {
Name string
Value any
}{name, value})
return
}
switch dpType {
case INT:
_, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_int) VALUES($1, $2)`, dpID, value)
case STRING:
_, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_string) VALUES($1, $2)`, dpID, value)
case DATETIME:
_, err = service.Db.Conn.Exec(`INSERT INTO datapoint_value(datapoint_id, value_datetime) VALUES($1, $2)`, dpID, value)
}
if err != nil {
err = we.Wrap(err).WithData(struct {
ID int
value any
}{dpID, value})
return
}
return
}
func DatapointRetrieve(name string) (dp Datapoint, err error) {
row := service.Db.Conn.QueryRowx(
`SELECT * FROM datapoint dp WHERE dp.name = $1`,
name,
)
err = row.StructScan(&dp)
if err != nil {
err = we.Wrap(err).WithData(name)
return
}
row = service.Db.Conn.QueryRowx(`
SELECT *
FROM datapoint_value
WHERE datapoint_id = $1
ORDER BY ts DESC
LIMIT 1
`,
dp.ID,
)
err = row.StructScan(&dp.LastDatapointValue)
if err != nil {
err = we.Wrap(err).WithData(dp.ID)
return
}
return
}