package main import ( // External werr "git.gibonuddevalla.se/go/wrappederror" // Standard "database/sql" "encoding/json" "sort" ) type Area struct { ID int Name string Sections []Section } func AreaRetrieve() (areas []Area, err error) { // {{{ areas = []Area{} row := service.Db.Conn.QueryRow(` 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 = service.Db.Conn.Exec(`INSERT INTO area(name) VALUES($1)`, name) return } // }}} func AreaRename(id int, name string) (err error) { // {{{ _, err = service.Db.Conn.Exec(`UPDATE area SET name=$2 WHERE id=$1`, id, name) return } // }}} func AreaDelete(id int) (err error) { // {{{ var trx *sql.Tx trx, err = service.Db.Conn.Begin() if err != nil { err = werr.Wrap(err).WithData(id) } _, err = trx.Exec(` 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() if err2 != nil { return werr.Wrap(err2).WithData(err) } return werr.Wrap(err).WithData(id) } _, err = trx.Exec(`DELETE FROM public.section WHERE area_id = $1`, id) if err != nil { err2 := trx.Rollback() if err2 != nil { return werr.Wrap(err2).WithData(err) } return werr.Wrap(err).WithData(id) } _, err = trx.Exec(`DELETE FROM public.area WHERE id = $1`, id) if err != nil { err2 := trx.Rollback() if err2 != nil { return werr.Wrap(err2).WithData(err) } return werr.Wrap(err).WithData(id) } err = trx.Commit() if err != nil { err2 := trx.Rollback() 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 } // }}}