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