db

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Close

func Close(gdb *gorm.DB) error

Close closes the underlying connection pool. Intended for use with App.AddCleanup.

func DBFromContext

func DBFromContext(ctx context.Context) *gorm.DB

DBFromContext returns the *gorm.DB stored in ctx by RunInTx, or nil if no transaction is active. Store uses this to automatically participate in a context-scoped transaction.

func EnableTracing

func EnableTracing(gdb *gorm.DB)

EnableTracing registers GORM callbacks that create OpenTelemetry spans for every query. Each span records the SQL operation (CREATE, QUERY, UPDATE, DELETE) and the number of affected rows.

Uses the global TracerProvider — when tracing is disabled (noop provider), the callbacks add negligible overhead (no allocations, no recording).

Call after *gorm.DB is opened:

gdb, _ := db.NewSQLite(opts)
db.EnableTracing(gdb)

func IsOwnedModel

func IsOwnedModel(model any) bool

IsOwnedModel returns true if the model implements OwnerAccessor (i.e. embeds the Owned mixin).

func IsSoftDeleteModel

func IsSoftDeleteModel(model any) bool

IsSoftDeleteModel returns true if the model embeds SoftDeleteModel, including through intermediate anonymous structs.

func Migrate

func Migrate(ctx context.Context, gdb *gorm.DB, specs ...TableSpec) error

Migrate performs AutoMigrate and creates SoftUnique indexes.

SoftDeleteModel supports both uniqueIndex (permanent, survives soft delete) and SoftUnique (released on soft delete). Choose per field.

Validation order (fail-fast):

  1. SoftUnique used on non-SoftDeleteModel → error
  2. SoftUnique columns must be NOT NULL → error for pointer/sql.Null* types or missing "not null" tag
  3. AutoMigrate
  4. Create SoftUnique indexes

ctx flows into every DDL statement (AutoMigrate, Raw, Exec) via gdb.WithContext so that registry Init timeouts and shutdown cancellation can abort long-running migrations instead of blocking startup.

func NewMySQL

func NewMySQL(opts *config.MySQLOptions) (*gorm.DB, error)

NewMySQL creates a GORM DB connected to MySQL.

func NewSQLite

func NewSQLite(opts *config.SQLiteOptions) (*gorm.DB, error)

NewSQLite creates a GORM DB using SQLite.

func RunInTx

func RunInTx(ctx context.Context, gdb *gorm.DB, fn func(txCtx context.Context) error) error

RunInTx begins a transaction on gdb, stores the *gorm.DB in ctx, and passes the enriched context to fn. Code inside fn — including Store methods — automatically detects and uses the transaction via DBFromContext. If fn returns an error or panics, the transaction is rolled back; otherwise it is committed.

RunInTx enables cross-Store transactions without manual WithTx wiring:

db.RunInTx(ctx, gdb, func(txCtx context.Context) error {
    userStore.Create(txCtx, &user)   // uses tx from txCtx
    orderStore.Create(txCtx, &order) // same transaction
    return nil
})

Nested RunInTx calls reuse the outermost transaction (no savepoints).

func Transaction

func Transaction(ctx context.Context, gdb *gorm.DB, fn func(tx *gorm.DB) error) error

Transaction wraps fn in Begin/Commit/Rollback. ctx is propagated to all DB operations inside fn.

On panic, the transaction is rolled back before re-raising. A failure of the rollback itself (e.g. driver hung, connection already torn) is surfaced through gorm's logger so the panic frame still reaches the caller intact — wrapping the error into the panic would change the observable type and confuse recover() handlers upstream.

func ValidateModel

func ValidateModel(model any) error

ValidateModel checks model metadata:

  • Must embed db.Model or db.SoftDeleteModel
  • If RIDPrefixer, prefix must be valid

Called by db.Table and store.New at construction time.

Types

type Model

type Model struct {
	ID        uint      `json:"-"          gorm:"primaryKey"`
	RID       string    `json:"id"         gorm:"column:rid;uniqueIndex;size:24;not null"`
	Version   int       `json:"version"    gorm:"default:1;not null"`
	CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
	UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}

Model is the base model with auto-increment PK, RID, optimistic lock, and timestamps.

func (*Model) BeforeCreate

func (m *Model) BeforeCreate(tx *gorm.DB) error

BeforeCreate is a GORM hook that:

  1. Initialises Version to 1 when unset, so the in-memory object matches the DB row. A caller-provided Version (e.g. data import or restore) is preserved — we only fill the zero value.
  2. Auto-generates a RID if the model implements RIDPrefixer. The prefix probe works for both single-object Create and batch inserts (CreateInBatches / slice Create) — for slices, the prefix is resolved from the element type rather than the slice itself. Validates the prefix independently so the hook is self-sufficient even when bypassing store.New / db.Table.

type Modeler

type Modeler interface {
	// contains filtered or unexported methods
}

Modeler is the generic constraint for store.Store[T]. The unexported marker method ensures only types embedding db.Model satisfy it.

type Owned

type Owned struct {
	OwnerID string `json:"-" gorm:"column:owner_id;index;not null;size:128"`
}

Owned is a low-level mixin that adds ownership tracking. Prefer OwnedModel or OwnedSoftDeleteModel for convenience. Use Owned directly only when composing with custom base structs.

func (*Owned) GetOwnerID

func (o *Owned) GetOwnerID() string

GetOwnerID returns the owner's identifier.

func (*Owned) SetOwnerID

func (o *Owned) SetOwnerID(id string)

SetOwnerID sets the owner's identifier.

type OwnedModel

type OwnedModel struct {
	Model
	Owned
}

OwnedModel embeds Model and Owned — use when both ownership and base model fields are needed (the common case).

type OwnedSoftDeleteModel

type OwnedSoftDeleteModel struct {
	SoftDeleteModel
	Owned
}

OwnedSoftDeleteModel embeds SoftDeleteModel and Owned — use when ownership + soft-delete are both needed.

type OwnerAccessor

type OwnerAccessor interface {
	GetOwnerID() string
	SetOwnerID(id string)
}

OwnerAccessor is implemented by models that track resource ownership. Store uses this to auto-fill OwnerID on create and auto-scope queries.

type RIDPrefixer

type RIDPrefixer interface {
	RIDPrefix() string
}

RIDPrefixer — models implementing this get auto-generated prefixed RIDs.

type SoftDeleteModel

type SoftDeleteModel struct {
	Model
	DeletedAt   gorm.DeletedAt `json:"-" gorm:"index"`
	DeleteToken string         `json:"-" gorm:"column:delete_token;default:'';not null;size:24"`
}

SoftDeleteModel embeds Model and adds soft-delete support (opt-in).

type SoftIndex

type SoftIndex struct {
	Name    string
	Columns []string
}

SoftIndex represents a composite unique index that includes delete_token for soft-delete compatibility.

func SoftUnique

func SoftUnique(name string, columns ...string) SoftIndex

SoftUnique declares a composite unique index including delete_token. The generated index is: UNIQUE(col1, col2, ..., delete_token).

type TableSpec

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

TableSpec holds migration information for a single model.

func Table

func Table(model any, indexes ...SoftIndex) TableSpec

Table constructs a TableSpec. Panics if model metadata is invalid (does not embed db.Model, illegal RIDPrefix, etc.) — fail-fast at Setup.

Jump to

Keyboard shortcuts

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