smon/area.go
2026-08-19 17:53:52 +02:00

132 lines
2.4 KiB
Go

package main
import (
// External
werr "git.ahall.se/go/wrappederror"
"github.com/jackc/pgx/v5"
// Standard
"context"
"encoding/json"
"sort"
)
type Area struct {
ID int
Name string
Sections []Section
}
func AreaRetrieve() (areas []Area, err error) { // {{{
areas = []Area{}
row := db.QueryRow(context.Background(), `
SELECT
jsonb_agg(jsonsections)
FROM (
SELECT
a.id,
a.name,
jsonb_agg(
jsonb_build_object(
'id', s.id,
'name', s.name
)
) AS sections
FROM area a
LEFT JOIN section 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 = werr.Wrap(err)
return
}
if jsonData == nil {
return
}
err = json.Unmarshal(jsonData, &areas)
if err != nil {
err = werr.Wrap(err)
return
}
return
} // }}}
func AreaCreate(name string) (err error) { // {{{
_, err = db.Exec(context.Background(), `INSERT INTO area(name) VALUES($1)`, name)
return
} // }}}
func AreaRename(id int, name string) (err error) { // {{{
_, err = db.Exec(context.Background(), `UPDATE area SET name=$2 WHERE id=$1`, id, name)
return
} // }}}
func AreaDelete(id int) (err error) { // {{{
ctx := context.Background()
var trx pgx.Tx
trx, err = db.Begin(ctx)
if err != nil {
err = werr.Wrap(err).WithData(id)
}
_, err = trx.Exec(context.Background(), `
DELETE
FROM trigger t
USING section s
WHERE
t.section_id = s.id AND
s.area_id = $1
`,
id,
)
if err != nil {
err2 := trx.Rollback(ctx)
if err2 != nil {
return werr.Wrap(err2).WithData(err)
}
return werr.Wrap(err).WithData(id)
}
_, err = trx.Exec(ctx, `DELETE FROM public.section WHERE area_id = $1`, id)
if err != nil {
err2 := trx.Rollback(ctx)
if err2 != nil {
return werr.Wrap(err2).WithData(err)
}
return werr.Wrap(err).WithData(id)
}
_, err = trx.Exec(ctx, `DELETE FROM public.area WHERE id = $1`, id)
if err != nil {
err2 := trx.Rollback(ctx)
if err2 != nil {
return werr.Wrap(err2).WithData(err)
}
return werr.Wrap(err).WithData(id)
}
err = trx.Commit(ctx)
if err != nil {
err2 := trx.Rollback(ctx)
if err2 != nil {
return werr.Wrap(err2).WithData(err)
}
return werr.Wrap(err).WithData(id)
}
return nil
} // }}}
func (a Area) SortedSections() []Section { // {{{
sort.SliceStable(a.Sections, func(i, j int) bool {
return a.Sections[i].Name < a.Sections[j].Name
})
return a.Sections
} // }}}