package main import ( "context" "database/sql/driver" "errors" "sync/atomic" ) // This driver models an acknowledgement lost AFTER persistence. Applications // use their normal SQL driver; this is solely a runnable fault demonstration. type demoConnector struct { beginErr, commitErr, rollbackErr error persistBeforeError bool stored atomic.Bool } func (d *demoConnector) Connect(context.Context) (driver.Conn, error) { return &demoConn{owner: d}, nil } func (d *demoConnector) Driver() driver.Driver { return d } func (d *demoConnector) Open(string) (driver.Conn, error) { return d.Connect(context.Background()) } type demoConn struct{ owner *demoConnector } func (c *demoConn) Prepare(string) (driver.Stmt, error) { return nil, errors.New("not implemented by demo") } func (c *demoConn) Close() error { return nil } func (c *demoConn) Begin() (driver.Tx, error) { if c.owner.beginErr != nil { return nil, c.owner.beginErr } return &demoTx{owner: c.owner}, nil } func (c *demoConn) ExecContext(context.Context, string, []driver.NamedValue) (driver.Result, error) { return driver.RowsAffected(1), nil } type demoTx struct{ owner *demoConnector } func (tx *demoTx) Commit() error { if tx.owner.commitErr == nil || tx.owner.persistBeforeError { tx.owner.stored.Store(true) } return tx.owner.commitErr } func (tx *demoTx) Rollback() error { return tx.owner.rollbackErr }