softdelete

package
v0.0.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package softdelete decorates any r3.CRUD[T, ID] with Restore and HardDelete, transparently satisfying the same interface and passing all standard methods through to the inner repo.

Soft-delete filtering and Delete-as-UPDATE stay in the engines (engine/sql, engine/mongo) and ORM drivers (gorm, bun, gopg); this decorator only adds:

  • Restore: un-deletes a soft-deleted record by clearing its deleted_at field.
  • HardDelete: permanently removes a record, bypassing soft-delete.

Both delegate to the inner CRUD when it implements SoftDeleter[ID], else return ErrNotSoftDeletable.

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

Constants

This section is empty.

Variables

View Source
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 adds Restore and HardDelete to the inner repo (delegated when it implements SoftDeleter[ID], else ErrNotSoftDeletable); standard methods pass through unchanged. See the package doc.

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

func (s *CRUD[T, ID]) Aggregate(ctx context.Context, qarg ...r3.Query) ([]r3.AggregateRow, error)

Aggregate passes through to the inner CRUD's Aggregate (trashed filtering is an engine concern, like List/Count).

func (*CRUD[T, ID]) AggregateThroughRelation added in v0.0.5

func (s *CRUD[T, ID]) AggregateThroughRelation(
	ctx context.Context, relation string, qarg ...r3.Query,
) ([]r3.AggregateRow, error)

AggregateThroughRelation passes through to the inner CRUD (trashed filtering is an engine concern, like List/Count).

func (*CRUD[T, ID]) Count

func (s *CRUD[T, ID]) Count(ctx context.Context, qarg ...r3.Query) (int64, error)

Count passes through to the inner CRUD.

func (*CRUD[T, ID]) Create

func (s *CRUD[T, ID]) Create(ctx context.Context, entity T) (T, error)

Create passes through to the inner CRUD.

func (*CRUD[T, ID]) Delete

func (s *CRUD[T, ID]) Delete(ctx context.Context, id ID) error

Delete passes through to the inner CRUD.

func (*CRUD[T, ID]) Get

func (s *CRUD[T, ID]) Get(ctx context.Context, id ID, qarg ...r3.Query) (T, error)

Get passes through to the inner CRUD.

func (*CRUD[T, ID]) HardDelete

func (s *CRUD[T, ID]) HardDelete(ctx context.Context, id ID) error

HardDelete permanently removes a record, bypassing soft-delete. It finds SoftDeleter anywhere in the inner chain. Returns ErrNotSoftDeletable if no layer implements it.

func (*CRUD[T, ID]) Inner

func (s *CRUD[T, ID]) Inner() r3.CRUD[T, ID]

Inner returns the wrapped CRUD (for advanced usage / unwrapping).

func (*CRUD[T, ID]) List

func (s *CRUD[T, ID]) List(ctx context.Context, qarg ...r3.Query) ([]T, int64, error)

List passes through to the inner CRUD.

func (*CRUD[T, ID]) Patch

func (s *CRUD[T, ID]) Patch(ctx context.Context, entity T, fields r3.Fields) (T, error)

Patch passes through to the inner CRUD.

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

func (s *CRUD[T, ID]) Restore(ctx context.Context, id ID) error

Restore un-deletes a soft-deleted record by clearing its deleted_at field. It finds SoftDeleter anywhere in the inner chain, so it works even with other decorators between here and the backend. Returns ErrNotSoftDeletable if no layer implements it.

func (*CRUD[T, ID]) Rewrap

func (s *CRUD[T, ID]) Rewrap(inner r3.CRUD[T, ID]) r3.CRUD[T, ID]

Rewrap rebuilds this decorator around inner, re-applying the soft-delete layer on top of a transaction-bound CRUD.

func (*CRUD[T, ID]) Unwrap

func (s *CRUD[T, ID]) Unwrap() r3.CRUD[T, ID]

Unwrap returns the wrapped CRUD so decorator-chain walks (capability detection, transaction propagation) can reach the backend.

func (*CRUD[T, ID]) Update

func (s *CRUD[T, ID]) Update(ctx context.Context, entity T) (T, error)

Update passes through to the inner CRUD.

func (*CRUD[T, ID]) Upsert added in v0.0.4

func (s *CRUD[T, ID]) Upsert(ctx context.Context, entity T, opts ...r3.UpsertOption) (T, error)

Upsert forwards to the inner CRUD's Upserter capability (soft-delete adds no concern to an upsert), returning r3.ErrUpsertNotSupported when the inner repo does not implement it.

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 the optional interface a CRUD satisfies to support restore and hard-delete. The engine drivers (engine/sql, engine/mongo) and ORM drivers (gorm, bun, gopg) implement it; the decorator checks for it at runtime.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL