db

package
v0.33.1 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotStruct    = errors.New("model must be a struct")
	ErrNoPrimaryKey = errors.New("model must have a primary key field tagged with db:\"...primary\"")
	ErrNotFound     = errors.New("record not found")
)

Functions

func AddInterval added in v0.30.0

func AddInterval(d SQLDialect, base, interval string) string

AddInterval returns an expression adding a human interval (e.g. "15 minutes", "24 hours") to base.

func EncodeCursor added in v0.11.0

func EncodeCursor(cursor PageCursor) string

func GoLibsqlOpen added in v0.20.0

func GoLibsqlOpen(ctx context.Context, primaryURL string, authToken string) (*sql.DB, error)

GoLibsqlOpen is unavailable in the default build (libsql-client-go is linked instead; both register the "libsql" driver). Build with -tags golibsql (and CGO) to use go-libsql embedded replicas.

func InList added in v0.30.0

func InList(d SQLDialect, column string, values []string) (string, []any)

InList returns "column IN (<placeholders>)" and its arguments. Avoids arrays/ANY, which SQLite and MySQL do not support.

func IndexFields added in v0.29.0

func IndexFields[T any]() ([]string, error)

IndexFields returns the columns of a model tagged index, unique or primary. MongoDB is schemaless (no DDL), so AutoInit there means ensuring these fields as indexes at startup: pass the result to the Mongo registration.

func LibsqlOpen added in v0.20.0

func LibsqlOpen(databaseURL string, authToken string) (*sql.DB, error)

LibsqlOpen opens a remote libSQL database using the libsql-client-go driver (hrana wire protocol). The token is passed via ?authToken= in the DSN.

func MySQLOpen

func MySQLOpen(url string) (*sql.DB, error)

func NewID added in v0.30.0

func NewID() string

NewID returns a random UUIDv4 string, for drivers without a server-side gen_random_uuid() default (SQLite/Turso).

func NewPool

func NewPool(ctx context.Context, cfg PoolConfig) (*pgxpool.Pool, error)

func Now added in v0.30.0

func Now(d SQLDialect) string

Now returns the current-timestamp expression for the dialect.

func OpenForDriver added in v0.32.0

func OpenForDriver(driver, dsn, authToken string) (*sql.DB, error)

OpenForDriver opens a *sql.DB using the driver's canonical constructor, including the out-of-band auth token that remote Turso/libSQL drivers need. It is the entry point for tools that must reach any supported family (the migration runner, for example) without duplicating the DSN wiring.

func OpenStdlib added in v0.30.0

func OpenStdlib(driver, dsn string) (*sql.DB, error)

OpenStdlib opens a *sql.DB for the given YAML driver and DSN, so code that must be driver-agnostic (e.g. the fosite store) can use database/sql for every family. Postgres uses the pgx stdlib driver; MySQL and Turso/libSQL use the drivers registered elsewhere in this package.

func ParseTime added in v0.30.0

func ParseTime(val any) (time.Time, error)

ParseTime converts a driver value (time.Time, string or []byte) into time.Time. Handy when scanning a timestamp by hand across dialects.

func ParseTimePtr added in v0.30.0

func ParseTimePtr(val any) (*time.Time, error)

ParseTimePtr converts a nullable driver value into *time.Time.

func Placeholder added in v0.30.0

func Placeholder(d SQLDialect, i int) string

Placeholder returns the placeholder for the i-th (1-based) argument.

func RandomUUIDExpr added in v0.30.0

func RandomUUIDExpr(d SQLDialect) string

RandomUUIDExpr returns a server-side random id expression for the dialect.

func ResolveFilterColumns added in v0.27.0

func ResolveFilterColumns(info *TableInfo, filters map[string]string) map[string]string

ResolveFilterColumns maps list filter keys (JSON names from query strings) to database columns. Same rules as ResolvePatchColumns.

func ResolvePatchColumns added in v0.26.0

func ResolvePatchColumns[V any](info *TableInfo, patch map[string]V) map[string]V

ResolvePatchColumns maps PATCH/filter keys (JSON names from request bodies and query strings) to database column names using the struct tags. Keys that already match a column pass through; unknown keys pass through unchanged so the caller's validation (or the database) still rejects them.

func ReturningClause added in v0.30.0

func ReturningClause(d SQLDialect, cols string) string

ReturningClause returns "RETURNING <cols>" where supported. MySQL has no RETURNING; callers there read LastInsertId instead.

func Rewrite added in v0.30.0

func Rewrite(d SQLDialect, query string, args ...any) (string, []any)

Rewrite converts a query written with PostgreSQL syntax to the dialect: $n placeholders become positional (with argument expansion), and the generic expressions now() and gen_random_uuid() are translated. PostgreSQL is a no-op. Placeholders and expressions inside single-quoted string literals are left untouched.

func SetSlowThreshold added in v0.11.0

func SetSlowThreshold(d time.Duration)

func TursoOpen

func TursoOpen(url string) (*sql.DB, error)

func TursoServerlessOpen added in v0.20.0

func TursoServerlessOpen(databaseURL string, authToken string) (*sql.DB, error)

TursoServerlessOpen opens a remote Turso/libSQL database over HTTP using the tursogo-serverless driver (pure Go, no native libs, no CGO). The token is passed via ?auth_token= in the DSN (accepted by Turso Cloud and Bunny).

func TursoSyncOpen added in v0.20.0

func TursoSyncOpen(ctx context.Context, path string, remoteURL string, authToken string) (*sql.DB, error)

TursoSyncOpen opens a local database synced to a remote Turso Cloud database (tursogo NewTursoSyncDb). Reads/writes are local; use Push/Pull for cloud sync. Only works with Turso Cloud (not Bunny).

func UpsertClause added in v0.30.0

func UpsertClause(d SQLDialect, conflict, updates []string) string

UpsertClause returns the conflict clause appended to an INSERT. conflict are the columns of the unique constraint; updates are the columns to overwrite.

Types

type ColumnValue

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

func Col

func Col(col string, val any) ColumnValue

type Constraint added in v0.13.0

type Constraint struct {
	Type    string   // "UNIQUE", "INDEX", "CHECK"
	Columns []string // column names in order
	Name    string   // optional constraint name
}

Constraint represents a table-level constraint such as UNIQUE(a,b).

type FieldInfo

type FieldInfo struct {
	Column       string
	GoName       string
	Primary      bool
	Auto         bool
	Required     bool
	Default      string
	Index        bool
	Unique       bool
	Skip         bool
	FieldType    reflect.Type
	Tags         reflect.StructTag
	TypeOverride string // type=DECIMAL(10,2), type=JSONB, type=TEXT[]
	FK           string // fk=users.id
}

type Migration added in v0.32.0

type Migration struct {
	Version  int
	Name     string
	Path     string
	SQL      string
	Checksum string
}

Migration is one versioned SQL file. The version is the leading integer of the file name (e.g. 0002_add_users_email.sql -> 2), so order is explicit and never depends on directory listing.

type MigrationStatus added in v0.32.0

type MigrationStatus struct {
	Migration
	Applied  bool
	Modified bool // applied before, but the file checksum changed
}

MigrationStatus describes one migration against the applied set.

type Migrator added in v0.32.0

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

Migrator applies versioned SQL migrations to a driver-agnostic *sql.DB. It keeps a schema_migrations control table so every environment (dev, staging, prod) converges to the same schema by running only the pending files, in order. This is the ALTER-table companion to AutoInit: AutoInit creates a table that does not exist, the migrator evolves one that does.

func NewMigrator added in v0.32.0

func NewMigrator(database *sql.DB, dir string) (*Migrator, error)

NewMigrator loads every migration file from dir. Files must be named <version>_<name>.sql (e.g. 0001_init.sql); the version is the leading number. File access is confined to dir with os.Root, so a name can never escape the migrations directory.

func (*Migrator) Close added in v0.32.0

func (m *Migrator) Close() error

Close releases the migrations directory handle.

func (*Migrator) Down added in v0.32.0

func (m *Migrator) Down(ctx context.Context) (int, error)

Down rolls back the highest applied migration using its .down.sql companion (e.g. 0002_add_users_email.down.sql). Missing companion is an error: an irreversible migration must be explicit, never silently skipped.

func (*Migrator) Migrations added in v0.32.0

func (m *Migrator) Migrations() []Migration

Migrations returns the loaded migrations (ordered).

func (*Migrator) Status added in v0.32.0

func (m *Migrator) Status(ctx context.Context) ([]MigrationStatus, error)

Status reports every loaded migration against what the database has applied, flagging applied files whose checksum changed (a schema drift warning).

func (*Migrator) Up added in v0.32.0

func (m *Migrator) Up(ctx context.Context) ([]int, error)

Up applies every pending migration in order. It returns the versions applied in this run. A migration whose file changed after being applied is a hard error: the schema and the file would diverge, so the run stops instead of guessing.

type MySQLTable

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

func NewMySQLTable

func NewMySQLTable[T any](db *sql.DB, tableName string) (*MySQLTable[T], error)

func NewMySQLTableFromURL

func NewMySQLTableFromURL[T any](url string, tableName string) (*MySQLTable[T], error)

func (*MySQLTable[T]) AutoInit

func (t *MySQLTable[T]) AutoInit(ctx context.Context) error

func (*MySQLTable[T]) Close

func (t *MySQLTable[T]) Close() error

func (*MySQLTable[T]) Count added in v0.14.0

func (t *MySQLTable[T]) Count(ctx context.Context) (int64, error)

func (*MySQLTable[T]) CountScoped added in v0.14.0

func (t *MySQLTable[T]) CountScoped(ctx context.Context, tenantField, tenantID string) (int64, error)

func (*MySQLTable[T]) CountWhere added in v0.27.0

func (t *MySQLTable[T]) CountWhere(ctx context.Context, where map[string]any) (int64, error)

CountWhere counts rows matching all filters.

func (*MySQLTable[T]) Create

func (t *MySQLTable[T]) Create(ctx context.Context, entity *T) error

func (*MySQLTable[T]) CreateScoped added in v0.10.0

func (t *MySQLTable[T]) CreateScoped(ctx context.Context, entity *T, tenantField string, tenantID string) error

func (*MySQLTable[T]) DB

func (t *MySQLTable[T]) DB() *sql.DB

func (*MySQLTable[T]) Delete

func (t *MySQLTable[T]) Delete(ctx context.Context, id any) error

func (*MySQLTable[T]) DeleteScoped added in v0.10.0

func (t *MySQLTable[T]) DeleteScoped(ctx context.Context, id any, tenantField string, tenantID string) error

func (*MySQLTable[T]) Get

func (t *MySQLTable[T]) Get(ctx context.Context, id any) (*T, error)

func (*MySQLTable[T]) GetScoped added in v0.10.0

func (t *MySQLTable[T]) GetScoped(ctx context.Context, id any, tenantField string, tenantID string) (*T, error)

func (*MySQLTable[T]) List

func (t *MySQLTable[T]) List(ctx context.Context) ([]T, error)

func (*MySQLTable[T]) ListPaginated added in v0.14.0

func (t *MySQLTable[T]) ListPaginated(ctx context.Context, limit, offset int) ([]T, error)

func (*MySQLTable[T]) ListScoped added in v0.10.0

func (t *MySQLTable[T]) ListScoped(ctx context.Context, tenantField string, tenantID string) ([]T, error)

func (*MySQLTable[T]) ListScopedPaginated added in v0.14.0

func (t *MySQLTable[T]) ListScopedPaginated(ctx context.Context, tenantField, tenantID string, limit, offset int) ([]T, error)

func (*MySQLTable[T]) QueryKeyset added in v0.6.0

func (t *MySQLTable[T]) QueryKeyset(ctx context.Context, cursor string, size int, orderBy string, where map[string]any) ([]T, string, error)

func (*MySQLTable[T]) QueryWhere added in v0.27.0

func (t *MySQLTable[T]) QueryWhere(ctx context.Context, where map[string]any, orderBy string, limit, offset int) ([]T, error)

QueryWhere lists rows matching all filters with limit/offset (offset pagination). Column names are validated against the model.

func (*MySQLTable[T]) TableInfo added in v0.27.0

func (t *MySQLTable[T]) TableInfo() *TableInfo

TableInfo exposes the parsed struct metadata (columns, tags).

func (*MySQLTable[T]) Update

func (t *MySQLTable[T]) Update(ctx context.Context, id any, patch map[string]any) (*T, error)

func (*MySQLTable[T]) UpdateScoped added in v0.10.0

func (t *MySQLTable[T]) UpdateScoped(ctx context.Context, id any, patch map[string]any, tenantField string, tenantID string) (*T, error)

type PageCursor added in v0.11.0

type PageCursor struct {
	LastValue string `json:"v"`
	LastID    string `json:"id,omitempty"`
}

func ParseCursor added in v0.11.0

func ParseCursor(encoded string) (PageCursor, error)

type PaginatedResponse added in v0.11.0

type PaginatedResponse[T any] struct {
	Items      []T    `json:"items"`
	NextCursor string `json:"next_cursor,omitempty"`
	HasMore    bool   `json:"has_more"`
}

func NewPaginatedResponse added in v0.11.0

func NewPaginatedResponse[T any](items []T, nextCursor string) PaginatedResponse[T]

type PoolConfig

type PoolConfig struct {
	URL               string
	MaxConns          int32
	MinConns          int32
	MaxConnLifetime   time.Duration
	MaxConnIdleTime   time.Duration
	HealthCheckPeriod time.Duration
	StatementTimeout  time.Duration
	ApplicationName   string
}

func DefaultPoolConfig

func DefaultPoolConfig() PoolConfig

type PreparedTable added in v0.14.0

type PreparedTable[T any] struct {
	*Table[T]
	// contains filtered or unexported fields
}

func NewPreparedTable added in v0.14.0

func NewPreparedTable[T any](pool *pgxpool.Pool, tableName string) (*PreparedTable[T], error)

func (*PreparedTable[T]) Count added in v0.14.0

func (pt *PreparedTable[T]) Count(ctx context.Context) (int64, error)

func (*PreparedTable[T]) Delete added in v0.14.0

func (pt *PreparedTable[T]) Delete(ctx context.Context, id any) error

func (*PreparedTable[T]) Exists added in v0.14.0

func (pt *PreparedTable[T]) Exists(ctx context.Context, column string, value any) (bool, error)

func (*PreparedTable[T]) Get added in v0.14.0

func (pt *PreparedTable[T]) Get(ctx context.Context, id any) (*T, error)

func (*PreparedTable[T]) List added in v0.14.0

func (pt *PreparedTable[T]) List(ctx context.Context) ([]T, error)

type SQLDialect added in v0.30.0

type SQLDialect string

SQLDialect is a SQL family the query helpers translate to. PostgreSQL is the pivot syntax: queries are written with $n placeholders and translated on demand for the other families.

const (
	DialectPostgres SQLDialect = "postgres"
	DialectMySQL    SQLDialect = "mysql"  // MySQL and MariaDB
	DialectSQLite   SQLDialect = "sqlite" // Turso / libSQL
)

func DialectForDriver added in v0.30.0

func DialectForDriver(driver string) SQLDialect

DialectForDriver maps a YAML database driver to its SQL dialect.

type Table

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

func NewTable

func NewTable[T any](pool *pgxpool.Pool, tableName string) (*Table[T], error)

func (*Table[T]) AutoInit

func (t *Table[T]) AutoInit(ctx context.Context) error

func (*Table[T]) BatchInsert

func (t *Table[T]) BatchInsert(ctx context.Context, entities []T) error

func (*Table[T]) Count

func (t *Table[T]) Count(ctx context.Context, where ...ColumnValue) (int64, error)

func (*Table[T]) Create

func (t *Table[T]) Create(ctx context.Context, entity *T) error

func (*Table[T]) CreateScoped added in v0.10.0

func (t *Table[T]) CreateScoped(ctx context.Context, entity *T, tenantField string, tenantID string) error

func (*Table[T]) Delete

func (t *Table[T]) Delete(ctx context.Context, id any) error

func (*Table[T]) DeleteScoped added in v0.10.0

func (t *Table[T]) DeleteScoped(ctx context.Context, id any, tenantField string, tenantID string) error

func (*Table[T]) ExecRaw

func (t *Table[T]) ExecRaw(ctx context.Context, sql string, args ...any) (int64, error)

func (*Table[T]) Exists

func (t *Table[T]) Exists(ctx context.Context, column string, value any) (bool, error)

func (*Table[T]) FindBy

func (t *Table[T]) FindBy(ctx context.Context, column string, value any) (*T, error)

func (*Table[T]) Get

func (t *Table[T]) Get(ctx context.Context, id any) (*T, error)

func (*Table[T]) GetScoped added in v0.10.0

func (t *Table[T]) GetScoped(ctx context.Context, id any, tenantField string, tenantID string) (*T, error)

func (*Table[T]) Increment

func (t *Table[T]) Increment(ctx context.Context, id any, column string, amount int64) error

func (*Table[T]) List

func (t *Table[T]) List(ctx context.Context) ([]T, error)

func (*Table[T]) ListScoped added in v0.10.0

func (t *Table[T]) ListScoped(ctx context.Context, tenantField string, tenantID string) ([]T, error)

func (*Table[T]) PrimaryKey

func (t *Table[T]) PrimaryKey() string

func (*Table[T]) QueryKeyset added in v0.6.0

func (t *Table[T]) QueryKeyset(ctx context.Context, cursor string, size int, orderBy string, where map[string]any) ([]T, string, error)

func (*Table[T]) QueryPaginated

func (t *Table[T]) QueryPaginated(ctx context.Context, page, size int, orderBy string) ([]T, int64, error)

func (*Table[T]) QueryWhere

func (t *Table[T]) QueryWhere(ctx context.Context, where map[string]any, orderBy string, limit, offset int) ([]T, error)

func (*Table[T]) ResolveColumn

func (t *Table[T]) ResolveColumn(jsonKey string) string

func (*Table[T]) ResolvePatch

func (t *Table[T]) ResolvePatch(patch map[string]any) map[string]any

func (*Table[T]) TableInfo

func (t *Table[T]) TableInfo() *TableInfo

func (*Table[T]) Transaction

func (t *Table[T]) Transaction(ctx context.Context, fn func(tx pgx.Tx) error) error

func (*Table[T]) Update

func (t *Table[T]) Update(ctx context.Context, id any, patch map[string]any) (*T, error)

func (*Table[T]) UpdateScoped added in v0.10.0

func (t *Table[T]) UpdateScoped(ctx context.Context, id any, patch map[string]any, tenantField string, tenantID string) (*T, error)

func (*Table[T]) Upsert

func (t *Table[T]) Upsert(ctx context.Context, entity *T, conflictColumn string) error

type TableConstraints added in v0.13.0

type TableConstraints interface {
	Constraints() []Constraint
}

TableConstraints is an optional interface that structs can implement to declare table-level constraints (composite unique, foreign keys, etc.).

type TableInfo

type TableInfo struct {
	Name       string
	Fields     []FieldInfo
	PrimaryKey string
}

func ParseStruct

func ParseStruct[T any]() (*TableInfo, error)

func ParseStructReflect

func ParseStructReflect(typ reflect.Type) (*TableInfo, error)

ParseStructReflect parses struct tags from a reflect.Type (non-generic version).

type TursoTable

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

func NewTursoTable

func NewTursoTable[T any](url string, tableName string) (*TursoTable[T], error)

func NewTursoTableFrom

func NewTursoTableFrom[T any](db *sql.DB, tableName string, info *TableInfo) (*TursoTable[T], error)

func (*TursoTable[T]) AutoInit

func (t *TursoTable[T]) AutoInit(ctx context.Context) error

func (*TursoTable[T]) Close

func (t *TursoTable[T]) Close() error

func (*TursoTable[T]) Count added in v0.14.0

func (t *TursoTable[T]) Count(ctx context.Context) (int64, error)

func (*TursoTable[T]) CountScoped added in v0.14.0

func (t *TursoTable[T]) CountScoped(ctx context.Context, tenantField, tenantID string) (int64, error)

func (*TursoTable[T]) CountWhere added in v0.27.0

func (t *TursoTable[T]) CountWhere(ctx context.Context, where map[string]any) (int64, error)

CountWhere counts rows matching all filters.

func (*TursoTable[T]) Create

func (t *TursoTable[T]) Create(ctx context.Context, entity *T) error

func (*TursoTable[T]) CreateScoped added in v0.10.0

func (t *TursoTable[T]) CreateScoped(ctx context.Context, entity *T, tenantField string, tenantID string) error

func (*TursoTable[T]) DB added in v0.14.0

func (t *TursoTable[T]) DB() *sql.DB

func (*TursoTable[T]) Delete

func (t *TursoTable[T]) Delete(ctx context.Context, id any) error

func (*TursoTable[T]) DeleteScoped added in v0.10.0

func (t *TursoTable[T]) DeleteScoped(ctx context.Context, id any, tenantField string, tenantID string) error

func (*TursoTable[T]) Get

func (t *TursoTable[T]) Get(ctx context.Context, id any) (*T, error)

func (*TursoTable[T]) GetScoped added in v0.10.0

func (t *TursoTable[T]) GetScoped(ctx context.Context, id any, tenantField string, tenantID string) (*T, error)

func (*TursoTable[T]) List

func (t *TursoTable[T]) List(ctx context.Context) ([]T, error)

func (*TursoTable[T]) ListPaginated added in v0.14.0

func (t *TursoTable[T]) ListPaginated(ctx context.Context, limit, offset int) ([]T, error)

func (*TursoTable[T]) ListScoped added in v0.10.0

func (t *TursoTable[T]) ListScoped(ctx context.Context, tenantField string, tenantID string) ([]T, error)

func (*TursoTable[T]) ListScopedPaginated added in v0.14.0

func (t *TursoTable[T]) ListScopedPaginated(ctx context.Context, tenantField, tenantID string, limit, offset int) ([]T, error)

func (*TursoTable[T]) QueryKeyset added in v0.6.0

func (t *TursoTable[T]) QueryKeyset(ctx context.Context, cursor string, size int, orderBy string, where map[string]any) ([]T, string, error)

func (*TursoTable[T]) QueryWhere added in v0.27.0

func (t *TursoTable[T]) QueryWhere(ctx context.Context, where map[string]any, orderBy string, limit, offset int) ([]T, error)

QueryWhere lists rows matching all filters with limit/offset (offset pagination). Column names are validated against the model.

func (*TursoTable[T]) TableInfo added in v0.27.0

func (t *TursoTable[T]) TableInfo() *TableInfo

TableInfo exposes the parsed struct metadata (columns, tags).

func (*TursoTable[T]) Update

func (t *TursoTable[T]) Update(ctx context.Context, id any, patch map[string]any) (*T, error)

func (*TursoTable[T]) UpdateScoped added in v0.10.0

func (t *TursoTable[T]) UpdateScoped(ctx context.Context, id any, patch map[string]any, tenantField string, tenantID string) (*T, error)

Jump to

Keyboard shortcuts

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