sqlmigration

package
v0.40.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupportedDBKind = errors.New("sqlmigration: unsupported database kind")

ErrUnsupportedDBKind indicates the configured database dialect has no migration script or schema lookup query for the supplied Plan.

Functions

func CountTables added in v0.40.0

func CountTables(ctx context.Context, db orm.DB, kind config.DBKind, tables []string) (int, error)

CountTables counts how many of the named tables exist in the connection's active schema — current_schema() on Postgres, the connected database on MySQL, the main database on SQLite. Every migration probe shares this one dialect vocabulary so presence semantics cannot drift between modules.

func IsBusyContention added in v0.40.0

func IsBusyContention(err error) bool

IsBusyContention reports whether err is SQLite write-lock contention: another connection held the database's single writer, so the statement was refused rather than failing on its own merits. Callers treat it as a benign "try again" — the migration lock retries acquisition, the cron store retries a claim on the next tick and re-attempts an outcome write.

The driver's own result code is authoritative and is trusted alone whenever it is available: an unrelated failure must never reclassify as contention because a statement argument echoed into its message happened to read "is locked". Only a driver that surfaces no result code (the cgo github.com/mattn/go-sqlite3 build) falls back to matching the message.

func LoadScript

func LoadScript(scripts fs.FS, kind config.DBKind) (string, error)

LoadScript returns the DDL script for the given dialect from the supplied script bundle. Exported so callers that need the SQL text (e.g. integration tests) can re-use the lookup convention.

func LoadTableColumns added in v0.40.0

func LoadTableColumns(
	ctx context.Context,
	db orm.DB,
	kind config.DBKind,
	table string,
) (map[string]Column, error)

LoadTableColumns returns the table's columns keyed by name, with types normalized into the ColumnKind vocabulary. The probe follows the connection's active schema, like every sqlmigration metadata query.

func Run

func Run(ctx context.Context, db orm.DB, plan Plan) error

Run executes the supplied Plan under the module's migration lock, so concurrently booting nodes provision a schema exactly once instead of racing the probe. It is a no-op when every expected table is already present and Pre hooks have completed without error.

func TableExists added in v0.40.0

func TableExists(ctx context.Context, db orm.DB, kind config.DBKind, table string) (bool, error)

TableExists reports whether the named table exists in the connection's active schema.

func WithLock added in v0.40.0

func WithLock(
	ctx context.Context,
	db orm.DB,
	kind config.DBKind,
	name string,
	fn func(context.Context, orm.DB) error,
) error

WithLock runs fn while holding the named migration lock, serializing concurrently booting nodes through the database's own locking primitive: a transaction-scoped advisory lock on Postgres, GET_LOCK on a dedicated MySQL connection, and BEGIN IMMEDIATE on SQLite (whose single writer makes the database file itself the lock scope). fn receives the handle the DDL must execute on — a transaction on Postgres and SQLite, a dedicated connection on MySQL.

Types

type Column added in v0.40.0

type Column struct {
	// Kind is the dialect-neutral type classification.
	Kind ColumnKind
	// Nullable reports whether the column accepts NULL.
	Nullable bool
	// MaxLength is the declared character bound of a varchar column; zero
	// when unbounded or not exposed by the dialect (SQLite reports it only
	// through the declared type text).
	MaxLength int
}

Column is the observed metadata of one table column, normalized across dialects. LoadTableColumns keys it by column name.

type ColumnKind added in v0.40.0

type ColumnKind string

ColumnKind is the dialect-neutral classification of a column's declared type: schema verifiers compare requirements against it instead of against raw dialect type names.

const (
	// ColumnVarchar is a length-bounded character column; Column.MaxLength
	// carries the bound where the dialect exposes one.
	ColumnVarchar ColumnKind = "varchar"
	// ColumnTimestamp is a wall-clock timestamp without timezone.
	ColumnTimestamp ColumnKind = "timestamp"
	// ColumnInt64 is a signed 64-bit integer; unsigned MySQL declarations
	// deliberately do not normalize to it.
	ColumnInt64 ColumnKind = "int64"
	// ColumnInt32 is a signed 32-bit integer; unsigned MySQL declarations
	// deliberately do not normalize to it.
	ColumnInt32 ColumnKind = "int32"
	// ColumnBool is a boolean (tinyint(1) on MySQL).
	ColumnBool ColumnKind = "bool"
	// ColumnJSON is a JSON document column (jsonb on Postgres).
	ColumnJSON ColumnKind = "json"
	// ColumnText is an unbounded character column.
	ColumnText ColumnKind = "text"
)

Dialect-neutral column kinds. A declaration outside this vocabulary surfaces verbatim (lowercased) so capability mismatches name what the schema actually contains.

type Index added in v0.40.0

type Index struct {
	// Name is the index's schema name.
	Name string
	// Columns is the exact key column sequence.
	Columns []string
	// Unique reports whether the index enforces uniqueness.
	Unique bool
}

Index is the observed metadata of one table index. Capability checks match on Columns and Unique; Name exists for diagnostics only.

func LoadTableIndexes added in v0.40.0

func LoadTableIndexes(
	ctx context.Context,
	db orm.DB,
	kind config.DBKind,
	table string,
) ([]Index, error)

LoadTableIndexes returns the table's complete, non-partial indexes with their exact key column sequences. Partial and expression indexes are excluded — they cannot back a capability requirement — and MySQL prefix index parts surface as an empty column name so they never match one.

type Plan

type Plan struct {
	// Label is a short, human-readable identifier ("storage",
	// "event inbox", ...). Used as the error prefix and as the
	// migration lock name.
	Label string
	// Kind is the database dialect.
	Kind config.DBKind
	// Scripts is the SQL bundle — typically a //go:embed FS. Run looks up
	// "scripts/<kind>.sql" within it.
	Scripts fs.FS
	// ExpectedTables names every table the migration must end up with.
	// The migration is skipped when all of them already exist.
	ExpectedTables []string
	// Pre is an optional list of steps that run before the
	// needs-migration probe (e.g. dropping obsolete tables left over
	// from earlier schema revisions). Each hook should be idempotent.
	Pre []func(ctx context.Context, db orm.DB) error
}

Plan describes one module's migration. Label appears in error messages so logs identify which module is being migrated.

Jump to

Keyboard shortcuts

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