smon/trigger.go
2024-04-30 21:23:05 +02:00

180 lines
3.1 KiB
Go

package main
import (
// External
we "git.gibonuddevalla.se/go/wrappederror"
"github.com/expr-lang/expr"
// Standard
"encoding/json"
"fmt"
"strings"
)
type Trigger struct {
ID int
Name string
SectionID int `db:"section_id"`
Expression string
Datapoints []string
}
func Foo() {
}
func TriggersRetrieve() (areas []Area, err error) { // {{{
areas = []Area{}
row := service.Db.Conn.QueryRow(`
WITH section_triggers AS (
SELECT
s.id AS id,
s.area_id,
s.name AS name,
jsonb_agg(
to_jsonb(t.*)
) AS triggers
FROM section s
LEFT JOIN "trigger" t ON t.section_id = s.id
GROUP BY
s.id, s.name)
SELECT
jsonb_agg(jsonsections)
FROM (
SELECT
a.id,
a.name,
jsonb_agg(
to_jsonb(
s.*
)
) AS sections
FROM area a
LEFT JOIN section_triggers s ON s.area_id = a.id
GROUP BY
a.id, a.name
) jsonsections
`,
)
var jsonData []byte
err = row.Scan(&jsonData)
if err != nil {
err = we.Wrap(err)
return
}
err = json.Unmarshal(jsonData, &areas)
if err != nil {
err = we.Wrap(err)
return
}
return
} // }}}
func TriggersRetrieveByDatapoint(datapointName string) (triggers []Trigger, err error) { // {{{
triggers = []Trigger{}
row := service.Db.Conn.QueryRow(`
SELECT jsonb_agg(t.*)
FROM public."trigger" t
WHERE
datapoints @> $1
`,
fmt.Sprintf(`["%s"]`, datapointName),
)
var data []byte
err = row.Scan(&data)
if err != nil {
err = we.Wrap(err).WithData(datapointName)
return
}
err = json.Unmarshal(data, &triggers)
if err != nil {
err = we.Wrap(err).WithData(datapointName)
return
}
return
} // }}}
func TriggerRetrieve(id int) (trigger Trigger, err error) { // {{{
row := service.Db.Conn.QueryRow(`SELECT to_jsonb(t.*) FROM "trigger" t WHERE id=$1`, id)
var jsonData []byte
err = row.Scan(&jsonData)
if err != nil {
err = we.Wrap(err)
return
}
err = json.Unmarshal(jsonData, &trigger)
return
} // }}}
func (t *Trigger) Validate() (ok bool, err error) { // {{{
if strings.TrimSpace(t.Name) == "" {
err = fmt.Errorf("Name can't be empty")
return
}
if strings.TrimSpace(t.Expression) == "" {
err = fmt.Errorf("Expression can't be empty")
return
}
return true, nil
} // }}}
func (t *Trigger) Update() (err error) { // {{{
var ok bool
if ok, err = t.Validate(); !ok {
return
}
logger.Info("FOO", "trigger", t)
_, err = service.Db.Conn.Exec(`
UPDATE "trigger"
SET
name=$2,
expression=$3
WHERE
id=$1
`,
t.ID,
t.Name,
t.Expression,
)
if err != nil {
err = we.Wrap(err)
}
return
} // }}}
func (t *Trigger) Run() (output any, err error) { // {{{
datapoints := make(map[string]Datapoint)
for _, dpname := range t.Datapoints {
var dp Datapoint
dp, err = DatapointRetrieve(0, dpname)
if err != nil {
err = we.Wrap(err)
return
}
datapoints[dpname] = dp
}
env := make(map[string]any)
for dpName, dp := range datapoints {
env[dpName] = dp.LastDatapointValue.Value()
}
program, err := expr.Compile(t.Expression)
if err != nil {
return
}
output, err = expr.Run(program, env)
if err != nil {
return
}
return
} // }}}