Monorepo for Tangled
tangled.org
1package rbac
2
3import (
4 "database/sql"
5 "log/slog"
6 "slices"
7)
8
9type Txn struct {
10 SQLTx *sql.Tx
11 undos []func() error
12 committed bool
13}
14
15func NewTxn(sqlTx *sql.Tx) *Txn {
16 return &Txn{SQLTx: sqlTx}
17}
18
19func (t *Txn) AddUndo(undo func() error) {
20 t.undos = append(t.undos, undo)
21}
22
23func (t *Txn) Commit() error {
24 if err := t.SQLTx.Commit(); err != nil {
25 return err
26 }
27 t.committed = true
28 return nil
29}
30
31func (t *Txn) Cleanup(l *slog.Logger) {
32 if t.committed {
33 return
34 }
35 t.SQLTx.Rollback()
36 for _, undo := range slices.Backward(t.undos) {
37 if err := undo(); err != nil {
38 l.Error("failed to reverse ACL change", "err", err)
39 }
40 }
41}