package database import ( "context" "database/sql" "fmt" ) // WithinTransaction is a functional equivalent of the Transactor interface created by Thibaut Rousseau's // https://blog.thibaut-rousseau.com/blog/sql-transactions-in-go-the-good-way/ func WithinTransaction(f Func) Func { return func(ctx context.Context, db *sql.DB) error { tx, err := db.BeginTx(ctx, nil) if err != nil { return fmt.Errorf("failed to begin transaction: %w", err) } if err := f(ctx, db); err != nil { _ = tx.Rollback() return err } if err := tx.Commit(); err != nil { return fmt.Errorf("failed to commit transaction: %w", err) } return nil } }