r3gorm

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package r3gorm is an r3.CRUD[T, ID] driver backed by GORM (gorm.io/gorm). It is the most complete SQL driver: alongside CRUD it wires preloads (native Preload plus r3-managed relations), soft-delete (Unscoped, Restore, HardDelete), transactions, aggregation, upsert, bulk patch, relationship ("has") filters, and transparent value-codec support via GORM serializers.

Index

Constants

This section is empty.

Variables

View Source
var ErrRawNotSupported = errors.New("r3gorm: raw driver access not supported")

ErrRawNotSupported is returned by RawOf and DBOf when the repository is not (and does not unwrap to) a gorm-backed repository. It is driver-specific and deliberately lives here rather than in core r3.

Functions

func DBOf added in v0.0.6

func DBOf[T any, ID comparable](repo r3.CRUD[T, ID]) (*gorm.DB, error)

DBOf returns the underlying *gorm.DB (full raw access: .Exec, .Raw(sql), ...), with the same unwrap and error contract as RawOf. Use it only when GormRaw's builder callback is not enough.

The RawOf caveat applies more sharply: the *gorm.DB bypasses the entire feature stack. Prefer high-level methods for writes; use DBOf for reads or queries that neither a repo method nor RawOf's builder can express.

func NewGormQuerier

func NewGormQuerier[T any, ID comparable](db *gorm.DB, opts ...r3.Option) r3.Querier[T, ID]

NewGormQuerier builds a read-only GORM repository (r3.Querier enforces it).

Types

type GormCRUD

type GormCRUD[T any, ID comparable] struct {
	enginesql.DefaultsManager

	Config r3.Config
	// contains filtered or unexported fields
}

GormCRUD is a CRUD repository based on gorm.DB.

func NewGormCRUD

func NewGormCRUD[T any, ID comparable](db *gorm.DB, opts ...r3.Option) *GormCRUD[T, ID]

NewGormCRUD builds a GORM-based repository.

func (*GormCRUD[T, ID]) Aggregate added in v0.0.3

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

Aggregate computes grouped aggregates over the records matching the query. See r3.Aggregator for the query semantics.

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

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

AggregateThroughRelation aggregates the entity's related rows through a declared relation, grouped and folded over the related base table (the child table for has-many, the join table for many-to-many). See r3.RelationAggregator for the full query semantics.

func (*GormCRUD[T, ID]) BeginTx

func (r *GormCRUD[T, ID]) BeginTx(ctx context.Context) (r3.TxCRUD[T, ID], error)

BeginTx starts a GORM transaction and returns an r3.TxCRUD scoped to it. The caller must call Commit or Rollback on the returned TxCRUD.

func (*GormCRUD[T, ID]) Count

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

Count returns the number of records matching the query's filters.

func (*GormCRUD[T, ID]) Create

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

func (*GormCRUD[T, ID]) DB

func (r *GormCRUD[T, ID]) DB() *gorm.DB

DB returns the underlying *gorm.DB for advanced usage.

func (*GormCRUD[T, ID]) Delete

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

func (*GormCRUD[T, ID]) Get

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

func (*GormCRUD[T, ID]) HardDelete

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

HardDelete permanently removes a record, bypassing GORM's soft-delete.

func (*GormCRUD[T, ID]) List

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

func (*GormCRUD[T, ID]) Patch

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

func (*GormCRUD[T, ID]) PatchWhere added in v0.0.4

func (r *GormCRUD[T, ID]) PatchWhere(
	ctx context.Context, filters r3.Filters, entity T, fields r3.Fields,
) (int64, error)

PatchWhere sets fields (to entity's values) on every row matching filters and returns the affected-row count. It is the multi-row analogue of Patch - same column validation and capability gating (ValidatePatchColumns + RequireMutableColumns), same updated_at bump, same write-guard bypass - but rows are selected by filters instead of by primary key.

Filters are schema-validated and reuse List's filter-to-SQL translation (including relationship "has" filter lowering). Soft-delete exclusion follows GORM's default model scoping.

func (*GormCRUD[T, ID]) Raw

func (r *GormCRUD[T, ID]) Raw() *GormRaw[T, ID]

Raw returns the GormRaw escape hatch for custom queries.

func (*GormCRUD[T, ID]) Restore

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

Restore un-deletes a soft-deleted record by clearing its soft-delete column.

func (*GormCRUD[T, ID]) Update

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

Update writes the entity and returns the row as persisted.

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

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

Upsert inserts entity, or updates the colliding row on a conflict at the conflict target (the primary key by default), via GORM's clause.OnConflict.

The insert branch obeys Creatable and stamps created_at/updated_at (shared writeOmit path); the update branch obeys Mutable and bumps updated_at. The write guard bypass (r3.WithoutWriteGuard) is honored. The stored row is re-fetched by the conflict target and returned, so the result reflects the update, defaults, and triggers even on a collision.

Upsert is row-level and does not sync associations; use Create/Update for entities carrying related rows.

type GormRaw

type GormRaw[T any, ID any] struct {
	// contains filtered or unexported fields
}

GormRaw is the GORM escape hatch, exposing any gorm query via Find/Scan callbacks.

func NewGormRaw

func NewGormRaw[T any, ID comparable](db *gorm.DB) *GormRaw[T, ID]

func RawOf added in v0.0.6

func RawOf[T any, ID comparable](repo r3.CRUD[T, ID]) (*GormRaw[T, ID], error)

RawOf returns the typed gorm raw-builder for repo, unwrapping any decorator chain (via r3.As) down to the gorm backend, or ErrRawNotSupported if repo is not gorm-backed. It saves a hand-written type assertion when a service holds its repo as the backend-agnostic r3.CRUD[T, ID].

The builder runs BELOW the feature decorators (history, permissions, i18n, ...): reads are fine, but a WRITE through it is neither audited, permission-checked, nor stale-marked. Prefer a high-level method for writes; use RawOf only for reads or queries no repo method can express.

func (*GormRaw[T, ID]) Find

func (r *GormRaw[T, ID]) Find(ctx context.Context, cb func(*gorm.DB) *gorm.DB) ([]T, error)

func (*GormRaw[T, ID]) Scan

func (r *GormRaw[T, ID]) Scan(ctx context.Context, cb func(*gorm.DB) *gorm.DB, dest any) error

type RawAccessor added in v0.0.6

type RawAccessor[T any, ID comparable] interface {
	Raw() *GormRaw[T, ID]
	DB() *gorm.DB
}

RawAccessor reaches the typed gorm builder (GormRaw, via Raw) or the *gorm.DB (via DB) of a gorm-backed repo. *GormCRUD[T, ID] already satisfies it; the interface exists so RawOf/DBOf can find it through a decorator chain.

Jump to

Keyboard shortcuts

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