Documentation
¶
Overview ¶
Package migrate is schema versioning over authored SQL: an ordered set of migrations, each SQL text plus a version, applied against a history table on one pinned connection under the dialect's lock capability. It designs for the cases a mature library has met: dirty state after a failed non-transactional migration (recorded, reported, cleared only by Force), engines without transactional DDL (a migration headed "-- transaction: none" runs outside a transaction and contains exactly one statement by convention), and concurrent starters (the lock; a dialect without one fails unless the consumer opts into an unlocked run). Files packages the NNNN_name.{up,down}.sql layout as a helper, never the contract.
Index ¶
- Variables
- type Catalog
- type DirtyError
- type Migration
- type Migrator
- func (m *Migrator) Down(ctx context.Context, n int) error
- func (m *Migrator) Force(ctx context.Context, version int) error
- func (m *Migrator) Migrations() []Migration
- func (m *Migrator) Steps(ctx context.Context, n int) error
- func (m *Migrator) Up(ctx context.Context) error
- func (m *Migrator) Verify(ctx context.Context) error
- func (m *Migrator) Version(ctx context.Context) (Version, error)
- type Options
- type PendingError
- type StandardCatalog
- type UnknownVersionError
- type Version
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoLocker reports a run that needs the lock on a dialect without the // capability; Options.Unlocked opts out. ErrNoLocker = errors.New("migrate: dialect has no lock capability") // ErrDirty is the class a *DirtyError unwraps to. ErrDirty = errors.New("migrate: schema is dirty") // ErrPending is the class a *PendingError unwraps to. ErrPending = errors.New("migrate: migrations pending") // ErrUnknownVersion is the class an *UnknownVersionError unwraps to. ErrUnknownVersion = errors.New("migrate: history does not match the migration set") // ErrNoDown reports a Down of a migration that has no down text. ErrNoDown = errors.New("migrate: migration has no down") // ErrVersionNotFound reports a Force to a version outside the set. ErrVersionNotFound = errors.New("migrate: version not in the migration set") )
Functions ¶
This section is empty.
Types ¶
type Catalog ¶
type Catalog interface {
// CreateHistory returns the DDL that creates table when it does not
// exist, with the columns the protocol reads and writes: version
// (integer, primary key), name (text, not null), applied_at (timestamp,
// not null, defaulting to the current time), dirty (boolean, not null,
// defaulting to false).
CreateHistory(table string) string
// HistoryExists returns the query that yields one row whose first
// column is nonzero when the history table exists. The table name is
// the query's one argument, bound at param, the dialect's placeholder.
HistoryExists(param string) string
}
Catalog is the engine-specific half of the history protocol: the two statements standard SQL cannot express the same way on every engine. A dialect provides it by implementing the methods; a dialect that does not gets StandardCatalog. Everything else the migrator runs is standard DML with bound parameters.
type DirtyError ¶
DirtyError reports a version whose non-transactional migration failed midway: the history row is marked dirty and every run refuses until Force clears it. Err is the failure that dirtied it, when this run caused it.
func (*DirtyError) Error ¶
func (e *DirtyError) Error() string
func (*DirtyError) Unwrap ¶
func (e *DirtyError) Unwrap() []error
type Migration ¶
Migration is one schema step: the version and name that identify it in the history, the SQL that applies and reverts it, and whether it runs in a transaction. Down may be empty.
func Files ¶
Files reads the NNNN_name.{up,down}.sql layout under dir in fsys into a version-ordered set. The up file's "--|" header decides Transactional: the "transaction" declaration, "none" opting out and "required" or absence keeping the transaction; a down file that declares differently is an error. Up and Down are the files' bodies; the engine never sees a header. Versions must be unique; a down without its up is an error; an up without its down is allowed.
type Migrator ¶
type Migrator struct {
// contains filtered or unexported fields
}
Migrator runs a migration set against a database.
func New ¶
New validates the set (versions positive and strictly increasing, names and up texts present) and prepares the migrator: the lock capability and the Catalog are taken from the dialect when it has them. It performs no I/O.
func (*Migrator) Force ¶
Force sets the history to version as an operator override: rows above it are deleted, its row is inserted if absent and marked clean, and version 0 empties the history. Nothing runs against the schema itself.
func (*Migrator) Migrations ¶
Migrations returns a copy of the set.
func (*Migrator) Steps ¶
Steps applies the next n pending migrations when n is positive, or reverts the last -n applied when negative; fewer remaining is not an error.
type Options ¶
type Options struct {
// Table names the history table; default "schema_version".
Table string
// LockName names the lock a run holds; default "migrate.<table>", so two
// migrators over different tables never contend and no lock of the
// program's own can collide with it by number.
LockName string
// Unlocked allows runs on a dialect without the lock capability, or with
// it, without taking the lock; concurrent starters are then unsafe.
Unlocked bool
// Logger records each applied and reverted migration; nil is silent.
Logger *slog.Logger
}
Options configures a Migrator. Every field has a default.
type PendingError ¶
type PendingError struct{ Versions []int }
PendingError reports migrations in the set the history has not applied.
func (*PendingError) Error ¶
func (e *PendingError) Error() string
func (*PendingError) Unwrap ¶
func (e *PendingError) Unwrap() error
type StandardCatalog ¶
type StandardCatalog struct{}
StandardCatalog is the Catalog for engines that accept CREATE TABLE IF NOT EXISTS with text and boolean columns and expose information_schema: PostgreSQL, MySQL, and MariaDB as they ship. SQL Server (no IF NOT EXISTS, no boolean), Oracle (no information_schema), and SQLite (sqlite_master) provide their own.
func (StandardCatalog) CreateHistory ¶
func (StandardCatalog) CreateHistory(table string) string
func (StandardCatalog) HistoryExists ¶
func (StandardCatalog) HistoryExists(param string) string
type UnknownVersionError ¶
UnknownVersionError reports an applied row the migration set does not contain at that position: a version the set lacks, or a name that differs.
func (*UnknownVersionError) Error ¶
func (e *UnknownVersionError) Error() string
func (*UnknownVersionError) Unwrap ¶
func (e *UnknownVersionError) Unwrap() error