Documentation
¶
Overview ¶
Package transactor decorates any r3.CRUD[T, ID] to surface the driver's transaction support, transparently satisfying the same interface and passing standard methods through to the inner repo.
Transactions in r3 are opt-in: drivers that support them implement r3.Transactor (BeginTx). The decorator delegates when the inner CRUD satisfies it, else returns r3.ErrTransactionsNotSupported.
Supported drivers ¶
All SQL-based drivers support transactions out of the box:
- r3pgx (PostgreSQL via pgx)
- r3pq (PostgreSQL via lib/pq)
- r3mysql (MySQL)
- r3sqlite3 (SQLite)
- r3gorm (GORM)
- r3bun (Bun)
- r3gopg (go-pg)
MongoDB (r3mongo) does not currently implement Transactor.
Usage ¶
inner := r3pgx.NewPgxCRUD[User, int64](db)
repo := transactor.WithTransactor[User, int64](inner)
// repo satisfies r3.CRUD[User, int64] - all methods pass through.
// Additionally:
repo.SupportsTransactions() // true for SQL drivers
// Start a transaction manually:
tx, err := repo.BeginTx(ctx)
if err != nil { ... }
defer tx.Rollback()
tx.Create(ctx, user)
tx.Commit()
// Or use the convenience helper:
err := repo.InTx(ctx, func(tx r3.CRUD[User, int64]) error {
_, err := tx.Create(ctx, user)
return err
})
Composability ¶
The decorator can be stacked with other feature decorators:
repo := transactor.WithTransactor(
history.WithHistory(
softdelete.WithSoftDelete(inner), store, ...opts),
)
Index ¶
- type CRUD
- func (c *CRUD[T, ID]) Aggregate(ctx context.Context, qarg ...r3.Query) ([]r3.AggregateRow, error)
- func (c *CRUD[T, ID]) AggregateThroughRelation(ctx context.Context, relation string, qarg ...r3.Query) ([]r3.AggregateRow, error)
- func (c *CRUD[T, ID]) BeginTx(ctx context.Context) (r3.TxCRUD[T, ID], error)
- func (c *CRUD[T, ID]) Count(ctx context.Context, qarg ...r3.Query) (int64, error)
- func (c *CRUD[T, ID]) Create(ctx context.Context, entity T) (T, error)
- func (c *CRUD[T, ID]) Delete(ctx context.Context, id ID) error
- func (c *CRUD[T, ID]) Get(ctx context.Context, id ID, qarg ...r3.Query) (T, error)
- func (c *CRUD[T, ID]) InTx(ctx context.Context, fn func(tx r3.CRUD[T, ID]) error) error
- func (c *CRUD[T, ID]) Inner() r3.CRUD[T, ID]
- func (c *CRUD[T, ID]) List(ctx context.Context, qarg ...r3.Query) ([]T, int64, error)
- func (c *CRUD[T, ID]) Patch(ctx context.Context, entity T, fields r3.Fields) (T, error)
- func (c *CRUD[T, ID]) PatchWhere(ctx context.Context, filters r3.Filters, entity T, fields r3.Fields) (int64, error)
- func (c *CRUD[T, ID]) SupportsTransactions() bool
- func (c *CRUD[T, ID]) Unwrap() r3.CRUD[T, ID]
- func (c *CRUD[T, ID]) Update(ctx context.Context, entity T) (T, error)
- func (c *CRUD[T, ID]) Upsert(ctx context.Context, entity T, opts ...r3.UpsertOption) (T, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CRUD ¶
type CRUD[T any, ID comparable] struct { // contains filtered or unexported fields }
CRUD adds transaction capabilities to the inner repo (BeginTx delegated when it implements r3.Transactor, else r3.ErrTransactionsNotSupported); standard methods pass through unchanged. See the package doc.
func WithTransactor ¶
func WithTransactor[T any, ID comparable](inner r3.CRUD[T, ID]) *CRUD[T, ID]
WithTransactor wraps inner with transaction capabilities.
func (*CRUD[T, ID]) Aggregate ¶ added in v0.0.3
Aggregate passes through to the inner CRUD's Aggregate.
func (*CRUD[T, ID]) AggregateThroughRelation ¶ added in v0.0.5
func (c *CRUD[T, ID]) AggregateThroughRelation( ctx context.Context, relation string, qarg ...r3.Query, ) ([]r3.AggregateRow, error)
AggregateThroughRelation passes through to the inner CRUD.
func (*CRUD[T, ID]) BeginTx ¶
BeginTx starts a transaction if the backend supports it. It walks the chain below the transactor to the backend, begins the transaction there, and re-applies the same decorator stack on top - so the returned r3.TxCRUD is fully decorated and in-transaction writes are still validated, audited, permission-checked, etc. Returns r3.ErrTransactionsNotSupported if no layer implements r3.Transactor.
func (*CRUD[T, ID]) InTx ¶
InTx runs fn inside a transaction (if supported), committing when fn returns nil and rolling back on an error or panic. Returns r3.ErrTransactionsNotSupported if the inner CRUD does not implement r3.Transactor.
func (*CRUD[T, ID]) PatchWhere ¶ added in v0.0.4
func (c *CRUD[T, ID]) PatchWhere( ctx context.Context, filters r3.Filters, entity T, fields r3.Fields, ) (int64, error)
PatchWhere passes through to the inner CRUD's BulkPatcher capability.
func (*CRUD[T, ID]) SupportsTransactions ¶
SupportsTransactions reports whether the backend (seen through any decorators below the transactor) supports transactions, and so can use BeginTx / InTx.
func (*CRUD[T, ID]) Unwrap ¶
Unwrap returns the wrapped CRUD so decorator-chain walks (capability detection, transaction propagation) can reach the backend.