113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
|
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
|
||
|
}
|