liteorm

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package liteorm is the driver-free core of the liteorm data-access library: the lean Querier/Rows/Result/Beginner/Tx contracts, demand-driven capability interfaces, normalized error sentinels, and the DB/Session handles the front-ends operate against. Backends (e.g. liteorm.org/dialect/sqlite) implement these contracts; consumers wire a backend in at construction so the core carries no driver dependency. This surface covers both native-driver and database/sql backends without leaking driver types.

Index

Constants

View Source
const (
	MsgQuery = "liteorm.query" // a QueryContext (SELECT / RETURNING) event
	MsgExec  = "liteorm.exec"  // an ExecContext (INSERT/UPDATE/DELETE/DDL) event

	AttrSQL    = "sql"    // the SQL text, with the dialect's placeholders
	AttrArgs   = "args"   // the bind args ([]any) or, when redacted, their count (int)
	AttrDur    = "dur"    // time.Duration the statement took
	AttrRows   = "rows"   // int64 rows affected (Exec only; absent for queries)
	AttrCaller = "caller" // "file:line" of the Go code that issued the statement
	AttrError  = "err"    // the error, if the statement failed
)

Statement-event message strings and attribute keys. A custom slog.Handler can match on these to format liteorm's statement logs specially.

Variables

View Source
var (
	ErrUniqueViolation = errors.New("liteorm: unique constraint violation")
	ErrForeignKey      = errors.New("liteorm: foreign key constraint violation")
	ErrNotNull         = errors.New("liteorm: not-null constraint violation")
	ErrCheck           = errors.New("liteorm: check constraint violation")
	ErrDeadlock        = errors.New("liteorm: deadlock detected")
	ErrSerialization   = errors.New("liteorm: serialization failure")
)

Typed sentinels for normalized constraint/transaction errors. Callers test with errors.Is(err, liteorm.ErrUniqueViolation); each backend's normalizeError dual-wraps the sentinel and the original driver error so both errors.Is and errors.As stay reachable.

View Source
var ErrNoRows = sql.ErrNoRows

ErrNoRows is returned by single-row reads that find nothing. It IS database/sql.ErrNoRows so errors.Is works uniformly across backends (pgx already proxies the same sentinel — see the R3 research).

Functions

func IsCheckViolation

func IsCheckViolation(err error) bool

IsCheckViolation reports whether err is a CHECK constraint violation.

func IsForeignKeyViolation

func IsForeignKeyViolation(err error) bool

IsForeignKeyViolation reports whether err is a foreign-key constraint violation.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether err is the no-rows sentinel (a single-row read that matched nothing).

func IsNotNullViolation

func IsNotNullViolation(err error) bool

IsNotNullViolation reports whether err is a NOT NULL constraint violation.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable reports whether err is a transient transaction failure (deadlock or serialization) that is safe to retry after rolling back.

func IsUniqueViolation

func IsUniqueViolation(err error) bool

IsUniqueViolation reports whether err is a unique/primary-key constraint violation.

Types

type Beginner

type Beginner interface {
	Begin(ctx context.Context) (Tx, error)
	BeginTx(ctx context.Context, opts TxOptions) (Tx, error)
}

Beginner is implemented by backends that support transactions.

type BoundTx

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

BoundTx is a transaction bound to its dialect + logger, so the front-ends (which take a Session) work identically inside a transaction.

func (*BoundTx) Begin

func (t *BoundTx) Begin(ctx context.Context) (*BoundTx, error)

Begin opens a nested transaction (a savepoint), uniform across backends.

func (*BoundTx) Commit

func (t *BoundTx) Commit(ctx context.Context) error

Commit commits the transaction (or releases the savepoint).

func (*BoundTx) Dialect

func (t *BoundTx) Dialect() dialect.Dialect

Dialect returns the transaction's dialect.

func (*BoundTx) ExecContext

func (t *BoundTx) ExecContext(ctx context.Context, query string, args ...any) (Result, error)

ExecContext runs a statement inside the transaction.

func (*BoundTx) Logger

func (t *BoundTx) Logger() *slog.Logger

Logger returns the transaction's logger.

func (*BoundTx) QueryContext

func (t *BoundTx) QueryContext(ctx context.Context, query string, args ...any) (Rows, error)

QueryContext runs a query inside the transaction.

func (*BoundTx) Rollback

func (t *BoundTx) Rollback(ctx context.Context) error

Rollback rolls back the transaction (or to the savepoint).

type BulkInserter

type BulkInserter interface {
	CopyFrom(ctx context.Context, table string, columns []string, src RowSource) (int64, error)
}

BulkInserter is the bulk-insert fast path: the Postgres backend implements it with native COPY. Where a backend does not, the query layer falls back to chunked multi-row VALUES.

type DB

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

DB is the primary handle: a backend Querier paired with its Dialect and a logger. Constructed by a backend's Open (e.g. sqlite.Open), never globally — liteorm has no global default DB by design.

func New

func New(q Querier, d dialect.Dialect, opts ...Option) *DB

New wraps a backend Querier + Dialect into a DB. Backends call this from Open.

func (*DB) Begin

func (db *DB) Begin(ctx context.Context) (*BoundTx, error)

Begin starts a transaction. Errors if the backend is not a Beginner.

func (*DB) BeginTx

func (db *DB) BeginTx(ctx context.Context, opts TxOptions) (*BoundTx, error)

BeginTx starts a transaction with options.

func (*DB) Close

func (db *DB) Close() error

Close closes the backend if it is an io.Closer.

func (*DB) Dialect

func (db *DB) Dialect() dialect.Dialect

Dialect returns the backend's SQL dialect.

func (*DB) ExecContext

func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error)

ExecContext runs a statement, logging it (with timing, rows affected, and source location) when the logger is debug-enabled.

func (*DB) Logger

func (db *DB) Logger() *slog.Logger

Logger returns the configured logger.

func (*DB) Querier

func (db *DB) Querier() Querier

Querier exposes the underlying backend Querier (for capability type-asserts).

func (*DB) QueryContext

func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (Rows, error)

QueryContext runs a query, logging it (with timing + source location) when the logger is debug-enabled.

func (*DB) Stats

func (db *DB) Stats() (PoolStats, bool)

Stats returns connection-pool statistics if the backend exposes them (a StatsProvider). The second result is false for backends without a pool. Stats are a database-level property, so this lives on *DB, not on a transaction.

type LastInsertIder

type LastInsertIder interface {
	LastInsertId() (int64, error)
}

LastInsertIder is implemented by backends whose driver returns a usable last-insert id (SQLite, MySQL). Postgres/MSSQL use RETURNING/OUTPUT instead.

type Option

type Option func(*DB)

Option configures a DB at construction.

func WithLogger

func WithLogger(l *slog.Logger) Option

WithLogger sets the slog.Logger used for statement logging. liteorm logs every statement at debug level, so logging is silent unless l is enabled for slog.LevelDebug. Use a JSON/text handler for structured logs or the colored handler in liteorm.org/log for development.

func WithSQLArgs

func WithSQLArgs(v bool) Option

WithSQLArgs controls whether bind-argument values are included in statement logs. Default true (values are shown, which is what makes a statement traceable); pass false to log only the argument count when values may be sensitive.

type PoolStats

type PoolStats struct {
	MaxOpenConnections int           // configured max; 0 = unlimited
	OpenConnections    int           // in use + idle
	InUse              int           // currently in use
	Idle               int           // idle in the pool
	WaitCount          int64         // total connections waited for
	WaitDuration       time.Duration // total time blocked waiting for a connection
	MaxIdleClosed      int64         // closed due to SetMaxIdleConns
	MaxIdleTimeClosed  int64         // closed due to SetConnMaxIdleTime
	MaxLifetimeClosed  int64         // closed due to SetConnMaxLifetime
}

PoolStats is liteorm's driver-neutral mirror of database/sql.DBStats, so the public surface reports connection-pool health without binding callers to database/sql (a backend may be pgx-based). Fields match DBStats one-for-one.

type Querier

type Querier interface {
	QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
	ExecContext(ctx context.Context, query string, args ...any) (Result, error)
}

Querier is the lean core every backend implements. No driver type appears in the signature.

type Queryer

type Queryer interface {
	QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
}

Queryer is the minimal read surface, so helpers can stay decoupled from *DB.

type Result

type Result interface {
	RowsAffected() int64
}

Result abstracts pgconn.CommandTag and database/sql.Result. RowsAffected is first-class; LastInsertId is the optional LastInsertIder capability.

type RowSource

type RowSource interface {
	Next() bool
	Values() ([]any, error)
	Err() error
}

RowSource is liteorm's driver-neutral mirror of a bulk row stream (pgx's CopyFromSource shape, owned by liteorm so the driver type never leaks).

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Columns() ([]string, error)
	Close() error
	Err() error
	Values() ([]any, error)
}

Rows is the driver-neutral row cursor. Scan is the primary, leak-free path; Values is advanced/best-effort (on a future pgx backend it may surface driver types for exotic columns — see the R3 research).

type Session

type Session interface {
	Querier
	Dialect() dialect.Dialect
	Logger() *slog.Logger
}

Session is a query-executing handle that knows its dialect and logger: both *DB and *BoundTx satisfy it, so the front-ends work identically on a connection or inside a transaction.

type StatsProvider

type StatsProvider interface {
	Stats() PoolStats
}

StatsProvider is implemented by backends whose driver exposes connection-pool statistics — every database/sql-based backend (SQLite, MySQL, MSSQL) and the pgx-pool Postgres backend. DB.Stats() type-asserts for it and reports whether stats are available.

type Tx

type Tx interface {
	Querier
	Begin(ctx context.Context) (Tx, error)
	Commit(ctx context.Context) error
	Rollback(ctx context.Context) error
}

Tx is a transaction. Nested Begin is a savepoint, uniform across backends.

type TxOptions

type TxOptions struct {
	IsoLevel   string // "serializable" | "repeatable read" | "read committed" | "read uncommitted"
	ReadOnly   bool
	Deferrable bool
}

TxOptions configures a transaction.

Directories

Path Synopsis
Package dialect defines the SQL-dialect contract liteorm's core depends on.
Package dialect defines the SQL-dialect contract liteorm's core depends on.
mssql module
mysql module
postgres module
sqlite module
internal
scan
Package scan maps result rows to typed Go values.
Package scan maps result rows to typed Go values.
sqladapter
Package sqladapter adapts a database/sql *sql.DB to liteorm's core contracts, shared by every database/sql-based backend (SQLite, MySQL, MSSQL).
Package sqladapter adapts a database/sql *sql.DB to liteorm's core contracts, shared by every database/sql-based backend (SQLite, MySQL, MSSQL).
sqlgen
Package sqlgen generates SQL for liteorm's core.
Package sqlgen generates SQL for liteorm's core.
Package log provides a colored, human-readable slog.Handler tuned for liteorm's statement logs: one line per executed statement with timing, the SQL, its bind arguments, the rows affected, and the Go source location that issued it — so you can watch every query during development and trace it back to the line of code.
Package log provides a colored, human-readable slog.Handler tuned for liteorm's statement logs: one line per executed statement with timing, the SQL, its bind arguments, the rows affected, and the Go source location that issued it — so you can watch every query during development and trace it back to the line of code.
Package migrate is liteorm's thin, driver-free migration runner.
Package migrate is liteorm's thin, driver-free migration runner.
Package orm is liteorm's declarative front-end: convention + struct-tag driven models over the SAME core (Conn, Tx, dialect, scanner) as the explicit `query` front-end, so a value fetched via one feeds the other on the same transaction.
Package orm is liteorm's declarative front-end: convention + struct-tag driven models over the SAME core (Conn, Tx, dialect, scanner) as the explicit `query` front-end, so a value fetched via one feeds the other on the same transaction.
Package query is liteorm's explicit, generics-first front-end: a typed query builder plus a Repo[T] for CRUD, operating against a liteorm.Session (a *DB or a transaction) so the same code runs on a connection or inside a tx.
Package query is liteorm's explicit, generics-first front-end: a typed query builder plus a Repo[T] for CRUD, operating against a liteorm.Session (a *DB or a transaction) so the same code runs on a connection or inside a tx.

Jump to

Keyboard shortcuts

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