Documentation
¶
Overview ¶
Package softdelete provides a decorator for r3.CRUD[T, ID] that adds Restore and HardDelete capabilities to any CRUD implementation that supports soft-delete.
It follows the same decorator pattern as features/history: the decorator wraps any r3.CRUD[T, ID] and transparently satisfies the same interface, passing all seven CRUD methods through to the inner implementation.
Soft-delete filtering and Delete-as-UPDATE logic remain in the engines (engine/sql, engine/mongo) and ORM drivers (gorm, bun, gopg). The decorator only adds new capabilities:
- Restore: un-deletes a soft-deleted record by clearing its deleted_at field.
- HardDelete: permanently removes a record, bypassing soft-delete.
These operations are delegated to the inner CRUD if it implements the SoftDeleter[ID] interface. If it does not, ErrNotSoftDeletable is returned.
Usage:
inner := r3pgx.NewPgxCRUD[User, int64](db) repo := softdelete.WithSoftDelete[User, int64](inner) // repo satisfies r3.CRUD[User, int64] — all methods pass through. // Additionally: repo.Restore(ctx, userID) // un-deletes repo.HardDelete(ctx, userID) // permanent delete
Index ¶
- Variables
- type CRUD
- func (s *CRUD[T, ID]) Aggregate(ctx context.Context, qarg ...r3.Query) ([]r3.AggregateRow, error)
- func (s *CRUD[T, ID]) Count(ctx context.Context, qarg ...r3.Query) (int64, error)
- func (s *CRUD[T, ID]) Create(ctx context.Context, entity T) (T, error)
- func (s *CRUD[T, ID]) Delete(ctx context.Context, id ID) error
- func (s *CRUD[T, ID]) Get(ctx context.Context, id ID, qarg ...r3.Query) (T, error)
- func (s *CRUD[T, ID]) HardDelete(ctx context.Context, id ID) error
- func (s *CRUD[T, ID]) Inner() r3.CRUD[T, ID]
- func (s *CRUD[T, ID]) List(ctx context.Context, qarg ...r3.Query) ([]T, int64, error)
- func (s *CRUD[T, ID]) Patch(ctx context.Context, entity T, fields r3.Fields) (T, error)
- func (s *CRUD[T, ID]) PatchWhere(ctx context.Context, filters r3.Filters, entity T, fields r3.Fields) (int64, error)
- func (s *CRUD[T, ID]) Restore(ctx context.Context, id ID) error
- func (s *CRUD[T, ID]) Rewrap(inner r3.CRUD[T, ID]) r3.CRUD[T, ID]
- func (s *CRUD[T, ID]) Unwrap() r3.CRUD[T, ID]
- func (s *CRUD[T, ID]) Update(ctx context.Context, entity T) (T, error)
- func (s *CRUD[T, ID]) Upsert(ctx context.Context, entity T, opts ...r3.UpsertOption) (T, error)
- type SoftDeleter
Constants ¶
This section is empty.
Variables ¶
var ErrNotSoftDeletable = errors.New("r3/softdelete: inner CRUD does not implement SoftDeleter")
ErrNotSoftDeletable is returned when Restore or HardDelete is called on a decorator whose inner CRUD does not implement the SoftDeleter interface.
Functions ¶
This section is empty.
Types ¶
type CRUD ¶
type CRUD[T any, ID comparable] struct { // contains filtered or unexported fields }
CRUD is a decorator that wraps any r3.CRUD[T, ID] and adds Restore and HardDelete capabilities. All seven standard CRUD methods are passed through to the inner implementation unchanged.
Restore and HardDelete are delegated to the inner CRUD if it implements the SoftDeleter[ID] interface. Otherwise, ErrNotSoftDeletable is returned.
func WithSoftDelete ¶
func WithSoftDelete[T any, ID comparable](inner r3.CRUD[T, ID]) *CRUD[T, ID]
WithSoftDelete wraps an existing r3.CRUD with soft-delete capabilities (Restore and HardDelete). All standard CRUD methods pass through unchanged.
func (*CRUD[T, ID]) Aggregate ¶ added in v0.0.3
Aggregate passes through to the inner CRUD's Aggregate (trashed filtering is an engine concern, like List/Count).
func (*CRUD[T, ID]) HardDelete ¶
HardDelete permanently removes a record, bypassing soft-delete. It looks for SoftDeleter support anywhere in the inner decorator chain. Returns ErrNotSoftDeletable if no layer implements SoftDeleter.
func (*CRUD[T, ID]) PatchWhere ¶ added in v0.0.4
func (s *CRUD[T, ID]) PatchWhere( ctx context.Context, filters r3.Filters, entity T, fields r3.Fields, ) (int64, error)
PatchWhere forwards to the inner CRUD's BulkPatcher capability, returning r3.ErrBulkPatchNotSupported when the inner repo does not implement it.
func (*CRUD[T, ID]) Restore ¶
Restore un-deletes a soft-deleted record by clearing its deleted_at field. It looks for SoftDeleter support anywhere in the inner decorator chain, so it works even when other decorators sit between this one and the backend. Returns ErrNotSoftDeletable if no layer implements SoftDeleter.
func (*CRUD[T, ID]) Rewrap ¶
Rewrap rebuilds this decorator around a different inner CRUD (used to re-apply the soft-delete layer on top of a transaction-bound CRUD).
func (*CRUD[T, ID]) Unwrap ¶
Unwrap returns the wrapped CRUD so capability detection and transaction propagation can walk the decorator chain.
type SoftDeleter ¶
type SoftDeleter[ID comparable] interface { // Restore un-deletes a soft-deleted record by clearing its deleted_at field. Restore(ctx context.Context, id ID) error // HardDelete permanently removes a record, bypassing soft-delete. HardDelete(ctx context.Context, id ID) error }
SoftDeleter is an optional interface that CRUD implementations can satisfy to support soft-delete restore and hard-delete operations.
Engine-based drivers (engine/sql, engine/mongo) and ORM drivers (gorm, bun, gopg) implement this interface. The decorator checks for it at runtime.