drel

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 11 Imported by: 0

README

Drel

Code-generation-based Go ORM for Postgres. Type-safe queries, snapshot-based change tracking, zero runtime reflection.

Installation

go install github.com/alternayte/drel/cmd/drel@latest

Quick Start

1. Define a model
package models

import "github.com/alternayte/drel"

type Task struct {
    drel.Model[int]
    Title    string `db:"title"`
    Done     bool   `db:"done"`
    Priority int    `db:"priority"`
}

func NewTask(title string, priority int) *Task {
    return &Task{Title: title, Priority: priority}
}

func (t *Task) MarkDone() { t.Done = true }
2. Generate code
drel generate

This produces type-safe query builders, scan functions, snapshot/diff helpers, and a DB struct that aggregates all discovered models.

3. Use it
// Open the generated DB
database, err := db.Open(dsn)

// Insert via transaction with change tracking
err = database.Transaction(ctx, func(tx *drel.Tx) error {
    repo := drel.NewTxRepository(tx, models.TaskMeta)
    repo.Add(models.NewTask("Build ORM", 1))
    return nil
})

// Query with generated type-safe columns
tasks, err := database.Tasks.
    Where(models.Tasks.Done.IsFalse()).
    OrderBy(models.Tasks.Priority.Asc()).
    All(ctx)

// Update with change tracking (only modified columns are UPDATEd)
err = database.Transaction(ctx, func(tx *drel.Tx) error {
    repo := drel.NewTxRepository(tx, models.TaskMeta)
    task, err := repo.Find(ctx, 1)
    if err != nil {
        return err
    }
    task.MarkDone()
    return nil
})

Features

  • No reflection -- all scanning, diffing, and query building use generated code.
  • Snapshot-based change tracking -- only modified columns appear in UPDATE statements.
  • Type-safe query builder -- compile-time checked column predicates and ordering (Eq, In, Between, ILike, Raw).
  • Transactions -- explicit transaction API with configurable isolation levels and automatic flush on commit.
  • Soft delete, versioning, audit -- embed drel.SoftDelete, drel.Versioned, or drel.Audit for automatic column management.
  • Relationships -- generated RelationInfo and IncludeSpec for has-many, has-one, belongs-to, and many-to-many eager loading with cross-package support. Filter-aware includes respect soft-delete on related models, with Unscoped() opt-out.
  • Bulk operations -- BulkInsert, BulkUpdate, BulkDelete, BulkUpsert with batching and safety guards.
  • Domain events -- register and dispatch events on entity lifecycle.
  • Raw SQL escape hatches -- Engine.Exec, Engine.Query, Engine.QueryRow, and Tx.Exec, Tx.QueryRow for anything the ORM does not cover.

Examples

See examples/ for working samples:

Limitations

  • Postgres only (SQLite/LibSQL planned).
  • Migration generation produces full schema; incremental diffing is not yet automated — treat generated SQL as a scaffold and review before applying.
  • Bulk Set accepts any values — type safety is enforced on column predicates and FindByID but not on bulk mutation values.

License

MIT -- see LICENSE.

Documentation

Index

Constants

View Source
const (
	StateUnchanged entityState = iota
	StateAdded
	StateModified
	StateDeleted
)

Variables

View Source
var ErrBulkDeleteRequiresFilter = fmt.Errorf("drel: BulkDelete requires at least one Where predicate to prevent accidental full-table deletes")

BulkUpsert inserts or updates multiple entities based on conflict resolution. It bypasses change tracking and executes directly against the database. Returns the total number of rows affected. ErrBulkDeleteRequiresFilter is returned when BulkDelete is called without any WHERE predicates or filters.

View Source
var ErrConcurrencyConflict = errors.New("drel: concurrency conflict — entity was modified by another transaction")

ErrConcurrencyConflict is returned when an entity was modified by another transaction.

View Source
var ErrEntityNotTracked = errors.New("drel: entity is not tracked")

ErrEntityNotTracked is returned when an operation requires a tracked entity but none is found.

View Source
var ErrNotFound = errors.New("drel: not found")

ErrNotFound is returned when a query expects a result but finds none.

View Source
var SoftDeleteFilter = NamedFilter{
	Name: "soft_delete",
	Clause: ast.WhereClause{
		Comparison: &ast.ComparisonNode{Column: "deleted_at", Op: ast.OpIsNull},
	},
}

Functions

func ActorFromContext

func ActorFromContext(ctx context.Context) string

ActorFromContext extracts the actor identifier from the context, returning an empty string if none is set.

func WithActor

func WithActor(ctx context.Context, actor string) context.Context

WithActor returns a new context carrying the given actor identifier.

Types

type AfterCommitHook

type AfterCommitHook func(ctx context.Context, events []any)

type Audit

type Audit struct {
	// contains filtered or unexported fields
}

func (*Audit) AuditPtrs

func (a *Audit) AuditPtrs() (*string, *string)

func (Audit) CreatedBy

func (a Audit) CreatedBy() string

func (Audit) UpdatedBy

func (a Audit) UpdatedBy() string

type BeforeCommitHook

type BeforeCommitHook func(ctx context.Context, tx *Tx, events []any) error

type BoolColumn

type BoolColumn struct {
	// contains filtered or unexported fields
}

func NewBoolCol

func NewBoolCol(name string) BoolColumn

func (BoolColumn) Asc

func (c BoolColumn) Asc() OrderExpr

func (BoolColumn) Desc

func (c BoolColumn) Desc() OrderExpr

func (BoolColumn) Eq

func (c BoolColumn) Eq(v bool) Predicate

func (BoolColumn) IsFalse

func (c BoolColumn) IsFalse() Predicate

func (BoolColumn) IsNotNull

func (c BoolColumn) IsNotNull() Predicate

func (BoolColumn) IsNull

func (c BoolColumn) IsNull() Predicate

func (BoolColumn) IsTrue

func (c BoolColumn) IsTrue() Predicate

func (BoolColumn) NEQ

func (c BoolColumn) NEQ(v bool) Predicate

func (BoolColumn) Name

func (c BoolColumn) Name() string

type Column

type Column[T any] struct {
	// contains filtered or unexported fields
}

func NewCol

func NewCol[T any](name string) Column[T]

func (Column[T]) Asc

func (c Column[T]) Asc() OrderExpr

func (Column[T]) Desc

func (c Column[T]) Desc() OrderExpr

func (Column[T]) Eq

func (c Column[T]) Eq(v T) Predicate

func (Column[T]) In

func (c Column[T]) In(vs ...T) Predicate

func (Column[T]) IsNotNull

func (c Column[T]) IsNotNull() Predicate

func (Column[T]) IsNull

func (c Column[T]) IsNull() Predicate

func (Column[T]) NEQ

func (c Column[T]) NEQ(v T) Predicate

func (Column[T]) Name

func (c Column[T]) Name() string

func (Column[T]) NotIn

func (c Column[T]) NotIn(vs ...T) Predicate

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine holds a database driver and dialect for executing queries.

func NewEngine

func NewEngine(dsn string, opts ...Option) (*Engine, error)

NewEngine creates a new Engine connected to the given DSN.

func (*Engine) Close

func (e *Engine) Close()

Close shuts down the underlying database connection.

func (*Engine) Exec

func (e *Engine) Exec(ctx context.Context, sql string, args ...any) (int64, error)

Exec executes a raw SQL statement and returns the number of rows affected.

func (*Engine) OnAfterCommit

func (e *Engine) OnAfterCommit(hook AfterCommitHook)

func (*Engine) OnBeforeCommit

func (e *Engine) OnBeforeCommit(hook BeforeCommitHook)

func (*Engine) OnQuery

func (e *Engine) OnQuery(hook QueryHook)

OnQuery registers a hook that is called after every query execution.

func (*Engine) Query

func (e *Engine) Query(ctx context.Context, sql string, args ...any) (Rows, error)

Query executes a raw SQL query and returns the result rows. The caller must close the returned Rows when done.

func (*Engine) QueryRow

func (e *Engine) QueryRow(ctx context.Context, sql string, args ...any) Row

QueryRow executes a raw SQL query that is expected to return at most one row.

func (*Engine) Transaction

func (e *Engine) Transaction(ctx context.Context, fn func(tx *Tx) error, opts ...TxOption) (retErr error)

Transaction runs fn inside a database transaction. If fn returns nil the transaction is committed; otherwise it is rolled back. Pending changes in the Tx change tracker are flushed automatically before commit.

type EventRecorder

type EventRecorder interface {
	PendingEvents() []any
	ClearEvents()
}

type FieldChange

type FieldChange struct {
	Column string
	Value  any
}

FieldChange represents a single column value that has changed on an entity.

type IncludableQuery

type IncludableQuery[T any] struct {
	// contains filtered or unexported fields
}

IncludableQuery constructs queries that eagerly load related entities.

func (*IncludableQuery[T]) All

func (q *IncludableQuery[T]) All(ctx context.Context) ([]*T, error)

All returns all records and loads included relationships.

func (*IncludableQuery[T]) Find

func (q *IncludableQuery[T]) Find(ctx context.Context, id any) (*T, error)

Find looks up a single record by primary key and loads included relationships.

type IncludeSpec

type IncludeSpec struct {
	// contains filtered or unexported fields
}

IncludeSpec wraps a RelationInfo for use with Include queries.

func NewIncludeSpec

func NewIncludeSpec(rel *RelationInfo) IncludeSpec

NewIncludeSpec creates an IncludeSpec from a RelationInfo.

func (IncludeSpec) Unscoped

func (s IncludeSpec) Unscoped() IncludeSpec

Unscoped returns a copy of the IncludeSpec that bypasses global filters (e.g. soft delete) when loading the related entities.

type IsolationLevel

type IsolationLevel int

IsolationLevel represents the transaction isolation level.

const (
	// ReadCommitted is the default isolation level.
	ReadCommitted IsolationLevel = iota
	// RepeatableRead prevents non-repeatable reads.
	RepeatableRead
	// Serializable provides full serializability.
	Serializable
)

type Model

type Model[K comparable] struct {
	// contains filtered or unexported fields
}

func (*Model[K]) ClearEvents

func (m *Model[K]) ClearEvents()

func (Model[K]) CreatedAt

func (m Model[K]) CreatedAt() time.Time

func (Model[K]) ID

func (m Model[K]) ID() K

func (*Model[K]) PendingEvents

func (m *Model[K]) PendingEvents() []any

func (*Model[K]) RecordEvent

func (m *Model[K]) RecordEvent(event any)

func (*Model[K]) ScanPtrs

func (m *Model[K]) ScanPtrs() (*K, *time.Time, *time.Time)

ScanPtrs returns pointers to the base model fields for use in row scanning. Generated code calls this to obtain scan destinations for id, createdAt, and updatedAt without directly accessing unexported fields.

func (Model[K]) UpdatedAt

func (m Model[K]) UpdatedAt() time.Time

type ModelMeta

type ModelMeta[T any] struct {
	Table          string
	Columns        []string
	PKColumn       string
	Scan           func(Row) (*T, error)
	Snapshot       func(*T) any
	Diff           func(*T, any) []FieldChange
	PKValue        func(*T) any
	InsertColumns  func(*T) ([]string, []any)
	ScanReturning  func(*T, Row) error
	ColumnValue    func(*T, int) any
	Filters        []NamedFilter
	HasSoftDelete  bool
	HasVersioned   bool
	HasAudit       bool
	VersionValue   func(*T) int
	SetVersion     func(*T, int)
	AuditSetCreate func(*T, string)
	AuditSetUpdate func(*T, string)
}

ModelMeta describes the database mapping for a model type T.

type ModelMetaBase

type ModelMetaBase struct {
	Table          string
	Columns        []string
	PKColumn       string
	Snapshot       func(entity any) any
	Diff           func(entity any, snapshot any) []FieldChange
	PKValue        func(entity any) any
	InsertColumns  func(entity any) ([]string, []any)
	ScanRow        func(Row) (any, error)
	ScanReturning  func(entity any, row Row) error
	ColumnValue    func(entity any, colIdx int) any
	HasSoftDelete  bool
	HasVersioned   bool
	HasAudit       bool
	VersionValue   func(entity any) int
	SetVersion     func(entity any, v int)
	AuditSetCreate func(entity any, actor string)
	AuditSetUpdate func(entity any, actor string)
	Filters        []NamedFilter
}

ModelMetaBase is the type-erased version of ModelMeta[T], used internally by the change tracker and relationship loading infrastructure.

func ToMetaBase

func ToMetaBase[T any](meta *ModelMeta[T]) *ModelMetaBase

ToMetaBase converts a typed ModelMeta[T] to a type-erased ModelMetaBase.

type MultiColumnMapper

type MultiColumnMapper interface {
	DrelColumns() []string
	DrelValues() ([]any, error)
	DrelScanMulti(vals []any) error
}

MultiColumnMapper is implemented by value objects that map to multiple database columns (e.g., Money → amount + currency).

type NamedFilter

type NamedFilter struct {
	Name   string
	Clause ast.WhereClause
}

type Option

type Option func(*engineConfig)

Option configures Engine creation.

func WithContext

func WithContext(ctx context.Context) Option

WithContext sets the context used during engine creation.

type OrderExpr

type OrderExpr struct {
	// contains filtered or unexported fields
}

func (OrderExpr) ToAST

func (o OrderExpr) ToAST() ast.OrderByExpr

type OrderedColumn

type OrderedColumn[T cmp.Ordered] struct {
	// contains filtered or unexported fields
}

func NewOrderedCol

func NewOrderedCol[T cmp.Ordered](name string) OrderedColumn[T]

func (OrderedColumn[T]) Asc

func (c OrderedColumn[T]) Asc() OrderExpr

func (OrderedColumn[T]) Between

func (c OrderedColumn[T]) Between(low, high T) Predicate

func (OrderedColumn[T]) Desc

func (c OrderedColumn[T]) Desc() OrderExpr

func (OrderedColumn[T]) Eq

func (c OrderedColumn[T]) Eq(v T) Predicate

func (OrderedColumn[T]) GT

func (c OrderedColumn[T]) GT(v T) Predicate

func (OrderedColumn[T]) GTE

func (c OrderedColumn[T]) GTE(v T) Predicate

func (OrderedColumn[T]) In

func (c OrderedColumn[T]) In(vs ...T) Predicate

func (OrderedColumn[T]) IsNotNull

func (c OrderedColumn[T]) IsNotNull() Predicate

func (OrderedColumn[T]) IsNull

func (c OrderedColumn[T]) IsNull() Predicate

func (OrderedColumn[T]) LT

func (c OrderedColumn[T]) LT(v T) Predicate

func (OrderedColumn[T]) LTE

func (c OrderedColumn[T]) LTE(v T) Predicate

func (OrderedColumn[T]) NEQ

func (c OrderedColumn[T]) NEQ(v T) Predicate

func (OrderedColumn[T]) Name

func (c OrderedColumn[T]) Name() string

func (OrderedColumn[T]) NotIn

func (c OrderedColumn[T]) NotIn(vs ...T) Predicate

type Predicate

type Predicate struct {
	// contains filtered or unexported fields
}

func And

func And(preds ...Predicate) Predicate

func Not

func Not(pred Predicate) Predicate

func Or

func Or(preds ...Predicate) Predicate

func Raw

func Raw(sql string, args ...any) Predicate

Raw creates a predicate from a raw SQL expression with bound arguments. Use ? as placeholder for each argument; they are rewritten to $N for Postgres. Panics if the number of ? placeholders does not match the number of arguments.

func (Predicate) ToAST

func (p Predicate) ToAST() ast.WhereClause

type QueryBuilder

type QueryBuilder[T any] struct {
	// contains filtered or unexported fields
}

QueryBuilder constructs and executes typed queries with an immutable builder pattern.

func (*QueryBuilder[T]) All

func (q *QueryBuilder[T]) All(ctx context.Context) ([]*T, error)

All executes the query and returns all matching results.

func (*QueryBuilder[T]) BulkDelete

func (q *QueryBuilder[T]) BulkDelete(ctx context.Context) (int, error)

BulkDelete deletes all rows matching the builder's WHERE conditions. If the model has soft delete, it performs a soft delete instead. Returns the number of affected rows.

func (*QueryBuilder[T]) BulkUpdate

func (q *QueryBuilder[T]) BulkUpdate(ctx context.Context, sets ...SetClause) (int, error)

BulkUpdate updates all rows matching the builder's WHERE conditions. Returns the number of affected rows.

func (*QueryBuilder[T]) Count

func (q *QueryBuilder[T]) Count(ctx context.Context) (int, error)

Count returns the number of matching rows.

func (*QueryBuilder[T]) Exists

func (q *QueryBuilder[T]) Exists(ctx context.Context) (bool, error)

Exists returns true if at least one matching row exists.

func (*QueryBuilder[T]) First

func (q *QueryBuilder[T]) First(ctx context.Context) (*T, error)

First returns the first matching result or ErrNotFound if none exist.

func (*QueryBuilder[T]) FirstOrNil

func (q *QueryBuilder[T]) FirstOrNil(ctx context.Context) (*T, error)

FirstOrNil returns the first matching result or nil if none exist.

func (*QueryBuilder[T]) Limit

func (q *QueryBuilder[T]) Limit(n int) *QueryBuilder[T]

Limit restricts the number of results returned.

func (*QueryBuilder[T]) OrderBy

func (q *QueryBuilder[T]) OrderBy(exprs ...OrderExpr) *QueryBuilder[T]

OrderBy sets the ordering for the query.

func (*QueryBuilder[T]) Skip

func (q *QueryBuilder[T]) Skip(n int) *QueryBuilder[T]

Skip sets the offset for the query (number of rows to skip).

func (*QueryBuilder[T]) Unscoped

func (q *QueryBuilder[T]) Unscoped() *QueryBuilder[T]

Unscoped returns a new builder with all global filters removed.

func (*QueryBuilder[T]) Where

func (q *QueryBuilder[T]) Where(pred Predicate) *QueryBuilder[T]

Where adds a filter predicate. Multiple calls are ANDed together.

func (*QueryBuilder[T]) WithoutFilter

func (q *QueryBuilder[T]) WithoutFilter(name string) *QueryBuilder[T]

WithoutFilter returns a new builder with the named filter removed.

type QueryEvent

type QueryEvent struct {
	SQL      string
	Args     []any
	Duration time.Duration
	Err      error
}

QueryEvent contains information about an executed query.

type QueryHook

type QueryHook func(ctx context.Context, event QueryEvent)

QueryHook is called after every query execution.

type RawExpr

type RawExpr struct {
	SQL string
}

RawExpr represents a raw SQL expression to embed in a query (e.g., NOW()).

type Relation

type Relation[T any] struct {
	// contains filtered or unexported fields
}

func NewRelation

func NewRelation[T any](name string) Relation[T]

func (Relation[T]) Name

func (r Relation[T]) Name() string

type RelationInfo

type RelationInfo struct {
	Name        string
	Type        RelationType
	FKColumn    string
	JoinTable   string // pivot table name (many-to-many only)
	RefColumn   string // target FK column in pivot table (many-to-many only)
	RelatedMeta *ModelMetaBase
	FieldSetter func(parent any, related any)
}

RelationInfo describes a relationship between two models.

type RelationType

type RelationType int

RelationType describes the kind of relationship between two models.

const (
	// HasMany indicates the parent has many related entities (1:N).
	HasMany RelationType = iota
	// HasOne indicates the parent has one related entity (1:1).
	HasOne
	// BelongsTo indicates the entity references a parent via a foreign key.
	BelongsTo
	// ManyToMany indicates a many-to-many relationship via a pivot table.
	ManyToMany
)

type Repository

type Repository[T any] struct {
	// contains filtered or unexported fields
}

Repository provides typed query access for a specific model.

func NewRepository

func NewRepository[T any](engine *Engine, meta ModelMeta[T]) *Repository[T]

NewRepository creates a new Repository for the given model metadata.

func (*Repository[T]) All

func (r *Repository[T]) All(ctx context.Context) ([]*T, error)

All returns all records for this model.

func (*Repository[T]) BulkInsert

func (r *Repository[T]) BulkInsert(ctx context.Context, entities []*T) (int, error)

BulkInsert inserts multiple entities in batches, bypassing change tracking. Returns the total number of rows affected.

func (*Repository[T]) BulkUpsert

func (r *Repository[T]) BulkUpsert(ctx context.Context, entities []*T, opts ...UpsertOption) (int, error)

func (*Repository[T]) Count

func (r *Repository[T]) Count(ctx context.Context) (int, error)

Count returns the total number of records for this model.

func (*Repository[T]) Exists

func (r *Repository[T]) Exists(ctx context.Context) (bool, error)

Exists returns true if any records exist for this model.

func (*Repository[T]) Find

func (r *Repository[T]) Find(ctx context.Context, id any) (*T, error)

Find looks up a single record by its primary key.

func (*Repository[T]) First

func (r *Repository[T]) First(ctx context.Context) (*T, error)

First returns the first record or ErrNotFound.

func (*Repository[T]) FirstOrNil

func (r *Repository[T]) FirstOrNil(ctx context.Context) (*T, error)

FirstOrNil returns the first record or nil.

func (*Repository[T]) Include

func (r *Repository[T]) Include(rels ...IncludeSpec) *IncludableQuery[T]

Include begins a query that will eagerly load the given relationships.

func (*Repository[T]) Limit

func (r *Repository[T]) Limit(n int) *QueryBuilder[T]

Limit starts a query with a row limit.

func (*Repository[T]) OrderBy

func (r *Repository[T]) OrderBy(exprs ...OrderExpr) *QueryBuilder[T]

OrderBy starts an ordered query.

func (*Repository[T]) Unscoped

func (r *Repository[T]) Unscoped() *QueryBuilder[T]

Unscoped returns a query builder with all global filters removed.

func (*Repository[T]) Where

func (r *Repository[T]) Where(pred Predicate) *QueryBuilder[T]

Where starts a filtered query.

func (*Repository[T]) WithoutFilter

func (r *Repository[T]) WithoutFilter(name string) *QueryBuilder[T]

WithoutFilter returns a query builder with the named filter removed.

type Row

type Row interface {
	Scan(dest ...any) error
}

Row represents a single database row that can scan values into destinations.

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Close()
	Err() error
}

Rows represents a set of database rows from a query result.

type SetClause

type SetClause struct {
	Column string
	Value  any
}

SetClause pairs a column name with a value for use in bulk updates and upserts.

func Set

func Set[C interface{ Name() string }, V any](col C, value V) SetClause

Set creates a SetClause from a typed column and value.

type SoftDelete

type SoftDelete struct {
	// contains filtered or unexported fields
}

func (SoftDelete) DeletedAt

func (s SoftDelete) DeletedAt() *time.Time

func (*SoftDelete) DeletedAtPtr

func (s *SoftDelete) DeletedAtPtr() **time.Time

func (SoftDelete) IsDeleted

func (s SoftDelete) IsDeleted() bool

type StringColumn

type StringColumn struct {
	// contains filtered or unexported fields
}

func NewStringCol

func NewStringCol(name string) StringColumn

func (StringColumn) Asc

func (c StringColumn) Asc() OrderExpr

func (StringColumn) Contains

func (c StringColumn) Contains(substr string) Predicate

func (StringColumn) Desc

func (c StringColumn) Desc() OrderExpr

func (StringColumn) Eq

func (c StringColumn) Eq(v string) Predicate

func (StringColumn) GT

func (c StringColumn) GT(v string) Predicate

func (StringColumn) GTE

func (c StringColumn) GTE(v string) Predicate

func (StringColumn) HasPrefix

func (c StringColumn) HasPrefix(prefix string) Predicate

func (StringColumn) HasSuffix

func (c StringColumn) HasSuffix(suffix string) Predicate

func (StringColumn) ILike

func (c StringColumn) ILike(pattern string) Predicate

func (StringColumn) In

func (c StringColumn) In(vs ...string) Predicate

func (StringColumn) IsNotNull

func (c StringColumn) IsNotNull() Predicate

func (StringColumn) IsNull

func (c StringColumn) IsNull() Predicate

func (StringColumn) LT

func (c StringColumn) LT(v string) Predicate

func (StringColumn) LTE

func (c StringColumn) LTE(v string) Predicate

func (StringColumn) Like

func (c StringColumn) Like(pattern string) Predicate

func (StringColumn) NEQ

func (c StringColumn) NEQ(v string) Predicate

func (StringColumn) Name

func (c StringColumn) Name() string

func (StringColumn) NotIn

func (c StringColumn) NotIn(vs ...string) Predicate

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx represents an active database transaction with change tracking.

func (*Tx) Exec

func (tx *Tx) Exec(ctx context.Context, sql string, args ...any) (int64, error)

Exec executes a raw SQL statement within the transaction.

func (*Tx) HardRemove

func (tx *Tx) HardRemove(entity any) error

HardRemove marks a tracked entity for permanent (hard) deletion on the next flush, bypassing soft delete even when the model supports it.

func (*Tx) QueryRow

func (tx *Tx) QueryRow(ctx context.Context, sql string, args ...any) Row

QueryRow executes a raw SQL query within the transaction that returns at most one row.

func (*Tx) SaveChanges

func (tx *Tx) SaveChanges(ctx context.Context) error

SaveChanges flushes all tracked changes within this transaction.

type TxOption

type TxOption func(*txConfig)

TxOption configures transaction behaviour.

func WithIsolation

func WithIsolation(level IsolationLevel) TxOption

WithIsolation sets the isolation level for the transaction.

type TxQueryBuilder

type TxQueryBuilder[T any] struct {
	// contains filtered or unexported fields
}

TxQueryBuilder constructs and executes typed queries within a transaction.

func (*TxQueryBuilder[T]) All

func (q *TxQueryBuilder[T]) All(ctx context.Context) ([]*T, error)

All executes the query and returns all matching results.

func (*TxQueryBuilder[T]) Count

func (q *TxQueryBuilder[T]) Count(ctx context.Context) (int, error)

Count returns the number of matching rows.

func (*TxQueryBuilder[T]) Exists

func (q *TxQueryBuilder[T]) Exists(ctx context.Context) (bool, error)

Exists returns true if at least one matching row exists.

func (*TxQueryBuilder[T]) First

func (q *TxQueryBuilder[T]) First(ctx context.Context) (*T, error)

First returns the first matching result or ErrNotFound if none exist.

func (*TxQueryBuilder[T]) FirstOrNil

func (q *TxQueryBuilder[T]) FirstOrNil(ctx context.Context) (*T, error)

FirstOrNil returns the first matching result or nil if none exist.

func (*TxQueryBuilder[T]) Limit

func (q *TxQueryBuilder[T]) Limit(n int) *TxQueryBuilder[T]

Limit restricts the number of results returned.

func (*TxQueryBuilder[T]) OrderBy

func (q *TxQueryBuilder[T]) OrderBy(exprs ...OrderExpr) *TxQueryBuilder[T]

OrderBy sets the ordering for the query.

func (*TxQueryBuilder[T]) Skip

func (q *TxQueryBuilder[T]) Skip(n int) *TxQueryBuilder[T]

Skip sets the offset for the query (number of rows to skip).

func (*TxQueryBuilder[T]) Unscoped

func (q *TxQueryBuilder[T]) Unscoped() *TxQueryBuilder[T]

Unscoped returns a new builder with all global filters removed.

func (*TxQueryBuilder[T]) Where

func (q *TxQueryBuilder[T]) Where(pred Predicate) *TxQueryBuilder[T]

Where adds a filter predicate. Multiple calls are ANDed together.

func (*TxQueryBuilder[T]) WithoutFilter

func (q *TxQueryBuilder[T]) WithoutFilter(name string) *TxQueryBuilder[T]

WithoutFilter returns a new builder with the named filter removed.

type TxRepository

type TxRepository[T any] struct {
	// contains filtered or unexported fields
}

TxRepository provides tracked query and mutation access within a transaction.

func NewTxRepository

func NewTxRepository[T any](tx *Tx, meta ModelMeta[T]) *TxRepository[T]

NewTxRepository creates a new TxRepository for the given transaction and model metadata.

func (*TxRepository[T]) Add

func (r *TxRepository[T]) Add(entity *T)

Add marks an entity for insertion on the next flush.

func (*TxRepository[T]) All

func (r *TxRepository[T]) All(ctx context.Context) ([]*T, error)

All returns all records for this model within the transaction.

func (*TxRepository[T]) Find

func (r *TxRepository[T]) Find(ctx context.Context, id any) (*T, error)

Find looks up a single record by primary key and begins tracking it.

func (*TxRepository[T]) Remove

func (r *TxRepository[T]) Remove(entity *T) error

Remove marks a tracked entity for deletion on the next flush.

func (*TxRepository[T]) Unscoped

func (r *TxRepository[T]) Unscoped() *TxQueryBuilder[T]

Unscoped returns a query builder with all global filters removed.

func (*TxRepository[T]) Where

func (r *TxRepository[T]) Where(pred Predicate) *TxQueryBuilder[T]

Where starts a filtered query within the transaction.

func (*TxRepository[T]) WithoutFilter

func (r *TxRepository[T]) WithoutFilter(name string) *TxQueryBuilder[T]

WithoutFilter returns a query builder with the named filter removed.

type UpsertOption

type UpsertOption func(*upsertConfig)

UpsertOption configures BulkUpsert behavior.

func ConflictColumns

func ConflictColumns[C interface{ Name() string }](cols ...C) UpsertOption

ConflictColumns specifies which columns form the conflict target for an upsert.

func UpdateOnConflict

func UpdateOnConflict[C interface{ Name() string }](cols ...C) UpsertOption

UpdateOnConflict specifies which columns to update when a conflict is detected.

type Versioned

type Versioned struct {
	// contains filtered or unexported fields
}

func (Versioned) Version

func (v Versioned) Version() int

func (*Versioned) VersionPtr

func (v *Versioned) VersionPtr() *int

Directories

Path Synopsis
cmd
drel command
examples
api command
Example: api
Example: api
bulk-ops command
Example: bulk-ops
Example: bulk-ops
getting-started command
Example: getting-started
Example: getting-started
internals command
Example: internals
Example: internals
model-features command
Example: model-features
Example: model-features
multi-model command
Example: multi-model
Example: multi-model
relationships command
Example: relationships
Example: relationships
internal
ast

Jump to

Keyboard shortcuts

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